16 卡牌服务端(聊天、广播、通用记录、查看玩家;)
| | |
| | |
|
| | | ;玩家查看数据缓存
|
| | | [PlayerViewCache]
|
| | | ScriptName = Player\PlayerViewCacheTube.py
|
| | | ScriptName = Player\PlayerViewCache.py
|
| | | Writer = xmnathan
|
| | | Releaser = xmnathan
|
| | | RegType = 0
|
| | |
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 3
|
| | | RegisterPackCount = 1
|
| | |
|
| | | PacketCMD_1=0xA2
|
| | | PacketSubCMD_1=0x16
|
| | | PacketCallFunc_1=OnPyTalk
|
| | |
|
| | | PacketCMD_2=0xA2
|
| | | PacketSubCMD_2=0x17
|
| | | PacketCallFunc_2=OnUsePYSpeaker
|
| | |
|
| | | PacketCMD_3=0xA2
|
| | | PacketSubCMD_3=0x26
|
| | | PacketCallFunc_3=OnVoiceChat
|
| | |
|
| | | PacketCMD_1=0xB3
|
| | | PacketSubCMD_1=0x20
|
| | | PacketCallFunc_1=OnTalk
|
| | |
|
| | | ;属性果实
|
| | | [PlayerAttrFruit]
|
| | |
| | | PacketCMD_5=0xA5
|
| | | PacketSubCMD_5=0xC4
|
| | | PacketCallFunc_5=OnDogzEquipPlus
|
| | |
|
| | | ;个推
|
| | | [PlayerGeTui]
|
| | | ScriptName = Player\PlayerGeTui.py
|
| | | Writer = Alee
|
| | | Releaser = Alee
|
| | | RegType = 0
|
| | | RegisterPackCount = 1
|
| | |
|
| | | PacketCMD_1=0xB2
|
| | | PacketSubCMD_1=0x5
|
| | | PacketCallFunc_1=GeTuiSetting
|
| | |
|
| | | ;充值
|
| | | [PlayerCoin]
|
| | |
| | | PacketSubCMD_1=0x3
|
| | | PacketCallFunc_1=PetStateChange
|
| | |
|
| | |
|
| | | ;聊天
|
| | | [Talk]
|
| | | ScriptName = Player\PlayerTalk.py
|
| | | Writer = Mark
|
| | | Releaser = Mark
|
| | | RegType = 0
|
| | | RegisterPackCount = 7
|
| | |
|
| | | PacketCMD_1=0x2
|
| | | PacketSubCMD_1=0x7
|
| | | PacketCallFunc_1=TalkArea
|
| | |
|
| | |
|
| | | PacketCMD_2=0x2
|
| | | PacketSubCMD_2=0x3
|
| | | PacketCallFunc_2=TalkFamily
|
| | |
|
| | | PacketCMD_3=0x2
|
| | | PacketSubCMD_3=0x5
|
| | | PacketCallFunc_3=TalkTeam
|
| | |
|
| | |
|
| | | PacketCMD_4=0x2
|
| | | PacketSubCMD_4=0x1
|
| | | PacketCallFunc_4=TalkWorld
|
| | |
|
| | | PacketCMD_5=0x2
|
| | | PacketSubCMD_5=0x6
|
| | | PacketCallFunc_5=TalkPrivateName
|
| | |
|
| | | PacketCMD_6=0x2
|
| | | PacketSubCMD_6=0x9
|
| | | PacketCallFunc_6=TalkPrivate
|
| | |
|
| | | PacketCMD_7=0x2
|
| | | PacketSubCMD_7=0x8
|
| | | PacketCallFunc_7=TalkCountry
|
| | |
|
| | |
|
| | | ;战斗
|
| | | [Battle]
|
| | | ScriptName = Player\PlayerBattle.py
|
| | |
| | | import ChNetSendPack
|
| | | import NetPackCommon
|
| | | import PassiveBuffEffMng
|
| | | import PlayerGeTui
|
| | | import IpyGameDataPY
|
| | | #---------------------------------------------------------------------
|
| | | g_skillHurtList = IPY_GameWorld.IPY_HurtList()
|
| | |
| | | if GameObj.GetHP(defender) <= 0:
|
| | | defender.SetDict(ChConfig.Def_NPCDead_KillerType, attacker.GetGameObjType())
|
| | | defender.SetDict(ChConfig.Def_NPCDead_KillerID, attacker.GetID())
|
| | | #PlayerGeTui.TJGDead(defender, attacker.GetName())
|
| | | if defender.GetGameObjType() == IPY_GameWorld.gotNPC:
|
| | | skillID = 0 if not useSkill else useSkill.GetSkillID()
|
| | | # 记录死亡原因
|
| | |
| | | import IPY_GameWorld
|
| | | import PlayerControl
|
| | | import OperControlManager
|
| | | import PlayerViewCacheTube
|
| | | import PassiveBuffEffMng
|
| | | import GameWorldProcess
|
| | | import ChNetSendPack
|
| | |
| | | import SkillShell
|
| | | import CommFunc
|
| | | import FBCommon
|
| | | import PlayerFB
|
| | | import GameMap
|
| | | import FBLogic
|
| | | import GameObj
|
| | |
| | | #};
|
| | | def OnSycnPlayerPackData(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
|
| | | #PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
|
| | | return
|
| | |
|
| | | #// B4 11 镜像战斗 #tagCMMirrorFight
|
| | |
| | | return True
|
| | |
|
| | | # 玩家自身需要用镜像的情况
|
| | | if isSysbg and playerID and playerID in mirrorIDList:
|
| | | PlayerViewCacheTube.NormalSyncPackData(curPlayer)
|
| | | #if isSysbg and playerID and playerID in mirrorIDList:
|
| | | # PlayerViewCacheTube.NormalSyncPackData(curPlayer)
|
| | |
|
| | | sendMsg = str(sendMsg)
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "ReuestPlayerPackData", sendMsg, len(sendMsg))
|
| | |
| | | Def_NPCErrorMaxDist = 99999
|
| | |
|
| | | #玩家聊天-------------------------------------------
|
| | | #聊天通用间隔时间
|
| | | Def_PlayerTalkTick = 1000
|
| | | #玩家聊天频道最大个数
|
| | | Def_PlayerTalkChannelMaxCount = 10
|
| | | #玩家聊天,单句最大字节数
|
| | | Def_PlayerTalkMaxCount = 8000 #原来为100
|
| | | #轻频频道
|
| | | #轻频频道相同内容允许时间(10秒2次)
|
| | | Def_PlayerTalkQingTime = 5000
|
| | | #区域频道
|
| | | #区域聊天频道时间间隔(1秒)
|
| | | Def_PlayerTalkAreaTime = 1000 #原来为180000 目前测试
|
| | | #区域聊天频道等级限制
|
| | | Def_PlayerTalkAreaLV = 1
|
| | | #国家频道
|
| | | #国家聊天频道时间间隔(10秒)
|
| | | Def_PlayerTalkCountryTime = 10000 #文档中为18000
|
| | | #国家聊天频道等级限制
|
| | | Def_PlayerTalkCountryLV = 41
|
| | | #国家频道聊天花费
|
| | | Def_PlayerTalkCoutryMoney = 10
|
| | | #世界频道
|
| | | #世界频道聊天花费(银子或银票)
|
| | | Def_PlayerTalkWorldMoney = 1000
|
| | | #世界聊天时间间隔(1秒)
|
| | | Def_PlayerTalkWorldTime = 1000
|
| | | #不可以轻频聊天的地图
|
| | | CanNotQingTalkMapIDList = []
|
| | | Def_PlayerTalkTick = 1000 #聊天通用间隔时间
|
| | | Def_PlayerTalkMaxCount = 8000 #玩家聊天,单句最大字节数
|
| | | Def_ChannelTalkTick = "ChannelTalkTick_%s" # 聊天频道玩家最近一次聊天tick
|
| | |
|
| | | ###################################################
|
| | | #类型定义, 以下内容不要修改
|
| | |
| | | ) = range(0, Def_QueryType_Count)
|
| | | #------------------------------------------------------------------------------
|
| | |
|
| | | #家族某行为类型保存的条数
|
| | | ActionTypeSaveCnt = {
|
| | | ShareDefine.Def_ActionType_FamilyPray:10 , #家族祈福
|
| | | ShareDefine.Def_ActionType_FamilyArrest:7, #家族悬赏
|
| | | ShareDefine.Def_ActionType_FamilyMember:1, #记录家族成员信息
|
| | | ShareDefine.Def_ActionType_LeaderImpeachTime:1, # 族长下线了多久
|
| | | ShareDefine.Def_ActionType_FamilyBossFB:1, # 记录家族boss副本信息
|
| | | ShareDefine.Def_ActionType_FamilyStore:30, #仓库操作记录
|
| | | ShareDefine.Def_ActionType_OfficerModelEquip:10, # 记录家族有职位的成员模型装备信息(盟主+副盟主*2+战斗队长*5)
|
| | | ShareDefine.Def_ActionType_FamilyEvent:50, # 记录家族事件
|
| | | }
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | #数值上限 2^31 - 1
|
| | | Def_UpperLimit_DWordEx = ShareDefine.Def_UpperLimit_DWordEx
|
| | | #数值上限(20亿)
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | #B3 07 语音聊天 #tagCGVoiceChat
|
| | |
|
| | | class tagCGVoiceChat(Structure):
|
| | | Head = tagHead()
|
| | | ChannelType = 0 #(BYTE ChannelType)// 1 世界 2 仙盟 3 私聊(好友) 4 队伍 -------查看封包tagCMVoiceChat 5 区域 |
| | | TargetNameLen = 0 #(BYTE TargetNameLen)
|
| | | TargetName = "" #(String TargetName)//size = TargetNameLen
|
| | | TargetID = 0 #(DWORD TargetID)// 默认发玩家ID,没有ID才发名称
|
| | | Len = 0 #(WORD Len)
|
| | | Content = list() #(vector<BYTE> Content)//size = Len
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x07
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.TargetNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.TargetName,_pos = CommFunc.ReadString(_lpData, _pos,self.TargetNameLen)
|
| | | self.TargetID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | for i in range(self.Len):
|
| | | value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
|
| | | self.Content.append(value)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x07
|
| | | self.ChannelType = 0
|
| | | self.TargetNameLen = 0
|
| | | self.TargetName = ""
|
| | | self.TargetID = 0
|
| | | self.Len = 0
|
| | | self.Content = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | length += len(self.TargetName)
|
| | | length += 4
|
| | | length += 2
|
| | | length += 1 * self.Len
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ChannelType)
|
| | | data = CommFunc.WriteBYTE(data, self.TargetNameLen)
|
| | | data = CommFunc.WriteString(data, self.TargetNameLen, self.TargetName)
|
| | | data = CommFunc.WriteDWORD(data, self.TargetID)
|
| | | data = CommFunc.WriteWORD(data, self.Len)
|
| | | for i in range(self.Len):
|
| | | data = CommFunc.WriteBYTE(data, self.Content[i])
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ChannelType:%d,
|
| | | TargetNameLen:%d,
|
| | | TargetName:%s,
|
| | | TargetID:%d,
|
| | | Len:%d,
|
| | | Content:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ChannelType,
|
| | | self.TargetNameLen,
|
| | | self.TargetName,
|
| | | self.TargetID,
|
| | | self.Len,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCGVoiceChat=tagCGVoiceChat()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGVoiceChat.Head.Cmd,m_NAtagCGVoiceChat.Head.SubCmd))] = m_NAtagCGVoiceChat
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | #B3 03 是否允许加入好友的回应#tagCGJoinFriendAnswer
|
| | |
|
| | | class tagCGJoinFriendAnswer(Structure):
|
| | |
| | | ("GroupValue2", c_int), #分组值2,与分组值1组合归为同组榜单数据
|
| | | ("StartIndex", c_ushort), #查看的起始名次索引, 默认0
|
| | | ("ViewCnt", c_ubyte), #查看条数,默认20,单次最大不超过100
|
| | | ("ViewID", c_int), #附带查看指定ID所在名次前后数据,如玩家ID、家族ID等,仅首页查询时有效,即StartIndex为0时
|
| | | ("ViewID", c_int), #附带查看指定ID所在名次前后数据,如玩家ID、家族ID等
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A2 17 喇叭聊天 #tagCMPYSpeaker
|
| | |
|
| | | class tagCMPYSpeaker(Structure):
|
| | | Head = tagHead()
|
| | | SpeakerType = 0 #(BYTE SpeakerType)//1-本服;2-跨服
|
| | | IsUseGold = 0 #(BYTE IsUseGold)//是否使用钻石
|
| | | ItemIndex = 0 #(BYTE ItemIndex)//使用物品说话时, 物品Index
|
| | | TextLen = 0 #(WORD TextLen)//字符长度
|
| | | Text = "" #(String Text)//size = TextLen
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xA2
|
| | | self.Head.SubCmd = 0x17
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.SpeakerType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.IsUseGold,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.ItemIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.TextLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Text,_pos = CommFunc.ReadString(_lpData, _pos,self.TextLen)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA2
|
| | | self.Head.SubCmd = 0x17
|
| | | self.SpeakerType = 0
|
| | | self.IsUseGold = 0
|
| | | self.ItemIndex = 0
|
| | | self.TextLen = 0
|
| | | self.Text = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | length += 1
|
| | | length += 2
|
| | | length += len(self.Text)
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.SpeakerType)
|
| | | data = CommFunc.WriteBYTE(data, self.IsUseGold)
|
| | | data = CommFunc.WriteBYTE(data, self.ItemIndex)
|
| | | data = CommFunc.WriteWORD(data, self.TextLen)
|
| | | data = CommFunc.WriteString(data, self.TextLen, self.Text)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | SpeakerType:%d,
|
| | | IsUseGold:%d,
|
| | | ItemIndex:%d,
|
| | | TextLen:%d,
|
| | | Text:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.SpeakerType,
|
| | | self.IsUseGold,
|
| | | self.ItemIndex,
|
| | | self.TextLen,
|
| | | self.Text
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMPYSpeaker=tagCMPYSpeaker()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMPYSpeaker.Head.Cmd,m_NAtagCMPYSpeaker.Head.SubCmd))] = m_NAtagCMPYSpeaker
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A2 16 自定义玩家聊天 #tagCMPyTalk
|
| | |
|
| | | class tagCMPyTalk(Structure):
|
| | | Head = tagHead()
|
| | | TalkType = 0 #(BYTE TalkType)// 自定义聊天类型
|
| | | Len = 0 #(WORD Len)
|
| | | Content = "" #(String Content)//size = Len
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xA2
|
| | | self.Head.SubCmd = 0x16
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.TalkType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA2
|
| | | self.Head.SubCmd = 0x16
|
| | | self.TalkType = 0
|
| | | self.Len = 0
|
| | | self.Content = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 2
|
| | | length += len(self.Content)
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.TalkType)
|
| | | data = CommFunc.WriteWORD(data, self.Len)
|
| | | data = CommFunc.WriteString(data, self.Len, self.Content)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | TalkType:%d,
|
| | | Len:%d,
|
| | | Content:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.TalkType,
|
| | | self.Len,
|
| | | self.Content
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMPyTalk=tagCMPyTalk()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMPyTalk.Head.Cmd,m_NAtagCMPyTalk.Head.SubCmd))] = m_NAtagCMPyTalk
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | #A2 11 查询世界Boss伤血列表 #tagCMQueryBossHurtList
|
| | |
|
| | | class tagCMQueryBossHurtList(Structure):
|
| | |
| | |
|
| | | m_NAtagCMClientTaskCount=tagCMClientTaskCount()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMClientTaskCount.Cmd,m_NAtagCMClientTaskCount.SubCmd))] = m_NAtagCMClientTaskCount
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | #A2 26 语音聊天 #tagCMVoiceChat
|
| | |
|
| | | class tagCMVoiceChat(Structure):
|
| | | Head = tagHead()
|
| | | ChannelType = 0 #(BYTE ChannelType)// 5 区域 --- 查看封包tagCGVoiceChat 1 世界 2 仙盟 3 私聊(好友) 4 队伍
|
| | | TargetNameLen = 0 #(BYTE TargetNameLen)
|
| | | TargetName = "" #(String TargetName)//size = TargetNameLen
|
| | | TargetID = 0 #(DWORD TargetID)// 私聊默认发玩家ID,没有ID才发名称
|
| | | Len = 0 #(WORD Len)
|
| | | Content = list() #(vector<BYTE> Content)//size = Len
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xA2
|
| | | self.Head.SubCmd = 0x26
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.TargetNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.TargetName,_pos = CommFunc.ReadString(_lpData, _pos,self.TargetNameLen)
|
| | | self.TargetID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | for i in range(self.Len):
|
| | | value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
|
| | | self.Content.append(value)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA2
|
| | | self.Head.SubCmd = 0x26
|
| | | self.ChannelType = 0
|
| | | self.TargetNameLen = 0
|
| | | self.TargetName = ""
|
| | | self.TargetID = 0
|
| | | self.Len = 0
|
| | | self.Content = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | length += len(self.TargetName)
|
| | | length += 4
|
| | | length += 2
|
| | | length += 1 * self.Len
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ChannelType)
|
| | | data = CommFunc.WriteBYTE(data, self.TargetNameLen)
|
| | | data = CommFunc.WriteString(data, self.TargetNameLen, self.TargetName)
|
| | | data = CommFunc.WriteDWORD(data, self.TargetID)
|
| | | data = CommFunc.WriteWORD(data, self.Len)
|
| | | for i in range(self.Len):
|
| | | data = CommFunc.WriteBYTE(data, self.Content[i])
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ChannelType:%d,
|
| | | TargetNameLen:%d,
|
| | | TargetName:%s,
|
| | | TargetID:%d,
|
| | | Len:%d,
|
| | | Content:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ChannelType,
|
| | | self.TargetNameLen,
|
| | | self.TargetName,
|
| | | self.TargetID,
|
| | | self.Len,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMVoiceChat=tagCMVoiceChat()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMVoiceChat.Head.Cmd,m_NAtagCMVoiceChat.Head.SubCmd))] = m_NAtagCMVoiceChat
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B3 20 聊天 #tagCMTalk
|
| | |
|
| | | class tagCMPyTalk(Structure):
|
| | | Head = tagHead()
|
| | | ChannelType = 0 #(BYTE ChannelType)// 频道
|
| | | Len = 0 #(WORD Len)
|
| | | Content = "" #(String Content)//size = Len
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x20
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x20
|
| | | self.ChannelType = 0
|
| | | self.Len = 0
|
| | | self.Content = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 2
|
| | | length += len(self.Content)
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ChannelType)
|
| | | data = CommFunc.WriteWORD(data, self.Len)
|
| | | data = CommFunc.WriteString(data, self.Len, self.Content)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ChannelType:%d,
|
| | | Len:%d,
|
| | | Content:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ChannelType,
|
| | | self.Len,
|
| | | self.Content
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B4 11 镜像战斗 #tagCMMirrorFight
|
| | |
|
| | | class tagCMMirrorFight(Structure):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | #B3 10 语音聊天 #tagGCVoiceChat
|
| | |
|
| | | class tagGCVoiceChat(Structure):
|
| | | Head = tagHead()
|
| | | ChannelType = 0 #(BYTE ChannelType)// 1 世界 2 仙盟 3 私聊(好友) 4 队伍 5 区域 |
| | | SrcNameLen = 0 #(BYTE SrcNameLen)
|
| | | SrcName = "" #(String SrcName)//size = SrcNameLen
|
| | | PlayerID = 0 #(DWORD PlayerID)
|
| | | ToNameLen = 0 #(BYTE ToNameLen)
|
| | | ToName = "" #(String ToName)//size = ToNameLen
|
| | | ToPlayerID = 0 #(DWORD ToPlayerID)
|
| | | Len = 0 #(WORD Len)
|
| | | Content = list() #(vector<BYTE> Content)//size = Len
|
| | | ExtraValue = 0 #(DWORD ExtraValue)//附加值
|
| | | Extras = "" #(char Extras[256])//附加值列表
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x10
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.SrcNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.SrcName,_pos = CommFunc.ReadString(_lpData, _pos,self.SrcNameLen)
|
| | | self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.ToNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.ToName,_pos = CommFunc.ReadString(_lpData, _pos,self.ToNameLen)
|
| | | self.ToPlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | for i in range(self.Len):
|
| | | value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
|
| | | self.Content.append(value)
|
| | | self.ExtraValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Extras,_pos = CommFunc.ReadString(_lpData, _pos,256)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x10
|
| | | self.ChannelType = 0
|
| | | self.SrcNameLen = 0
|
| | | self.SrcName = ""
|
| | | self.PlayerID = 0
|
| | | self.ToNameLen = 0
|
| | | self.ToName = ""
|
| | | self.ToPlayerID = 0
|
| | | self.Len = 0
|
| | | self.Content = list()
|
| | | self.ExtraValue = 0
|
| | | self.Extras = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | length += len(self.SrcName)
|
| | | length += 4
|
| | | length += 1
|
| | | length += len(self.ToName)
|
| | | length += 4
|
| | | length += 2
|
| | | length += 1 * self.Len
|
| | | length += 4
|
| | | length += 256
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ChannelType)
|
| | | data = CommFunc.WriteBYTE(data, self.SrcNameLen)
|
| | | data = CommFunc.WriteString(data, self.SrcNameLen, self.SrcName)
|
| | | data = CommFunc.WriteDWORD(data, self.PlayerID)
|
| | | data = CommFunc.WriteBYTE(data, self.ToNameLen)
|
| | | data = CommFunc.WriteString(data, self.ToNameLen, self.ToName)
|
| | | data = CommFunc.WriteDWORD(data, self.ToPlayerID)
|
| | | data = CommFunc.WriteWORD(data, self.Len)
|
| | | for i in range(self.Len):
|
| | | data = CommFunc.WriteBYTE(data, self.Content[i])
|
| | | data = CommFunc.WriteDWORD(data, self.ExtraValue)
|
| | | data = CommFunc.WriteString(data, 256, self.Extras)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ChannelType:%d,
|
| | | SrcNameLen:%d,
|
| | | SrcName:%s,
|
| | | PlayerID:%d,
|
| | | ToNameLen:%d,
|
| | | ToName:%s,
|
| | | ToPlayerID:%d,
|
| | | Len:%d,
|
| | | Content:%s,
|
| | | ExtraValue:%d,
|
| | | Extras:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ChannelType,
|
| | | self.SrcNameLen,
|
| | | self.SrcName,
|
| | | self.PlayerID,
|
| | | self.ToNameLen,
|
| | | self.ToName,
|
| | | self.ToPlayerID,
|
| | | self.Len,
|
| | | "...",
|
| | | self.ExtraValue,
|
| | | self.Extras
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagGCVoiceChat=tagGCVoiceChat()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCVoiceChat.Head.Cmd,m_NAtagGCVoiceChat.Head.SubCmd))] = m_NAtagGCVoiceChat
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B3 11 聊天缓存通知 #tagGCTalkCache
|
| | |
|
| | | class tagGCTalkCacheInfo(Structure):
|
| | | ChannelType = 0 #(BYTE ChannelType)// 1 世界 2 仙盟
|
| | | NameLen = 0 #(BYTE NameLen)
|
| | | Name = "" #(String Name)//size = SrcNameLen
|
| | | PlayerID = 0 #(DWORD PlayerID)
|
| | | Time = 0 #(DWORD Time)
|
| | | Len = 0 #(WORD Len)
|
| | | Content = "" #(String Content)//size = Len
|
| | | Extras = "" #(char Extras[256])//附加值列表
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
|
| | | self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
|
| | | self.Extras,_pos = CommFunc.ReadString(_lpData, _pos,256)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.ChannelType = 0
|
| | | self.NameLen = 0
|
| | | self.Name = ""
|
| | | self.PlayerID = 0
|
| | | self.Time = 0
|
| | | self.Len = 0
|
| | | self.Content = ""
|
| | | self.Extras = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 1
|
| | | length += 1
|
| | | length += len(self.Name)
|
| | | length += 4
|
| | | length += 4
|
| | | length += 2
|
| | | length += len(self.Content)
|
| | | length += 256
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteBYTE(data, self.ChannelType)
|
| | | data = CommFunc.WriteBYTE(data, self.NameLen)
|
| | | data = CommFunc.WriteString(data, self.NameLen, self.Name)
|
| | | data = CommFunc.WriteDWORD(data, self.PlayerID)
|
| | | data = CommFunc.WriteDWORD(data, self.Time)
|
| | | data = CommFunc.WriteWORD(data, self.Len)
|
| | | data = CommFunc.WriteString(data, self.Len, self.Content)
|
| | | data = CommFunc.WriteString(data, 256, self.Extras)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | ChannelType:%d,
|
| | | NameLen:%d,
|
| | | Name:%s,
|
| | | PlayerID:%d,
|
| | | Time:%d,
|
| | | Len:%d,
|
| | | Content:%s,
|
| | | Extras:%s
|
| | | '''\
|
| | | %(
|
| | | self.ChannelType,
|
| | | self.NameLen,
|
| | | self.Name,
|
| | | self.PlayerID,
|
| | | self.Time,
|
| | | self.Len,
|
| | | self.Content,
|
| | | self.Extras
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagGCTalkCache(Structure):
|
| | | Head = tagHead()
|
| | | Count = 0 #(WORD Count)
|
| | | InfoList = list() #(vector<tagGCTalkCacheInfo> InfoList)//size = Count
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x11
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | for i in range(self.Count):
|
| | | temInfoList = tagGCTalkCacheInfo()
|
| | | _pos = temInfoList.ReadData(_lpData, _pos)
|
| | | self.InfoList.append(temInfoList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x11
|
| | | self.Count = 0
|
| | | self.InfoList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 2
|
| | | for i in range(self.Count):
|
| | | length += self.InfoList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteWORD(data, self.Count)
|
| | | for i in range(self.Count):
|
| | | data = CommFunc.WriteString(data, self.InfoList[i].GetLength(), self.InfoList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | Count:%d,
|
| | | InfoList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.Count,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagGCTalkCache=tagGCTalkCache()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCTalkCache.Head.Cmd,m_NAtagGCTalkCache.Head.SubCmd))] = m_NAtagGCTalkCache
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B5 04 拍卖行新上架拍品 #tagGCAddAuctionItemInfo
|
| | |
|
| | | class tagGCAddAuctionItem(Structure):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A7 07 通知玩家自定义聊天 #tagMCPyTalk
|
| | |
|
| | | class tagMCPyTalk(Structure):
|
| | | Head = tagHead()
|
| | | TalkType = 0 #(BYTE TalkType)// 自定义聊天类型
|
| | | NameLen = 0 #(BYTE NameLen)
|
| | | Name = "" #(String Name)//size = NameLen
|
| | | PlayerID = 0 #(DWORD PlayerID)
|
| | | Len = 0 #(WORD Len)
|
| | | Content = "" #(String Content)//size = Len
|
| | | ExtraValue = 0 #(DWORD ExtraValue)//附加值
|
| | | Extras = "" #(char Extras[256])//附加值列表
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xA7
|
| | | self.Head.SubCmd = 0x07
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.TalkType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
|
| | | self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
|
| | | self.ExtraValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Extras,_pos = CommFunc.ReadString(_lpData, _pos,256)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA7
|
| | | self.Head.SubCmd = 0x07
|
| | | self.TalkType = 0
|
| | | self.NameLen = 0
|
| | | self.Name = ""
|
| | | self.PlayerID = 0
|
| | | self.Len = 0
|
| | | self.Content = ""
|
| | | self.ExtraValue = 0
|
| | | self.Extras = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | length += len(self.Name)
|
| | | length += 4
|
| | | length += 2
|
| | | length += len(self.Content)
|
| | | length += 4
|
| | | length += 256
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.TalkType)
|
| | | data = CommFunc.WriteBYTE(data, self.NameLen)
|
| | | data = CommFunc.WriteString(data, self.NameLen, self.Name)
|
| | | data = CommFunc.WriteDWORD(data, self.PlayerID)
|
| | | data = CommFunc.WriteWORD(data, self.Len)
|
| | | data = CommFunc.WriteString(data, self.Len, self.Content)
|
| | | data = CommFunc.WriteDWORD(data, self.ExtraValue)
|
| | | data = CommFunc.WriteString(data, 256, self.Extras)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | TalkType:%d,
|
| | | NameLen:%d,
|
| | | Name:%s,
|
| | | PlayerID:%d,
|
| | | Len:%d,
|
| | | Content:%s,
|
| | | ExtraValue:%d,
|
| | | Extras:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.TalkType,
|
| | | self.NameLen,
|
| | | self.Name,
|
| | | self.PlayerID,
|
| | | self.Len,
|
| | | self.Content,
|
| | | self.ExtraValue,
|
| | | self.Extras
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCPyTalk=tagMCPyTalk()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCPyTalk.Head.Cmd,m_NAtagMCPyTalk.Head.SubCmd))] = m_NAtagMCPyTalk
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A7 08 通知跑环奖励记录 #tagMCRunTaskAwardInfo
|
| | |
|
| | | class tagMCRunTaskAwardRecord(Structure):
|
| | |
| | |
|
| | | class tagSCQueryPlayerCacheResult(Structure):
|
| | | Head = tagHead()
|
| | | PlayerID = 0 #(DWORD PlayerID)//玩家ID
|
| | | PropDataSize = 0 #(DWORD PropDataSize)
|
| | | PropData = "" #(String PropData)//属性记录
|
| | | ItemDataSize = 0 #(DWORD ItemDataSize)
|
| | | ItemData = "" #(String ItemData)//物品记录
|
| | | PlayerID = 0 #(DWORD PlayerID)
|
| | | PlayerName = "" #(char PlayerName[33])
|
| | | LV = 0 #(WORD LV)
|
| | | Job = 0 #(BYTE Job)
|
| | | RealmLV = 0 #(BYTE RealmLV)
|
| | | Face = 0 #(DWORD Face)
|
| | | FacePic = 0 #(DWORD FacePic)
|
| | | TitleID = 0 #(DWORD TitleID)//佩戴的称号
|
| | | ServerID = 0 #(DWORD ServerID)
|
| | | FightPower = 0 #(DWORD FightPower)
|
| | | FightPowerEx = 0 #(DWORD FightPowerEx)
|
| | | FamilyID = 0 #(DWORD FamilyID)
|
| | | FamilyName = "" #(char FamilyName[33])
|
| | | FamilyEmblemID = 0 #(DWORD FamilyEmblemID)//仙盟徽章ID
|
| | | PlusDataSize = 0 #(DWORD PlusDataSize)
|
| | | PlusData = "" #(String PlusData)//扩展记录
|
| | | data = None
|
| | |
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.PropDataSize,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.PropData,_pos = CommFunc.ReadString(_lpData, _pos,self.PropDataSize)
|
| | | self.ItemDataSize,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.ItemData,_pos = CommFunc.ReadString(_lpData, _pos,self.ItemDataSize)
|
| | | self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
|
| | | self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.RealmLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.TitleID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FamilyID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FamilyName,_pos = CommFunc.ReadString(_lpData, _pos,33)
|
| | | self.FamilyEmblemID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.PlusDataSize,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.PlusData,_pos = CommFunc.ReadString(_lpData, _pos,self.PlusDataSize)
|
| | | return _pos
|
| | |
| | | self.Head.Cmd = 0xA7
|
| | | self.Head.SubCmd = 0x05
|
| | | self.PlayerID = 0
|
| | | self.PropDataSize = 0
|
| | | self.PropData = ""
|
| | | self.ItemDataSize = 0
|
| | | self.ItemData = ""
|
| | | self.PlayerName = ""
|
| | | self.LV = 0
|
| | | self.Job = 0
|
| | | self.RealmLV = 0
|
| | | self.Face = 0
|
| | | self.FacePic = 0
|
| | | self.TitleID = 0
|
| | | self.ServerID = 0
|
| | | self.FightPower = 0
|
| | | self.FightPowerEx = 0
|
| | | self.FamilyID = 0
|
| | | self.FamilyName = ""
|
| | | self.FamilyEmblemID = 0
|
| | | self.PlusDataSize = 0
|
| | | self.PlusData = ""
|
| | | return
|
| | |
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 4
|
| | | length += 33
|
| | | length += 2
|
| | | length += 1
|
| | | length += 1
|
| | | length += 4
|
| | | length += len(self.PropData)
|
| | | length += 4
|
| | | length += len(self.ItemData)
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 33
|
| | | length += 4
|
| | | length += 4
|
| | | length += len(self.PlusData)
|
| | |
|
| | |
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteDWORD(data, self.PlayerID)
|
| | | data = CommFunc.WriteDWORD(data, self.PropDataSize)
|
| | | data = CommFunc.WriteString(data, self.PropDataSize, self.PropData)
|
| | | data = CommFunc.WriteDWORD(data, self.ItemDataSize)
|
| | | data = CommFunc.WriteString(data, self.ItemDataSize, self.ItemData)
|
| | | data = CommFunc.WriteString(data, 33, self.PlayerName)
|
| | | data = CommFunc.WriteWORD(data, self.LV)
|
| | | data = CommFunc.WriteBYTE(data, self.Job)
|
| | | data = CommFunc.WriteBYTE(data, self.RealmLV)
|
| | | data = CommFunc.WriteDWORD(data, self.Face)
|
| | | data = CommFunc.WriteDWORD(data, self.FacePic)
|
| | | data = CommFunc.WriteDWORD(data, self.TitleID)
|
| | | data = CommFunc.WriteDWORD(data, self.ServerID)
|
| | | data = CommFunc.WriteDWORD(data, self.FightPower)
|
| | | data = CommFunc.WriteDWORD(data, self.FightPowerEx)
|
| | | data = CommFunc.WriteDWORD(data, self.FamilyID)
|
| | | data = CommFunc.WriteString(data, 33, self.FamilyName)
|
| | | data = CommFunc.WriteDWORD(data, self.FamilyEmblemID)
|
| | | data = CommFunc.WriteDWORD(data, self.PlusDataSize)
|
| | | data = CommFunc.WriteString(data, self.PlusDataSize, self.PlusData)
|
| | | return data
|
| | |
| | | DumpString = '''
|
| | | Head:%s,
|
| | | PlayerID:%d,
|
| | | PropDataSize:%d,
|
| | | PropData:%s,
|
| | | ItemDataSize:%d,
|
| | | ItemData:%s,
|
| | | PlayerName:%s,
|
| | | LV:%d,
|
| | | Job:%d,
|
| | | RealmLV:%d,
|
| | | Face:%d,
|
| | | FacePic:%d,
|
| | | TitleID:%d,
|
| | | ServerID:%d,
|
| | | FightPower:%d,
|
| | | FightPowerEx:%d,
|
| | | FamilyID:%d,
|
| | | FamilyName:%s,
|
| | | FamilyEmblemID:%d,
|
| | | PlusDataSize:%d,
|
| | | PlusData:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.PlayerID,
|
| | | self.PropDataSize,
|
| | | self.PropData,
|
| | | self.ItemDataSize,
|
| | | self.ItemData,
|
| | | self.PlayerName,
|
| | | self.LV,
|
| | | self.Job,
|
| | | self.RealmLV,
|
| | | self.Face,
|
| | | self.FacePic,
|
| | | self.TitleID,
|
| | | self.ServerID,
|
| | | self.FightPower,
|
| | | self.FightPowerEx,
|
| | | self.FamilyID,
|
| | | self.FamilyName,
|
| | | self.FamilyEmblemID,
|
| | | self.PlusDataSize,
|
| | | self.PlusData
|
| | | )
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B3 10 聊天信息 #tagMCTalk
|
| | |
|
| | | class tagMCTalk(Structure):
|
| | | Head = tagHead()
|
| | | ChannelType = 0 #(BYTE ChannelType)// 0-世界;1-跨服;3- 仙盟 |
| | | NameLen = 0 #(BYTE NameLen)
|
| | | Name = "" #(String Name)//size = NameLen
|
| | | PlayerID = 0 #(DWORD PlayerID)
|
| | | Len = 0 #(WORD Len)
|
| | | Content = "" #(String Content)//size = Len
|
| | | BubbleBox = 0 #(DWORD BubbleBox)//聊天气泡框
|
| | | LV = 0 #(WORD LV)//等级
|
| | | Job = 0 #(BYTE Job)//ְҵ
|
| | | RealmLV = 0 #(BYTE RealmLV)//境界
|
| | | Face = 0 #(DWORD Face)//基本脸型
|
| | | FacePic = 0 #(DWORD FacePic)//头像框
|
| | | ServerID = 0 #(DWORD ServerID)//所属区服ID
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x10
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
|
| | | self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
|
| | | self.BubbleBox,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.RealmLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x10
|
| | | self.ChannelType = 0
|
| | | self.NameLen = 0
|
| | | self.Name = ""
|
| | | self.PlayerID = 0
|
| | | self.Len = 0
|
| | | self.Content = ""
|
| | | self.BubbleBox = 0
|
| | | self.LV = 0
|
| | | self.Job = 0
|
| | | self.RealmLV = 0
|
| | | self.Face = 0
|
| | | self.FacePic = 0
|
| | | self.ServerID = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | length += len(self.Name)
|
| | | length += 4
|
| | | length += 2
|
| | | length += len(self.Content)
|
| | | length += 4
|
| | | length += 2
|
| | | length += 1
|
| | | length += 1
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ChannelType)
|
| | | data = CommFunc.WriteBYTE(data, self.NameLen)
|
| | | data = CommFunc.WriteString(data, self.NameLen, self.Name)
|
| | | data = CommFunc.WriteDWORD(data, self.PlayerID)
|
| | | data = CommFunc.WriteWORD(data, self.Len)
|
| | | data = CommFunc.WriteString(data, self.Len, self.Content)
|
| | | data = CommFunc.WriteDWORD(data, self.BubbleBox)
|
| | | data = CommFunc.WriteWORD(data, self.LV)
|
| | | data = CommFunc.WriteBYTE(data, self.Job)
|
| | | data = CommFunc.WriteBYTE(data, self.RealmLV)
|
| | | data = CommFunc.WriteDWORD(data, self.Face)
|
| | | data = CommFunc.WriteDWORD(data, self.FacePic)
|
| | | data = CommFunc.WriteDWORD(data, self.ServerID)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ChannelType:%d,
|
| | | NameLen:%d,
|
| | | Name:%s,
|
| | | PlayerID:%d,
|
| | | Len:%d,
|
| | | Content:%s,
|
| | | BubbleBox:%d,
|
| | | LV:%d,
|
| | | Job:%d,
|
| | | RealmLV:%d,
|
| | | Face:%d,
|
| | | FacePic:%d,
|
| | | ServerID:%d
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ChannelType,
|
| | | self.NameLen,
|
| | | self.Name,
|
| | | self.PlayerID,
|
| | | self.Len,
|
| | | self.Content,
|
| | | self.BubbleBox,
|
| | | self.LV,
|
| | | self.Job,
|
| | | self.RealmLV,
|
| | | self.Face,
|
| | | self.FacePic,
|
| | | self.ServerID
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCTalk=tagMCTalk()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTalk.Head.Cmd,m_NAtagMCTalk.Head.SubCmd))] = m_NAtagMCTalk
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B3 11 聊天缓存通知 #tagMCTalkCacheList
|
| | |
|
| | | class tagMCTalkCacheInfo(Structure):
|
| | | NameLen = 0 #(BYTE NameLen)
|
| | | Name = "" #(String Name)//size = NameLen
|
| | | PlayerID = 0 #(DWORD PlayerID)
|
| | | Len = 0 #(WORD Len)
|
| | | Content = "" #(String Content)//size = Len
|
| | | BubbleBox = 0 #(DWORD BubbleBox)//聊天气泡框
|
| | | LV = 0 #(WORD LV)//等级
|
| | | Job = 0 #(BYTE Job)//ְҵ
|
| | | RealmLV = 0 #(BYTE RealmLV)//境界
|
| | | Face = 0 #(DWORD Face)//基本脸型
|
| | | FacePic = 0 #(DWORD FacePic)//头像框
|
| | | ServerID = 0 #(DWORD ServerID)//所属区服ID
|
| | | TalkTime = 0 #(DWORD TalkTime)//该聊天发送时间戳
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
|
| | | self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
|
| | | self.BubbleBox,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.RealmLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.TalkTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.NameLen = 0
|
| | | self.Name = ""
|
| | | self.PlayerID = 0
|
| | | self.Len = 0
|
| | | self.Content = ""
|
| | | self.BubbleBox = 0
|
| | | self.LV = 0
|
| | | self.Job = 0
|
| | | self.RealmLV = 0
|
| | | self.Face = 0
|
| | | self.FacePic = 0
|
| | | self.ServerID = 0
|
| | | self.TalkTime = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 1
|
| | | length += len(self.Name)
|
| | | length += 4
|
| | | length += 2
|
| | | length += len(self.Content)
|
| | | length += 4
|
| | | length += 2
|
| | | length += 1
|
| | | length += 1
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteBYTE(data, self.NameLen)
|
| | | data = CommFunc.WriteString(data, self.NameLen, self.Name)
|
| | | data = CommFunc.WriteDWORD(data, self.PlayerID)
|
| | | data = CommFunc.WriteWORD(data, self.Len)
|
| | | data = CommFunc.WriteString(data, self.Len, self.Content)
|
| | | data = CommFunc.WriteDWORD(data, self.BubbleBox)
|
| | | data = CommFunc.WriteWORD(data, self.LV)
|
| | | data = CommFunc.WriteBYTE(data, self.Job)
|
| | | data = CommFunc.WriteBYTE(data, self.RealmLV)
|
| | | data = CommFunc.WriteDWORD(data, self.Face)
|
| | | data = CommFunc.WriteDWORD(data, self.FacePic)
|
| | | data = CommFunc.WriteDWORD(data, self.ServerID)
|
| | | data = CommFunc.WriteDWORD(data, self.TalkTime)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | NameLen:%d,
|
| | | Name:%s,
|
| | | PlayerID:%d,
|
| | | Len:%d,
|
| | | Content:%s,
|
| | | BubbleBox:%d,
|
| | | LV:%d,
|
| | | Job:%d,
|
| | | RealmLV:%d,
|
| | | Face:%d,
|
| | | FacePic:%d,
|
| | | ServerID:%d,
|
| | | TalkTime:%d
|
| | | '''\
|
| | | %(
|
| | | self.NameLen,
|
| | | self.Name,
|
| | | self.PlayerID,
|
| | | self.Len,
|
| | | self.Content,
|
| | | self.BubbleBox,
|
| | | self.LV,
|
| | | self.Job,
|
| | | self.RealmLV,
|
| | | self.Face,
|
| | | self.FacePic,
|
| | | self.ServerID,
|
| | | self.TalkTime
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCTalkCacheList(Structure):
|
| | | Head = tagHead()
|
| | | ChannelType = 0 #(BYTE ChannelType)// 0-世界;1-跨服;3- 仙盟 |
| | | Count = 0 #(BYTE Count)
|
| | | InfoList = list() #(vector<tagMCTalkCacheInfo> InfoList)//size = Count
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x11
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.Count):
|
| | | temInfoList = tagMCTalkCacheInfo()
|
| | | _pos = temInfoList.ReadData(_lpData, _pos)
|
| | | self.InfoList.append(temInfoList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xB3
|
| | | self.Head.SubCmd = 0x11
|
| | | self.ChannelType = 0
|
| | | self.Count = 0
|
| | | self.InfoList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.Count):
|
| | | length += self.InfoList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ChannelType)
|
| | | data = CommFunc.WriteBYTE(data, self.Count)
|
| | | for i in range(self.Count):
|
| | | data = CommFunc.WriteString(data, self.InfoList[i].GetLength(), self.InfoList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ChannelType:%d,
|
| | | Count:%d,
|
| | | InfoList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ChannelType,
|
| | | self.Count,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCTalkCacheList=tagMCTalkCacheList()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTalkCacheList.Head.Cmd,m_NAtagMCTalkCacheList.Head.SubCmd))] = m_NAtagMCTalkCacheList
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B4 11 新增恶意攻击玩家 #tagMCAddMaliciousAtkPlayer
|
| | |
|
| | | class tagMCAddMaliciousAtkPlayer(Structure):
|
| | |
| | | import DBPlayerViewCache
|
| | | import DBEventTrig
|
| | | import DBBillboard
|
| | | import DBGameRec
|
| | | import DBFamily
|
| | | import DBMail
|
| | |
|
| | |
| | | self.BillboardMgr = DBBillboard.BillboardMgr()
|
| | | self.MailMgr = DBMail.MailMgr()
|
| | | self.FamilyMgr = DBFamily.FamilyMgr()
|
| | | self.GameRecMgr = DBGameRec.GameRecMgr()
|
| | | return
|
| | |
|
| | | def GetSaveData(self):
|
| | |
| | | buff += self.BillboardMgr.GetSaveData()
|
| | | buff += self.MailMgr.GetSaveData()
|
| | | buff += self.FamilyMgr.GetSaveData()
|
| | | buff += self.GameRecMgr.GetSaveData()
|
| | | return buff
|
| | |
|
| | | def LoadGameData(self, gameBuffer, pos):
|
| | |
| | | pos = self.BillboardMgr.LoadPyGameData(gameBuffer, pos, dataslen)
|
| | | pos = self.MailMgr.LoadPyGameData(gameBuffer, pos, dataslen)
|
| | | pos = self.FamilyMgr.LoadPyGameData(gameBuffer, pos, dataslen)
|
| | | pos = self.GameRecMgr.LoadPyGameData(gameBuffer, pos, dataslen)
|
| | | return pos
|
| | |
|
| | | def GetDBDataMgr():
|
| | |
| | | dbDataMgr = GetDBDataMgr()
|
| | | return dbDataMgr.BillboardMgr
|
| | |
|
| | | def GetGameRecMgr():
|
| | | ## 通用记录数据管理器
|
| | | dbDataMgr = GetDBDataMgr()
|
| | | return dbDataMgr.GameRecMgr
|
| | |
|
| | |
| | | self.Name2 = Str[:65]
|
| | |
|
| | |
|
| | | # 通用记录表新 #tagDBGameRec
|
| | | class tagDBGameRec(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ('RecType', ctypes.c_ushort),
|
| | | ('RecID', ctypes.c_ulong),
|
| | | ('Time', ctypes.c_double),
|
| | | ('Value1', ctypes.c_ulong),
|
| | | ('Value2', ctypes.c_ulong),
|
| | | ('Value3', ctypes.c_ulong),
|
| | | ('Value4', ctypes.c_ulong),
|
| | | ('Value5', ctypes.c_ulong),
|
| | | ('Value6', ctypes.c_ulong),
|
| | | ('Value7', ctypes.c_ulong),
|
| | | ('Value8', ctypes.c_ulong),
|
| | | ('UserDataLen', ctypes.c_ushort),
|
| | | ('UserData', ctypes.c_char_p),
|
| | | ('ADOResult', ctypes.c_ulong),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | Structure.__init__(self)
|
| | | self.clear()
|
| | |
|
| | | def clear(self):
|
| | | self.RecType = 0
|
| | | self.RecID = 0
|
| | | self.Time = 0.0
|
| | | self.Value1 = 0
|
| | | self.Value2 = 0
|
| | | self.Value3 = 0
|
| | | self.Value4 = 0
|
| | | self.Value5 = 0
|
| | | self.Value6 = 0
|
| | | self.Value7 = 0
|
| | | self.Value8 = 0
|
| | | self.UserDataLen = 0
|
| | | self.UserData = ''
|
| | |
|
| | | def readData(self, buf, pos = 0, length = 0):
|
| | | if not pos <= length:
|
| | | return -1
|
| | | if len(buf) < pos + self.getLength():
|
| | | return -1
|
| | | self.clear()
|
| | | self.RecType, pos = CommFunc.ReadWORD(buf, pos)
|
| | | self.RecID, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Time, pos = CommFunc.ReadDouble(buf, pos)
|
| | | self.Value1, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value2, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value3, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value4, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value5, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value6, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value7, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value8, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.UserDataLen, pos = CommFunc.ReadWORD(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.UserDataLen)
|
| | | self.UserData = ctypes.c_char_p(tmp)
|
| | | return self.getLength()
|
| | |
|
| | | def getBuffer(self):
|
| | | buf = ''
|
| | | buf = CommFunc.WriteWORD(buf, self.RecType)
|
| | | buf = CommFunc.WriteDWORD(buf, self.RecID)
|
| | | buf = CommFunc.WriteDouble(buf, self.Time)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value1)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value2)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value3)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value4)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value5)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value6)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value7)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value8)
|
| | | buf = CommFunc.WriteWORD(buf, self.UserDataLen)
|
| | | buf = CommFunc.WriteString(buf, self.UserDataLen, self.UserData)
|
| | | return buf
|
| | |
|
| | | def getLength(self):
|
| | | length = 0
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_double)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += self.UserDataLen
|
| | | return length
|
| | |
|
| | | def outputString(self):
|
| | | output = '''// 通用记录表新 #tagDBGameRec:
|
| | | RecType = %s,
|
| | | RecID = %s,
|
| | | Time = %s,
|
| | | Value1 = %s,
|
| | | Value2 = %s,
|
| | | Value3 = %s,
|
| | | Value4 = %s,
|
| | | Value5 = %s,
|
| | | Value6 = %s,
|
| | | Value7 = %s,
|
| | | Value8 = %s,
|
| | | UserDataLen = %s,
|
| | | UserData = %s,
|
| | | ADOResult = %s,
|
| | | '''%(
|
| | | self.RecType,
|
| | | self.RecID,
|
| | | self.Time,
|
| | | self.Value1,
|
| | | self.Value2,
|
| | | self.Value3,
|
| | | self.Value4,
|
| | | self.Value5,
|
| | | self.Value6,
|
| | | self.Value7,
|
| | | self.Value8,
|
| | | self.UserDataLen,
|
| | | self.UserData,
|
| | | self.ADOResult,
|
| | | )
|
| | | return output
|
| | |
|
| | |
|
| | |
|
| | | #服务器世界数据表版本号
|
| | | GAMEWORLD_DATA_VERSION_NO = ctypes.c_ulong (\
|
| | | sizeof(tagDBEventTrig) + sizeof(tagDBFamily) + sizeof(tagDBFamilyMem) + sizeof(tagDBFamilyAction) +
|
| | | sizeof(tagDBPlayerViewCache) + sizeof(tagDBMailPersonal) + sizeof(tagDBMailServer) + sizeof(tagDBMailItem) +
|
| | | sizeof(tagDBMailPlayerRec) + sizeof(tagDBBillboard) |
| | | sizeof(tagDBMailPlayerRec) + sizeof(tagDBBillboard) + sizeof(tagDBGameRec)
|
| | | ).value
|
| | | |
| | |
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import PlayerViewCache
|
| | | import PyMongoMain
|
| | | import DBDataMgr
|
| | | import ChConfig
|
| | |
| | | self.__actionDataList.append(actionData)
|
| | | return actionData
|
| | |
|
| | | def AddAction(self, fullClear=True):
|
| | | def AddAction(self, maxCount=None):
|
| | | ## 添加仙盟Action数据
|
| | | # @param fullClear: 数据条数超过最大数时是否清除最早一条,并创建一条新记录
|
| | | # @param maxCount: 可传入由配置决定的最大条数,如果为None则进一步取程序默认设定的最大条数,都没配置的话默认不限条数
|
| | |
|
| | | fullClear = True
|
| | | if maxCount == None:
|
| | | maxCount = ShareDefine.ActionTypeSaveCnt.get(self.actionType, 0)
|
| | | actionData = None
|
| | | if self.Count() >= ChConfig.ActionTypeSaveCnt.get(self.actionType, 0):
|
| | | if maxCount and self.Count() >= maxCount:
|
| | | if not fullClear:
|
| | | #超过记录记录不了了
|
| | | return actionData
|
| | |
| | | ## 根据玩家ID更新成员数据,一般用于离线功能,如添加离线成员,直接使用查看缓存更新
|
| | | if playerID != self.GetPlayerID():
|
| | | return
|
| | | viewCache = DBDataMgr.GetPlayerViewCacheMgr().FindViewCache(playerID)
|
| | | viewCache = PlayerViewCache.FindViewCache(playerID)
|
| | | if not viewCache:
|
| | | return
|
| | | self.SetPlayerName(viewCache.GetPlayerName())
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package DB.StructData.DBGameRec
|
| | | #
|
| | | # @todo:通用记录表新
|
| | | # @author hxp
|
| | | # @date 2025-05-23
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 通用记录表新,原通用记录字符长度记录有限,且针对某个记录类型下的子类型查找每次需要遍历,效率不高
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2025-05-23 20:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import DBStruct
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import CommFunc
|
| | | import DBComm
|
| | |
|
| | | import time
|
| | |
|
| | | class GameRecData():
|
| | | |
| | | def __init__(self, dbData=None, dataToJson=False):
|
| | | if not dbData:
|
| | | dbData = DBStruct.tagDBGameRec()
|
| | | self.__dbData = dbData
|
| | | self.__dataDict = DBComm.UserDataDict(self.__dbData, "UserData", "UserDataLen", dataToJson)
|
| | | return
|
| | | def GetRecType(self): return self.__dbData.RecType
|
| | | def SetRecType(self, recType): self.__dbData.RecType = recType
|
| | | def GetRecID(self): return self.__dbData.RecID
|
| | | def SetRecID(self, recID): self.__dbData.RecID = recID
|
| | | def GetTime(self): return self.__dbData.Time
|
| | | def SetTime(self, sTime): self.__dbData.Time = sTime
|
| | | def GetValue1(self): return self.__dbData.Value1
|
| | | def SetValue1(self, value1): self.__dbData.Value1 = value1
|
| | | def GetValue2(self): return self.__dbData.Value2
|
| | | def SetValue2(self, value2): self.__dbData.Value2 = value2
|
| | | def GetValue3(self): return self.__dbData.Value3
|
| | | def SetValue3(self, value3): self.__dbData.Value3 = value3
|
| | | def GetValue4(self): return self.__dbData.Value4
|
| | | def SetValue4(self, value4): self.__dbData.Value4 = value4
|
| | | def GetValue5(self): return self.__dbData.Value5
|
| | | def SetValue5(self, value5): self.__dbData.Value5 = value5
|
| | | def GetValue6(self): return self.__dbData.Value6
|
| | | def SetValue6(self, value6): self.__dbData.Value6 = value6
|
| | | def GetValue7(self): return self.__dbData.Value7
|
| | | def SetValue7(self, value7): self.__dbData.Value7 = value7
|
| | | def GetValue8(self): return self.__dbData.Value8
|
| | | def SetValue8(self, value8): self.__dbData.Value8 = value8
|
| | | def GetUserDict(self): return self.__dataDict.GetData()
|
| | | def GetUserData(self): return self.__dataDict.ToString()
|
| | | def SetUserData(self, value): self.__dataDict.SetData(value)
|
| | | def GetBuffer(self):
|
| | | self.__dataDict.ToString()
|
| | | return self.__dbData.getBuffer()
|
| | | |
| | | def IsMatchValue(self, valueList):
|
| | | # 检查记录值列表是否配置该记录
|
| | | # @param valueList: [value1, value2, ...] value为None时不判断该值
|
| | | if not valueList:
|
| | | return False
|
| | | for i, value in enumerate(valueList, 1):
|
| | | if value == None:
|
| | | continue
|
| | | if not hasattr(self, "GetValue%s" % i):
|
| | | return False
|
| | | curValue = getattr(self, "GetValue%s" % i)()
|
| | | if curValue != value:
|
| | | return False
|
| | | return True
|
| | | |
| | | def GetValueIndexKey(self):
|
| | | ## 获取Value快速查找索引key,默认使用value1
|
| | | recType = self.GetRecType()
|
| | | if recType not in ShareDefine.Def_GameRecValueKeyDict:
|
| | | return ""
|
| | | valueNumList = ShareDefine.Def_GameRecValueKeyDict[recType]
|
| | | if not valueNumList:
|
| | | valueNumList = [1]
|
| | | keyStr = ""
|
| | | for num in valueNumList:
|
| | | if not hasattr(self, "GetValue%s" % num):
|
| | | return ""
|
| | | if keyStr:
|
| | | keyStr += "_"
|
| | | keyStr += str(getattr(self, "GetValue%s" % num)())
|
| | | return keyStr
|
| | | |
| | | class GameRecIDMgr():
|
| | | ## 类型数据ID管理
|
| | | |
| | | def __init__(self, recType, recID):
|
| | | self.__recType = recType
|
| | | self.__recID = recID
|
| | | self.__dataList = [] # 数据列表 [GameRecData, ...]
|
| | | self.__valueIndexDict = {} # value索引值对应数据列表 {indexKey:[GameRecData, ...], ...}
|
| | | return
|
| | | |
| | | def InitRecDataInstance(self, dbData):
|
| | | '''初始化功能数据实例,创建或加载数据时通用,功能一般不调用
|
| | | @param dbData: 实例对应绑定的dbData
|
| | | @return: 成功返回实例对象,失败返回None
|
| | | '''
|
| | | dataToJson = False
|
| | | # 如果需要 dataToJson,可根据 RecType 在这里处理
|
| | | if dbData.RecType in []:
|
| | | dataToJson = True
|
| | | recData = GameRecData(dbData, dataToJson)
|
| | | self.__dataList.append(recData)
|
| | | |
| | | keyStr = recData.GetValueIndexKey()
|
| | | if keyStr:
|
| | | if keyStr not in self.__valueIndexDict:
|
| | | self.__valueIndexDict[keyStr] = []
|
| | | recIndexDataList = self.__valueIndexDict[keyStr]
|
| | | recIndexDataList.append(recData)
|
| | | |
| | | return recData
|
| | | |
| | | def GetRecType(self): return self.__recType
|
| | | def GetRecID(self): return self.__recID
|
| | | |
| | | def SortByTime(self):
|
| | | self.__dataList.sort(key=lambda r: (r.GetTime()), reverse=False)
|
| | | return
|
| | | |
| | | def AddRecData(self, maxCount=None):
|
| | | '''添加记录
|
| | | @param maxCount: 可传入由配置决定的最大条数,如果为None则进一步取程序默认设定的最大条数,都没配置的话默认不限条数
|
| | | '''
|
| | | |
| | | fullClear = True
|
| | | recData = None
|
| | | if maxCount == None:
|
| | | maxCount = 0
|
| | | if maxCount and self.GetCount() >= maxCount:
|
| | | if not fullClear:
|
| | | #超过记录记录不了了
|
| | | return recData
|
| | | #self.SortByTime() # 按时间升序
|
| | | self.DelCount(self.GetCount() - maxCount + 1)
|
| | | |
| | | dbData = DBStruct.tagDBGameRec()
|
| | | dbData.RecType = self.__recType
|
| | | dbData.RecID = self.__recID
|
| | | dbData.Time = int(time.time())
|
| | | #if valueSetList:
|
| | | # for num, v in enumerate(valueSetList, 1):
|
| | | # if not hasattr(dbData, "Value%s" % num):
|
| | | # continue
|
| | | # setattr(dbData, "Value%s" % num, v
|
| | | |
| | | recData = self.InitRecDataInstance(dbData)
|
| | | return recData
|
| | | |
| | | def GetCount(self): return len(self.__dataList)
|
| | | def At(self, index):
|
| | | recData = None
|
| | | if 0 <= index < len(self.__dataList):
|
| | | recData = self.__dataList[index]
|
| | | elif False:
|
| | | recData = GameRecData()
|
| | | return recData
|
| | | |
| | | def GetOneRecData(self, isAddNew=False):
|
| | | ## 获取第一条记录,适用于仅需一条的记录类型
|
| | | # @param isAddNew: 没有记录时是否添加一条新记录,一般获取后需要更新数据的可以设置为True,仅判断用的建议设置为False,减少产生多余空数据
|
| | | recData = None
|
| | | if self.__dataList:
|
| | | recData = self.__dataList[0]
|
| | | elif isAddNew:
|
| | | recData = self.AddRecData()
|
| | | return recData
|
| | | |
| | | def GetRecDataByValues(self, valueList, findone=False):
|
| | | '''获取匹配value值的记录
|
| | | @param valueList: [value1, value2, ...] value为None时不判断该值
|
| | | @param findone: 是否只匹配一条满足的记录
|
| | | @return: recData or [recData, ...] or None
|
| | | '''
|
| | | |
| | | # 有配置value索引key的,直接快速获取
|
| | | if self.__recType in ShareDefine.Def_GameRecValueKeyDict:
|
| | | keyStr = ""
|
| | | for v in valueList:
|
| | | if keyStr:
|
| | | keyStr += "_"
|
| | | keyStr += str(v)
|
| | | if keyStr not in self.__valueIndexDict:
|
| | | return
|
| | | recIndexDataList = self.__valueIndexDict[keyStr]
|
| | | if not recIndexDataList:
|
| | | return
|
| | | return recIndexDataList[0] if findone else recIndexDataList
|
| | | |
| | | # 没有的则遍历匹配
|
| | | matchRecDataList = []
|
| | | for recData in self.__dataList:
|
| | | if not recData.IsMatchValue(valueList):
|
| | | continue
|
| | | if findone:
|
| | | return recData
|
| | | matchRecDataList.append(recData)
|
| | | return matchRecDataList
|
| | | |
| | | def DelAllData(self):
|
| | | ## 删除该记录ID的所有数据
|
| | | dataCount = self.GetCount()
|
| | | if not dataCount:
|
| | | return 0
|
| | | #GameWorld.DebugLog("删除通用记录某个类型ID所有记录: recType=%s,recID=%s,dataCount=%s" % (self.__recType, self.__recID, dataCount))
|
| | | self.__dataList = []
|
| | | self.__valueIndexDict = {}
|
| | | return dataCount
|
| | | |
| | | def DelDataByValue(self, valueList):
|
| | | ## 删除该记录ID所有匹配Value值列表的数据记录
|
| | | # @param valueList: [value1, value2, ...] value为None时不判断该值
|
| | | if not valueList:
|
| | | return 0
|
| | | |
| | | delCount = 0
|
| | | for recData in self.__dataList[::-1]: # 倒序处理删除
|
| | | if recData.IsMatchValue(valueList):
|
| | | self.DelRecData(recData)
|
| | | delCount += 1
|
| | | |
| | | #if delCount:
|
| | | # GameWorld.DebugLog("删除通用记录某个类型ID所有匹配Value值的记录: recType=%s,recID=%s,valueList=%s,delCount=%s" |
| | | # % (self.__recType, self.__recID, valueList, delCount))
|
| | | return delCount
|
| | | |
| | | def DelRecData(self, recData):
|
| | | ## 删除指定记录
|
| | | if not recData:
|
| | | return 0
|
| | | |
| | | if recData in self.__dataList:
|
| | | self.__dataList.remove(recData)
|
| | | |
| | | keyStr = recData.GetValueIndexKey()
|
| | | if keyStr in self.__valueIndexDict:
|
| | | recIndexDataList = self.__valueIndexDict[keyStr]
|
| | | if recData in recIndexDataList:
|
| | | recIndexDataList.remove(recData)
|
| | | |
| | | return 1
|
| | | |
| | | def DelCount(self, delCount, reverse=False):
|
| | | ## 删除条数
|
| | | # @param reverse: False-从索引0开始删除,True-从最后一个索引往前删
|
| | | delDataList = self.__dataList[:delCount] if not reverse else self.__dataList[-delCount-1:]
|
| | | for recData in delDataList:
|
| | | self.DelRecData(recData)
|
| | | #GameWorld.DebugLog("删除通用记录条数: recType=%s,recID=%s,delCount=%s,remainCount=%s" |
| | | # % (self.__recType, self.__recID, delCount, len(self.__dataList)))
|
| | | return
|
| | | |
| | | class GameRecTypeMgr():
|
| | | ## 类型管理
|
| | | |
| | | def __init__(self, recType):
|
| | | self.__recType = recType
|
| | | self.__recIDDict = {} # recID对应数据列表 {recID:GameRecIDMgr, ...}
|
| | | return
|
| | | |
| | | def GetRecType(self): return self.__recType
|
| | | |
| | | def GetRecIDMgr(self, recID):
|
| | | recIDMgr = None
|
| | | if recID in self.__recIDDict:
|
| | | recIDMgr = self.__recIDDict[recID]
|
| | | else:
|
| | | recIDMgr = GameRecIDMgr(self.__recType, recID)
|
| | | self.__recIDDict[recID] = recIDMgr
|
| | | return recIDMgr
|
| | | |
| | | def GetRecIDList(self): return self.__recIDDict.keys()
|
| | | |
| | | def GetRecDataByValues(self, valueList, findone=False):
|
| | | ## 获取该类型所有记录匹配value值的记录
|
| | | matchRecDataList = []
|
| | | for recID in self.__recIDDict.keys():
|
| | | recIDMgr = self.GetRecIDMgr(recID)
|
| | | ret = recIDMgr.GetRecDataByValues(valueList, findone)
|
| | | if not ret:
|
| | | continue
|
| | | if findone:
|
| | | return ret
|
| | | |
| | | if isinstance(ret, list):
|
| | | matchRecDataList += ret
|
| | | |
| | | return matchRecDataList
|
| | | |
| | | def DelAllData(self):
|
| | | ## 删除该类型所有记录
|
| | | delCount = 0
|
| | | for recID in self.__recIDDict.keys():
|
| | | delCount += self.DelDataByRecID(recID)
|
| | | return delCount
|
| | | def DelDataByRecID(self, recID):
|
| | | ## 删除该类型某个记录ID的所有记录
|
| | | return self.GetRecIDMgr(recID).DelAllData()
|
| | | def DelDataByValue(self, valueList):
|
| | | ## 删除该类型所有匹配Value值列表的记录
|
| | | delCount = 0
|
| | | for recID in self.__recIDDict.keys():
|
| | | recIDMgr = self.GetRecIDMgr(recID)
|
| | | delCount += recIDMgr.DelDataByValue(valueList)
|
| | | return delCount
|
| | | |
| | | class GameRecMgr():
|
| | | ## 通用记录管理
|
| | | |
| | | def __init__(self):
|
| | | self.__recTypeDict = {} # {recType:GameRecTypeMgr, ...}
|
| | | return
|
| | | |
| | | def GetRecTypeMgr(self, recType):
|
| | | recTypeMgr = None
|
| | | if recType in self.__recTypeDict:
|
| | | recTypeMgr = self.__recTypeDict[recType]
|
| | | else:
|
| | | recTypeMgr = GameRecTypeMgr(recType)
|
| | | self.__recTypeDict[recType] = recTypeMgr
|
| | | return recTypeMgr
|
| | | |
| | | def GetRecTypeIDMgr(self, recType, recID):
|
| | | recTypeMgr = self.GetRecTypeMgr(recType)
|
| | | recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
|
| | | if not recTypeIDMgr and False:
|
| | | recTypeIDMgr = GameRecIDMgr(recType, recID)
|
| | | return recTypeIDMgr
|
| | | |
| | | # 保存数据 存数据库和realtimebackup
|
| | | def GetSaveData(self):
|
| | | savaData = ""
|
| | | cntData = ""
|
| | | cnt = 0
|
| | | |
| | | for recType in self.__recTypeDict.keys():
|
| | | recTypeMgr = self.GetRecTypeMgr(recType)
|
| | | for recID in recTypeMgr.GetRecIDList():
|
| | | recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
|
| | | for index in range(recTypeIDMgr.GetCount()):
|
| | | recData = recTypeIDMgr.At(index)
|
| | | savaData += recData.GetBuffer()
|
| | | cnt += 1
|
| | | |
| | | GameWorld.Log("Save DBGameRec count :%s len=%s" % (cnt, len(savaData)))
|
| | | return CommFunc.WriteDWORD(cntData, cnt) + savaData
|
| | | |
| | | # 从数据库载入数据
|
| | | def LoadPyGameData(self, datas, pos, dataslen):
|
| | | cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
| | | GameWorld.Log("Load DBGameRec count :%s" % cnt)
|
| | | |
| | | for _ in xrange(cnt):
|
| | | dbData = DBStruct.tagDBGameRec()
|
| | | dbData.readData(datas, pos, dataslen)
|
| | | recType = dbData.RecType
|
| | | recID = dbData.RecID
|
| | | recTypeIDMgr = self.GetRecTypeIDMgr(recType, recID)
|
| | | recTypeIDMgr.InitRecDataInstance(dbData)
|
| | | |
| | | for recType in self.__recTypeDict.keys():
|
| | | recTypeMgr = self.GetRecTypeMgr(recType)
|
| | | for recID in recTypeMgr.GetRecIDList():
|
| | | recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
|
| | | recTypeIDMgr.SortByTime()
|
| | | |
| | | return pos
|
| | | |
| | | |
| | |
|
| | |
|
| | |
| | | import DBComm
|
| | | import DBStruct
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import DBDataMgr
|
| | | import CommFunc
|
| | | import ChConfig
|
| | | import GameObj
|
| | |
|
| | | import random
|
| | | import time
|
| | |
|
| | | Key_UpdViewCacheTick = "UpdViewCacheTick"
|
| | |
|
| | | class PlayerViewCache():
|
| | |
|
| | |
| | |
|
| | | def __init__(self):
|
| | | self.__viewCacheList = [] # [PlayerViewCache, ...]
|
| | | self.__idIndexDict = {} # {playerID:index, ...}
|
| | | self.__viewCacheDict = {} # {playerID:PlayerViewCache, ...}
|
| | | self.__needSort = False
|
| | | self.__serverIDRangePlayerIDDict = {} # {serverIDRangeTuple:[playerID, ...], ....}
|
| | | return
|
| | |
|
| | | def InitViewCacheInstance(self, dbData):
|
| | | def __InitViewCacheInstance(self, dbData):
|
| | | '''初始化功能数据实例,创建或加载数据时通用,功能一般不调用
|
| | | @param dbData: 实例对应绑定的dbData
|
| | | @return: 成功返回实例对象,失败返回None
|
| | | '''
|
| | | playerID = dbData.PlayerID
|
| | | self.__refreshIDIndex()
|
| | | if playerID in self.__idIndexDict:
|
| | | if playerID in self.__viewCacheDict:
|
| | | return
|
| | | viewCache = PlayerViewCache(dbData)
|
| | | self.__viewCacheList.append(viewCache)
|
| | | self.__idIndexDict[playerID] = len(self.__viewCacheList) - 1
|
| | | self.__viewCacheDict[playerID] = viewCache
|
| | | self.__needSort = True
|
| | | return viewCache
|
| | |
|
| | | def CheckUpdViewCache(self, playerID):
|
| | | if playerID <= ShareDefine.FackPlayerIDMax:
|
| | | return
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | lastUpdTick = curPlayer.GetDictByKey(Key_UpdViewCacheTick)
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | if lastUpdTick and tick - lastUpdTick < 60000:
|
| | | GameWorld.DebugLog("1分钟内只更新一次玩家缓存", playerID)
|
| | | return
|
| | | curPlayer.SetDict(Key_UpdViewCacheTick, tick)
|
| | | return UpdPlayerViewCache(curPlayer)
|
| | | |
| | | def FindViewCache(self, playerID, isAdd=False):
|
| | | '''查找玩家缓存,如果不存在,则会有额外逻辑,如从redis、db直接找,
|
| | | 跨服玩家从跨服取,可能延迟获得
|
| | | '''
|
| | | curCache = self.GetPlayerViewCache(playerID)
|
| | | if curCache:
|
| | | updCache = self.CheckUpdViewCache(playerID)
|
| | | if updCache:
|
| | | curCache = updCache
|
| | | |
| | | # 真实玩家
|
| | | elif playerID > ShareDefine.FackPlayerIDMax:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | # 本服在线玩家,直接生成新数据
|
| | | if curPlayer:
|
| | | dbData = DBStruct.tagDBPlayerViewCache()
|
| | | dbData.PlayerID = playerID
|
| | | self.InitViewCacheInstance(dbData)
|
| | | UpdPlayerViewCache(curPlayer)
|
| | | |
| | | # 离线玩家
|
| | | else:
|
| | | pass
|
| | | # 本服玩家,从redis或db读取重新加载读取,换句话说,本服玩家只要获取一定有查看缓存数据
|
| | | # 跨服玩家,去子服拉取数据,理论上也一定有,但是如果需要拉数据,有一定延迟
|
| | | # 逻辑待扩展
|
| | | |
| | | # 假玩家,默认添加
|
| | | elif ShareDefine.FackPlayerIDStart <= playerID <= ShareDefine.FackPlayerIDMax:
|
| | | serverID = playerID % 100 + 1 # 1 ~ 100 服
|
| | | accID = "fake%s@test@s%s" % (playerID, serverID)
|
| | | fightPower = random.randint(1000000, 100000000) # 先随机,外层有需要的话再自己设置
|
| | | |
| | | dbData = DBStruct.tagDBPlayerViewCache()
|
| | | dbData.PlayerID = playerID
|
| | | dbData.PlayerName = "%s%s" % (GameWorld.GbkToCode("神秘道友"), playerID)
|
| | | dbData.AccID = accID
|
| | | dbData.LV = random.randint(100, 200)
|
| | | dbData.Job = random.randint(1, 2)
|
| | | dbData.RealmLV = random.randint(5, 15)
|
| | | dbData.FightPower = fightPower % ChConfig.Def_PerPointValue
|
| | | dbData.FightPowerEx = fightPower / ChConfig.Def_PerPointValue
|
| | | dbData.ServerID = serverID
|
| | | dbData.OffTime = int(time.time()) - random.randint(1, 3600 * 24 * 10) # 随机离线 0~10天
|
| | | curCache = self.InitViewCacheInstance(dbData)
|
| | | |
| | | return curCache
|
| | | def AddPlayerViewCache(self, playerID):
|
| | | dbData = DBStruct.tagDBPlayerViewCache()
|
| | | dbData.PlayerID = playerID
|
| | | return self.__InitViewCacheInstance(dbData)
|
| | |
|
| | | def GetPlayerViewCache(self, playerID):
|
| | | ## 获取玩家查看缓存,仅内存中数据,无额外逻辑
|
| | | self.__refreshIDIndex()
|
| | | viewCache = None
|
| | | if playerID in self.__idIndexDict:
|
| | | index = self.__idIndexDict[playerID]
|
| | | if index < len(self.__viewCacheList):
|
| | | viewCache = self.__viewCacheList[index]
|
| | | |
| | | if playerID in self.__viewCacheDict:
|
| | | viewCache = self.__viewCacheDict[playerID]
|
| | | |
| | | if not viewCache and False:
|
| | | viewCache = PlayerViewCache()
|
| | |
|
| | |
| | | self.__serverIDRangePlayerIDDict[key] = playerIDList
|
| | | return self.__serverIDRangePlayerIDDict[key]
|
| | |
|
| | | def IsPlayerIn(self, playerID):
|
| | | self.__refreshIDIndex()
|
| | | return playerID in self.__idIndexDict
|
| | | |
| | | def __refreshIDIndex(self):
|
| | | if not self.__idIndexDict:
|
| | | self.__idIndexDict = {}
|
| | | for index, viewCache in enumerate(self.__viewCacheList):
|
| | | self.__idIndexDict[viewCache.GetPlayerID()] = index
|
| | | return self.__idIndexDict
|
| | | |
| | | def DelPlayerViewCache(self, playerID):
|
| | | self.__refreshIDIndex()
|
| | | index = self.__idIndexDict.pop(playerID, -1)
|
| | | if index >= 0 and index < len(self.__viewCacheList):
|
| | | self.__viewCacheList.pop(index)
|
| | | viewCache = self.__viewCacheDict.pop(playerID, None)
|
| | | if viewCache in self.__viewCacheList:
|
| | | self.__viewCacheList.remove(viewCache)
|
| | | for playerIDList in self.__serverIDRangePlayerIDDict.values():
|
| | | if playerID in playerIDList:
|
| | | playerIDList.remove(playerID)
|
| | | self.__idIndexDict = {}
|
| | | self.__serverIDRangePlayerIDDict = {}
|
| | | return
|
| | |
|
| | | def DelAllCache(self):
|
| | | self.__viewCacheList = []
|
| | | self.__idIndexDict = {}
|
| | | self.__viewCacheDict = {}
|
| | | self.__needSort = False
|
| | | self.__serverIDRangePlayerIDDict = {}
|
| | | return
|
| | |
| | | return
|
| | | self.__needSort = False
|
| | | self.__viewCacheList.sort(key=lambda v: (v.GetFightPowerTotal(), v.GetLV()), reverse=True)
|
| | | self.__idIndexDict = {}
|
| | | self.__serverIDRangePlayerIDDict = {}
|
| | | self.__refreshIDIndex()
|
| | | return
|
| | |
|
| | | # 保存数据 存数据库和realtimebackup
|
| | |
| | | for _ in xrange(cnt):
|
| | | dbData = DBStruct.tagDBPlayerViewCache()
|
| | | pos += dbData.readData(datas, pos, dataslen)
|
| | | self.InitViewCacheInstance(dbData)
|
| | | self.__InitViewCacheInstance(dbData)
|
| | |
|
| | | self.Sort()
|
| | | return pos
|
| | | |
| | | def OnPlayerLogout(curPlayer):
|
| | | if curPlayer.GetLV() >= 10:
|
| | | UpdPlayerViewCache(curPlayer)
|
| | | |
| | | return
|
| | |
|
| | | def UpdPlayerViewCache(curPlayer, isOffline=False):
|
| | | '''更新玩家查看缓存数据,更新时机由外层自己判断,这里只做更新逻辑
|
| | | 1. 下线时强制更新一次,上线暂不更新,上线时由各功能如果有需要用到触发更新
|
| | | 2. 有需要用到缓存数据时,如果玩家在线,1分钟内多次获取时最多更新一次,没有获取缓存数据则不更新
|
| | | '''
|
| | | if not curPlayer:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | curCache = DBDataMgr.GetPlayerViewCacheMgr().GetPlayerViewCache(playerID)
|
| | | if not curCache:
|
| | | return
|
| | | |
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | curPlayer.SetDict(Key_UpdViewCacheTick, tick)
|
| | | GameWorld.DebugLog("更新玩家查看缓存数据! isOffline=%s" % isOffline, playerID)
|
| | | curCache.SetAccID(curPlayer.GetAccID())
|
| | | curCache.SetPlayerName(curPlayer.GetPlayerName())
|
| | | curCache.SetLV(curPlayer.GetLV())
|
| | | curCache.SetJob(curPlayer.GetJob())
|
| | | curCache.SetRealmLV(curPlayer.GetOfficialRank())
|
| | | curCache.SetFace(curPlayer.GetFace())
|
| | | curCache.SetFacePic(curPlayer.GetFacePic())
|
| | | curCache.SetFamilyID(curPlayer.GetFamilyID())
|
| | | curCache.SetFamilyName(curPlayer.GetFamilyName())
|
| | | curCache.SetFamilyEmblemID(PlayerControl.GetFamilyEmblemID(curPlayer))
|
| | | curCache.SetTitleID(PlayerControl.GetTitleID(curPlayer))
|
| | | curCache.SetFightPowerTotal(PlayerControl.GetFightPower(curPlayer))
|
| | | curCache.SetServerID(GameWorld.GetPlayerServerID(curPlayer))
|
| | | if isOffline:
|
| | | curCache.SetOffTime(int(time.time()))
|
| | | |
| | | plusDict = curCache.GetPlusDict()
|
| | | |
| | | #战斗属性
|
| | | plusDict.update({
|
| | | "MinAtk":curPlayer.GetMinAtk(),
|
| | | "MaxAtk":curPlayer.GetMaxAtk(),
|
| | | "Def":curPlayer.GetDef(),
|
| | | "MaxHP":GameObj.GetMaxHP(curPlayer),
|
| | | "Hit":curPlayer.GetHit(),
|
| | | "Miss":curPlayer.GetMiss(),
|
| | | "SuperHitRate":curPlayer.GetSuperHitRate(), # 暴击率
|
| | | })
|
| | | |
| | | # 功能数据
|
| | | |
| | | # 其他
|
| | | |
| | | return curCache
|
| | |
|
| | | |
| | |
| | |
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import PlayerViewCache
|
| | | import IPY_PlayerDefine
|
| | | import PlayerFamily
|
| | | import DBDataMgr
|
| | |
| | | else:
|
| | | memFightPower = avgValue + memCnt / 2 - m
|
| | | memFightPowerTotal -= memFightPower
|
| | | viewCache = DBDataMgr.GetPlayerViewCacheMgr().FindViewCache(memID, True)
|
| | | viewCache = PlayerViewCache.FindViewCache(memID, True)
|
| | | viewCache.SetFightPowerTotal(memFightPower)
|
| | | GameWorld.DebugLog(" 仙盟成员: memID=%s,memFightPower=%s,fmLV=%s" % (memID, memFightPower, fmLV))
|
| | | member.RefreshMemberByID(memID)
|
| | |
| | |
|
| | | import GameWorld
|
| | | import MirrorAttack
|
| | | import PlayerViewCacheTube
|
| | | import ChConfig
|
| | |
|
| | | ## GM命令执行入口
|
| | |
| | | return
|
| | |
|
| | | elif value1 == 5:
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
|
| | | #tick = GameWorld.GetGameWorld().GetTick()
|
| | | #PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
|
| | | GameWorld.DebugAnswer(curPlayer, "已更新最新镜像缓存!")
|
| | | elif value1 in ["a", "d", "p"]:
|
| | | return True
|
| | |
| | | return mainServerID
|
| | | return 0
|
| | |
|
| | | def GetDBPlayerAccIDByID(playerID):
|
| | | ## 获取玩家表账号ID - 根据玩家ID, 可用于判断是否本服玩家
|
| | | return PyGameData.g_dbPlayerIDMap.get(playerID, "")
|
| | |
|
| | | #===============================================================================
|
| | | # ƽ̨ID = appid
|
| | |
| | | import PlayerControl
|
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | | import PlayerViewCacheTube
|
| | | import PlayerActGarbageSorting
|
| | | import FBCommon
|
| | | import IpyGameDataPY
|
| | |
| | | PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_HelpBattle)
|
| | |
|
| | | # 没有数据缓存的话,马上同步一次
|
| | | if not haveViewCache:
|
| | | PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, False)
|
| | | #if not haveViewCache:
|
| | | # PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, False)
|
| | |
|
| | | SyncCheckInState(curPlayer, 1, False)
|
| | |
|
| | |
| | | import ChItem
|
| | | import IpyGameDataPY
|
| | | import Operate_EquipStone
|
| | | import PlayerViewCacheTube
|
| | | import Operate_EquipWash
|
| | | import FormulaControl
|
| | | import ChPyNetSendPack
|
| | |
| | | #curPlayer.SendFakePack(innerPackData, len(innerPackData))
|
| | | curPlayer.SendFakePack(clientPack.GetBuffer(), clientPack.GetLength())
|
| | |
|
| | | def SendFackPackOnline(clientPack, parseFunc=None, *args):
|
| | | ## 发送给全服在线玩家
|
| | | # @param parseFunc: 中间处理逻辑,可以做一些修改包数据的逻辑或者过滤某些玩家不发送,返回值为True时发送
|
| | | # @param args: parseFunc方法参数(curPlayer, ...)
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.OnlineCount()):
|
| | | curPlayer = playerManager.OnlineAt(i)
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | if parseFunc and not parseFunc(curPlayer, *args):
|
| | | continue
|
| | | SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|
| | | #-------------------------------------------------------------------------------
|
| | | #---Py封包注册信息
|
| | |
| | | import PlayerArena
|
| | | import PyGameData
|
| | | import PlayerCoin
|
| | | import PlayerGeTui
|
| | | import PlayerCharm
|
| | | import PlayerDogz
|
| | | import PlayerCoat
|
| | |
| | | import IPY_ServerDefine
|
| | | import CommFunc
|
| | | from PyMongoDB import RecvPackToMapDB
|
| | | import PlayerTalk
|
| | |
|
| | | import datetime
|
| | | import time
|
| | |
| | | #初始化玩家的时钟个数
|
| | | if curPlayer.GetTickTypeCount() == 0:
|
| | | curPlayer.SetTickTypeCount(ChConfig.TYPE_Player_Tick_Count)
|
| | | |
| | | #初始化玩家聊天频道
|
| | | if curPlayer.GetMaxChannelCount() == 0:
|
| | | curPlayer.SetMaxChannelCount(ChConfig.Def_PlayerTalkChannelMaxCount)
|
| | |
|
| | | #===============================================================================
|
| | | # #初始化玩家鉴定管理器物品最大个数
|
| | |
| | | #大师
|
| | | PlayerGreatMaster.MasterOnLogin(curPlayer)
|
| | |
|
| | | # 推送提醒
|
| | | PlayerGeTui.LoginNotifySetting(curPlayer)
|
| | | |
| | | #֪ͨVIP
|
| | | PlayerVip.DoOnLogin(curPlayer, tick)
|
| | |
|
| | |
| | | PlayerMineArea.OnPlayerLogin(curPlayer)
|
| | | PlayerGuaji.OnPlayerLogin(curPlayer)
|
| | | PlayerActFamilyGCZ.OnPlayerLogin(curPlayer)
|
| | | PlayerTalk.OnPlayerLogin(curPlayer)
|
| | |
|
| | | # 上线查询一次充值订单
|
| | | curPlayer.SendDBQueryRecharge()
|
| | |
| | | import OperControlManager
|
| | | import PlayerFamily
|
| | | import ShareDefine
|
| | | import PlayerViewCache
|
| | | import PlayerBillboard
|
| | | import GameServerRefresh
|
| | | import IPY_GameWorld
|
| | |
| | | import PlayerWorldAverageLv
|
| | | import PlayerActivity
|
| | | import FBCommon
|
| | | import PlayerViewCacheTube
|
| | | import PassiveBuffEffMng
|
| | | import PlayerGameEvent
|
| | | import EventReport
|
| | |
| | | import PlayerActGarbageSorting
|
| | | import GY_Query_CrossRealmReg
|
| | | import PlayerTongTianLing
|
| | | import PlayerCrossRealmPK
|
| | | import FunctionNPCCommon
|
| | | import DBPlayerViewCache
|
| | | import PlayerGoldInvest
|
| | | import IPY_PlayerDefine
|
| | | import CrossRealmPlayer
|
| | |
| | | # @param mergeMapInfo 该提示所属的跨服活动地图信息, 主要用于不同子服对应所跨的活动地图ID
|
| | | # @return 无返回值
|
| | | def WorldNotify(country, msgMark, msgParamList=[], lineID=0, mergeMinOSD=-1, mergeMaxOSD=-1, mergeMapInfo=[]):
|
| | | GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(country, 0, msgMark, __GetNotifyCodeList(msgParamList), lineID)
|
| | | #GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(country, 0, msgMark, __GetNotifyCodeList(msgParamList), lineID)
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.OnlineCount()):
|
| | | curPlayer = playerManager.OnlineAt(i)
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | NotifyCode(curPlayer, msgMark, msgParamList)
|
| | | return
|
| | |
|
| | | def GetCrossWorldNotifyInfo(country, msgMark, msgParamList=[]):
|
| | |
| | | # @return 无返回值
|
| | | # @remarks
|
| | | def FamilyNotify(familyID, msgMark, msgParamList=[]):
|
| | | GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(0, familyID, msgMark, __GetNotifyCodeList(msgParamList))
|
| | | #GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(0, familyID, msgMark, __GetNotifyCodeList(msgParamList))
|
| | | PlayerFamily.NotifyAllFamilyMemberMsg(familyID, msgMark, msgParamList)
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故下线不再同步
|
| | |
|
| | | #玩家下线通知gameserver记录缓存(放在下线更新排行榜之后,方便Gameserver判断是否需要存入数据库中)
|
| | | PlayerViewCacheTube.OnPlayerLogOut(curPlayer, tick)
|
| | | DBPlayerViewCache.OnPlayerLogout(curPlayer)
|
| | | PlayerViewCache.OnPlayerLogout(curPlayer)
|
| | | PlayerFamily.OnPlayerLogout(curPlayer)
|
| | |
|
| | | #玩家下线/玩家切换地图公用逻辑
|
| | |
| | | import PlayerFuncTeam
|
| | | import PlayerMineArea
|
| | | import PlayerBillboard
|
| | | import PlayerViewCache
|
| | | import PlayerMail
|
| | |
|
| | | import datetime
|
| | |
| | | DoLogic_OnDayEx(tick)
|
| | |
|
| | | PlayerBillboard.OnDay()
|
| | | PlayerViewCache.OnDay()
|
| | | return
|
| | |
|
| | | def DoLogic_OnDayEx(tick):
|
| | |
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import NetPackCommon
|
| | | import PlayerViewCache
|
| | | import ChPyNetSendPack
|
| | | import PlayerFamilyTech
|
| | | import PlayerFamilyEmblem
|
| | |
| | | reqInfo.ReqTime = reqTime
|
| | | if curPlayer:
|
| | | reqInfo.IsOnLine = True
|
| | | viewCache = DBDataMgr.GetPlayerViewCacheMgr().FindViewCache(playerID)
|
| | | viewCache = PlayerViewCache.FindViewCache(playerID)
|
| | | if viewCache:
|
| | | reqInfo.Name = viewCache.GetPlayerName()
|
| | | reqInfo.NameLen = len(reqInfo.Name)
|
| | |
| | | import PlayerAutoCheckOnline
|
| | | import PlayerGameWallow
|
| | | import ReadChConfig
|
| | | import PlayerViewCacheTube
|
| | | import PlayerDienstgrad
|
| | | import PlayerVip
|
| | | import IpyGameDataPY
|
| | |
| | |
|
| | | #副本相关时间处理
|
| | | PlayerFB.DoPlayerFBTimeProcess(curPlayer, tick)
|
| | | |
| | | #玩家数据缓存定时同步
|
| | | PlayerViewCacheTube.ProcessCache(curPlayer, tick)
|
| | |
|
| | | #脱机计算
|
| | | #PlayerTJG.ProcessPlayerTJG(curPlayer, tick)
|
| | |
| | | import math
|
| | | import PassiveBuffEffMng
|
| | | import PlayerPet
|
| | | import PlayerGeTui
|
| | | import ChEquip
|
| | | import QuestCommon
|
| | | import random
|
| | |
| | | ChangeGuard(curPlayer, tick)
|
| | | times, finalAddExp = CalcPlayerTJG(curPlayer, tick)
|
| | |
|
| | | #PlayerGeTui.TJGEfficiency(curPlayer, times, finalAddExp)
|
| | | #PlayerGeTui.TJGTimeLess(curPlayer)
|
| | | return
|
| | |
|
| | | def GetTJGTime(curPlayer): return curPlayer.GetHappyPoint()
|
| | |
| | | def CheckPackFull(curPlayer):
|
| | | if not ItemCommon.CheckPackHasSpace(curPlayer, IPY_GameWorld.rptItem):
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_TJGPackFullAfterEat, 1)
|
| | | #PlayerGeTui.FullPack(curPlayer)
|
| | |
|
| | | # 可执行吞噬操作
|
| | | def CanEatItemsOper(curPlayer):
|
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package
|
| | | ##@package Player.PlayerTalk
|
| | | #
|
| | | # @todo: 玩家聊天逻辑 支持语音
|
| | | #
|
| | | # @author: Alee
|
| | | # @date 2018-4-24 下午07:36:28
|
| | | # @todo:聊天
|
| | | # @author hxp
|
| | | # @date 2025-05-23
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | # 详细描述: 聊天
|
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | import IPY_GameWorld
|
| | | import GameWorld
|
| | | import PlayerControl
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2025-05-23 20:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ChConfig
|
| | | import FBLogic
|
| | | #import ReadChConfig
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import IPY_GameWorld
|
| | | import ChPyNetSendPack
|
| | | import CrossRealmPlayer
|
| | | import PlayerViewCache
|
| | | import NetPackCommon
|
| | | import EventReport
|
| | | import PlayerSuccess
|
| | | import IpyGameDataPY
|
| | | import ItemCommon
|
| | | import ChItem
|
| | | import PlayerTJG
|
| | | import EventShell
|
| | | import PyGameData
|
| | | import PlayerLove
|
| | | import PlayerControl
|
| | | import PlayerFamily
|
| | | import DBDataMgr
|
| | |
|
| | | import math
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #需要记录聊天缓存的频道对应限制最大条数
|
| | | ChannelCacheMax = {IPY_GameWorld.tcFamily:30,
|
| | | IPY_GameWorld.tcWorld:100,
|
| | | }
|
| | | |
| | | def OnPlayerLogin(curPlayer):
|
| | | NotifyTalkCache(curPlayer)
|
| | | return
|
| | |
|
| | | ## 区域频道(封包参数) |
| | | # @param index 玩家索引
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | # 整个地图的人都可以听到
|
| | | def TalkArea(index, tick):
|
| | | #// B3 20 聊天 #tagCMTalk
|
| | | #
|
| | | #struct tagCMPyTalk
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE ChannelType; // 频道
|
| | | # WORD Len;
|
| | | # char Content[Len]; //size = Len
|
| | | #};
|
| | | def OnTalk(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | familyID = curPlayer.GetFamilyID()
|
| | | channelType = clientData.ChannelType
|
| | | content = clientData.Content
|
| | |
|
| | | #获得区域频封包
|
| | | sendPack = IPY_GameWorld.IPY_CTalkArea()
|
| | | #玩家聊天内容
|
| | | content = sendPack.GetContent()
|
| | | |
| | | #通用判断
|
| | | if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcArea):
|
| | | return
|
| | | |
| | | #通用设置
|
| | | SetTalkTime(curPlayer, content, IPY_GameWorld.tcArea, tick)
|
| | | |
| | | |
| | | #如果在普通地图, 就广播, 如果在副本就单个通知
|
| | | if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull and not GameWorld.IsCrossServer():
|
| | | #广播
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | curPlayer.ChatArea(content, 0, extras)
|
| | | else:
|
| | | __DoLogic_FB_TalkArea(curPlayer, content)
|
| | | |
| | | return True
|
| | |
|
| | | ## 副本中说话
|
| | | # @param curPlayer 当前玩家
|
| | | # @param content 讲话的内容
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def __DoLogic_FB_TalkArea(curPlayer, content):
|
| | | playerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | |
| | | for index in range(0 , playerManager.GetPlayerCount()):
|
| | | #广播玩家
|
| | | tempPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if not tempPlayer.GetPlayerID():
|
| | | continue
|
| | | #GameWorld.DebugLog("OnTalk channelType=%s, %s" % (channelType, GameWorld.CodeToGbk(content)))
|
| | | if channelType == IPY_GameWorld.tcFamily:
|
| | | if not familyID:
|
| | | PlayerControl.NotifyCode(curPlayer, "jiazu_lhs_0")
|
| | | return
|
| | |
|
| | | #单个广播说话
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | tempPlayer.Sync_ChatArea(curPlayer.GetPlayerID(), content, 0, extras)
|
| | | elif channelType == IPY_GameWorld.tcCountry:
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | if not CrossRealmPlayer.IsCrossServerOpen():
|
| | | PlayerControl.NotifyCode(curPlayer, "CrossMatching18")
|
| | | return
|
| | |
|
| | | if not __CheckTalk(curPlayer, channelType, content, tick):
|
| | | return
|
| | | |
| | | curPlayer.SetLastChatTick(tick)
|
| | | curPlayer.SetDict(ChConfig.Def_ChannelTalkTick % channelType, tick)
|
| | | |
| | | if channelType == IPY_GameWorld.tcCountry:
|
| | | #发送到跨服,待扩展
|
| | | return
|
| | | |
| | | bubbleBox = PlayerControl.GetChatBubbleBox(curPlayer) # 气泡框
|
| | | |
| | | clientPack = ChPyNetSendPack.tagMCTalk()
|
| | | clientPack.ChannelType = channelType
|
| | | clientPack.PlayerID = playerID
|
| | | clientPack.Name = curPlayer.GetPlayerName()
|
| | | clientPack.NameLen = len(clientPack.Name)
|
| | | clientPack.Content = content
|
| | | clientPack.Len = len(clientPack.Content)
|
| | | clientPack.BubbleBox = bubbleBox
|
| | | clientPack.LV = curPlayer.GetLV()
|
| | | clientPack.Job = curPlayer.GetJob()
|
| | | clientPack.RealmLV = curPlayer.GetOfficialRank()
|
| | | clientPack.Face = curPlayer.GetFace()
|
| | | clientPack.FacePic = curPlayer.GetFacePic()
|
| | | clientPack.ServerID = GameWorld.GetPlayerServerID(curPlayer)
|
| | | |
| | | if channelType == IPY_GameWorld.tcWorld:
|
| | | NetPackCommon.SendFackPackOnline(clientPack)
|
| | | elif channelType == IPY_GameWorld.tcFamily:
|
| | | PlayerFamily.Broadcast_FamilyPack(familyID, clientPack)
|
| | | |
| | | DoTalkCache(channelType, playerID, content, bubbleBox, familyID)
|
| | | return
|
| | |
|
| | | ## 世界频道(封包参数)
|
| | | # @param index 玩家索引
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def TalkWorld(index, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | |
| | | sendPack = IPY_GameWorld.IPY_CTalkGong()
|
| | | #玩家聊天内容
|
| | | content = sendPack.GetContent()
|
| | | |
| | | #通用检测
|
| | | if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, checkSameMsg = False, talkType=IPY_GameWorld.tcWorld):
|
| | | return
|
| | | |
| | | #通用设置
|
| | | SetTalkTime(curPlayer, content, IPY_GameWorld.tcWorld, tick)
|
| | | #发送聊天内容
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | curPlayer.ChatGong(content, 0, extras)
|
| | | #世界频道发言成就
|
| | | #PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_TalkWorld, 1)
|
| | | PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FeastRedPack_TalkWorld, 1)
|
| | | EventShell.EventRespons_Talk(curPlayer, 'talkworld')
|
| | | return
|
| | |
|
| | | ## 国家频道(封包参数)
|
| | | # @param index 玩家索引
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def TalkCountry(index, tick):
|
| | | ## 跨服世界频道
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | |
| | | if not CrossRealmPlayer.IsCrossServerOpen():
|
| | | PlayerControl.NotifyCode(curPlayer, "CrossMatching18")
|
| | | return
|
| | | |
| | | sendPack = IPY_GameWorld.IPY_CTalkCountry()
|
| | | #玩家聊天内容
|
| | | content = sendPack.GetContent()
|
| | | |
| | | #通用检测
|
| | | if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, checkSameMsg = False, talkType=IPY_GameWorld.tcCountry):
|
| | | return
|
| | | |
| | | #通用设置
|
| | | SetTalkTime(curPlayer, content, IPY_GameWorld.tcCountry, tick)
|
| | | #发送聊天内容
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | curPlayer.ChatCountry(content, 0, extras)
|
| | | return
|
| | |
|
| | | ## 联盟家族频道(封包参数)
|
| | | # @param index 玩家索引
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def TalkFamily(index, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | if curPlayer.GetFamilyID() == 0:
|
| | | PlayerControl.NotifyCode(curPlayer, "jiazu_lhs_0 ")
|
| | | return
|
| | | |
| | | sendPack = IPY_GameWorld.IPY_CTalkBang()
|
| | | #玩家聊天内容
|
| | | content = sendPack.GetContent()
|
| | | |
| | | if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcFamily):
|
| | | return
|
| | | |
| | | #通用设置
|
| | | SetTalkTime(curPlayer, content, IPY_GameWorld.tcFamily, tick)
|
| | | |
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | curPlayer.ChatFamily(content, 0, extras)
|
| | | #仙盟频道发言成就
|
| | | PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_TalkFamily, 1)
|
| | | EventShell.EventRespons_Talk(curPlayer, 'talkfamily')
|
| | | return
|
| | |
|
| | | ## 队伍频道(封包参数)
|
| | | # @param index 玩家索引
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def TalkTeam(index, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | if curPlayer.GetTeam() == None:
|
| | | PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_161795 ")
|
| | | return
|
| | | |
| | | sendPack = IPY_GameWorld.IPY_CTalkDui()
|
| | | #玩家聊天内容
|
| | | content = sendPack.GetContent()
|
| | | |
| | | if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcTeam):
|
| | | return
|
| | | |
| | | #通用设置
|
| | | SetTalkTime(curPlayer, content, IPY_GameWorld.tcTeam, tick)
|
| | | #说话
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | curPlayer.ChatTeam(content, 0, extras)
|
| | | return
|
| | |
|
| | |
|
| | | ## 私聊频道(封包参数)
|
| | | # @param index 玩家索引
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def TalkPrivate(index, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | sendPack = IPY_GameWorld.IPY_CTalkMiFix()
|
| | | |
| | | #玩家聊天内容
|
| | | content = sendPack.GetContent()
|
| | | |
| | | if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcPrivate):
|
| | | return
|
| | | |
| | | #通用设置
|
| | | SetTalkTime(curPlayer, content, IPY_GameWorld.tcPrivate, tick)
|
| | | #说话
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | curPlayer.ChatMiByID(sendPack.GetTalkType(), sendPack.GetPlayerID(), content, 0, extras)
|
| | | return
|
| | |
|
| | | def TalkPrivateByID(curPlayer, tagPlayerID, content):
|
| | | #私聊 0为默认 1为1对1聊天
|
| | | talkType = 1
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | curPlayer.ChatMiByID(talkType, tagPlayerID, content, 0, extras)
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | | ## 私聊频道(封包参数)
|
| | | # @param index 玩家索引
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def TalkPrivateName(index, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | sendPack = IPY_GameWorld.IPY_CTalkMi()
|
| | | #玩家聊天内容
|
| | | content = sendPack.GetContent()
|
| | | |
| | | if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcPrivate):
|
| | | return
|
| | | |
| | | #通用设置
|
| | | SetTalkTime(curPlayer, content, IPY_GameWorld.tcPrivate, tick)
|
| | | #说话
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | curPlayer.ChatMiByName(sendPack.GetTalkType(), sendPack.GetTargetName(), content, 0, extras)
|
| | | return
|
| | |
|
| | | |
| | | #-3秒重复,;聊天信息太长
|
| | | ## 聊天通用检查 |
| | | # @param curPlayer 当前玩家 |
| | | # @param content 聊天内容 |
| | | # @param length 聊天长度 |
| | | # @param tick 当前时间 |
| | | # @param checkGMForbidenTalk 检查是否禁言 |
| | | # @param checkSameMsg 是否检查相同信息
|
| | | # @return True or False
|
| | | # @remarks 函数详细说明.
|
| | | def __CheckTalk(curPlayer, content, length, tick, checkGMForbidenTalk = True, checkSameMsg = True, talkType=None):
|
| | | def __CheckTalk(curPlayer, channelType, content, tick, checkGMForbidenTalk=True):
|
| | | ## 聊天通用检查 |
| | | if checkGMForbidenTalk and GetGMToolForbidTalk(curPlayer):
|
| | | #GeRen_chenxin_921745 对不起,您已被GM禁言,发送信息失败
|
| | | #PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_921745")
|
| | |
| | | return False
|
| | |
|
| | | #频道各自间隔时间
|
| | | if talkType != None:
|
| | | if channelType != None:
|
| | | talkCDDict = IpyGameDataPY.GetFuncEvalCfg("TalkCD", 1, {})
|
| | | if str(talkType) in talkCDDict:
|
| | | cdTicks = talkCDDict[str(talkType)] * 1000
|
| | | lastTalkTick = curPlayer.GetTalkTick(talkType)
|
| | | if str(channelType) in talkCDDict:
|
| | | cdTicks = talkCDDict[str(channelType)] * 1000
|
| | | lastTalkTick = curPlayer.GetDictByKey(ChConfig.Def_ChannelTalkTick % channelType)
|
| | | remainTick = cdTicks - (tick - lastTalkTick)
|
| | | if remainTick > 0:
|
| | | PlayerControl.NotifyCode(curPlayer, "CanootTalk01", [int(math.ceil(remainTick/1000.0))])
|
| | | PlayerControl.NotifyCode(curPlayer, "CanootTalk01", [int(math.ceil(remainTick / 1000.0))])
|
| | | return False
|
| | |
|
| | | #聊天信息太长
|
| | | if length > ChConfig.Def_PlayerTalkMaxCount :
|
| | | if len(content) > ChConfig.Def_PlayerTalkMaxCount:
|
| | | PlayerControl.NotifyCode(curPlayer, "CanootTalk13")
|
| | | return False
|
| | |
|
| | |
| | |
|
| | | return True
|
| | |
|
| | |
|
| | | ## 获得玩家是否被禁言 |
| | | # @param curPlayer 当前玩家
|
| | | # @return 是否禁言
|
| | | def GetGMToolForbidTalk(curPlayer):
|
| | | |
| | | ## 获得玩家是否被禁言 |
| | | #accIDForbid = (curPlayer.GetAccState() & pow(2, ChConfig.Def_PysForbidTalk)) > 0
|
| | | |
| | | return curPlayer.GetGMForbidenTalk()# or accIDForbid
|
| | |
|
| | |
|
| | | ## 聊天时间通用设置 |
| | | # @param curPlayer 当前玩家
|
| | | # @param content 聊天内容
|
| | | # @param type 类型
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def SetTalkTime(curPlayer, content, type, tick):
|
| | | #设置当前时间为玩家开始聊天时间
|
| | | curPlayer.SetLastChatTick(tick)
|
| | | #设置当前聊天内容为玩家本次聊天内容
|
| | | #curPlayer.SetLastChatContent(content)
|
| | | #设置当前频道时间
|
| | | curPlayer.SetTalkTick(type, tick)
|
| | | return
|
| | |
|
| | | ## 信件2B封包
|
| | | # @param index 玩家索引
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def GBLetter(index, tick):
|
| | | #===========================================================================
|
| | | # curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | # sendPack = IPY_GameWorld.IPY_CGBLetter()
|
| | | # |
| | | # if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_GBLetter) <= ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_GBLetter]:
|
| | | # #发信1秒间隔
|
| | | # return
|
| | | # |
| | | # curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_GBLetter, tick)
|
| | | # |
| | | # #信件标题和内容
|
| | | # titleStr = sendPack.GetTitle()
|
| | | # contentStr = sendPack.GetContent()
|
| | | # |
| | | # #发给GM
|
| | | # curPlayer.Interface_SendGMLetter(titleStr, contentStr)
|
| | | #===========================================================================
|
| | | return
|
| | | |
| | | ## 记录玩家聊天内容
|
| | | # @param messageStr 聊天类型
|
| | | # @param curPlayer 聊天的玩家
|
| | | # @param tagPlayer None
|
| | | # @param content 聊天内容
|
| | | # @param addinfo 额外信息
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def __LogInDBPlayerTalk(messageStr , curPlayer , tagPlayer , content, addinfo=""):
|
| | | # 由客户端向后台发送
|
| | | return
|
| | | #===========================================================================
|
| | | # tagName = "" if not tagPlayer else tagPlayer.GetName()
|
| | | # #EventReport.WriteEvent_chat_log(curPlayer, content, messageStr, tagName, addinfo)
|
| | | # gameWorld = GameWorld.GetGameWorld()
|
| | | # #开关未开启
|
| | | # if not gameWorld.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_PurTalk):
|
| | | # return
|
| | | # |
| | | # #将聊天内容存入数据库
|
| | | # gameWorld.DataServer_TalkTrace('%s'%(messageStr), curPlayer, tagPlayer, content)
|
| | | # return
|
| | | #===========================================================================
|
| | |
|
| | |
|
| | | ## 获取聊天内容附加值
|
| | | # @param objTalk: 聊天对象
|
| | | # @return: 聊天内容附加值
|
| | | def GetTalkExtraValue(objTalk):
|
| | | vipLv = objTalk.GetVIPLv() # 玩家vip等级
|
| | | GMLevel = objTalk.GetGMLevel()
|
| | | job = objTalk.GetJob()
|
| | | playerID = objTalk.GetID()
|
| | | |
| | | extraValueStr = ""
|
| | | # vip等级
|
| | | extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_VipLv)%vipLv
|
| | | # GM
|
| | | extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_GM)% (GMLevel > 0)
|
| | | # job
|
| | | extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_JOB)% job
|
| | | # 气泡框
|
| | | extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_BubbleBox) % PlayerControl.GetChatBubbleBox(objTalk)
|
| | | # 服务器组ID
|
| | | extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_ServerGroupID) % PlayerControl.GetPlayerServerGroupID(objTalk)
|
| | | # 等级
|
| | | extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_LV) % objTalk.GetLV()
|
| | | # 伴侣信息
|
| | | coupleName = PlayerControl.GetCoupleName(objTalk)
|
| | | coupleJob = PlayerControl.GetCoupleJob(objTalk)
|
| | | bridePriceMaxID = PlayerControl.GetBridePriceMaxID(objTalk)
|
| | | face = objTalk.GetFace()
|
| | | facePic = objTalk.GetFacePic()
|
| | | extraValueStr = "%s|%s|%s|%s|%s|%s" % (extraValueStr, coupleName, coupleJob, bridePriceMaxID, face, facePic)
|
| | | return extraValueStr
|
| | |
|
| | |
|
| | | ## 附加信息的长度匹配
|
| | | # @param extraValueInfo: 附加信息的长度
|
| | | # @return: |
| | | def GetTalkExtraValueStar(extraValueType):
|
| | | extraValueInfo = ShareDefine.Def_TalkExtraValue_LenDict.get(extraValueType)
|
| | | extraValueLen = extraValueInfo[1] - extraValueInfo[0]
|
| | | |
| | | return "%0" + str(extraValueLen) + "d"
|
| | |
|
| | |
|
| | | #// A2 17 喇叭聊天 #tagCMPYSpeaker
|
| | | #
|
| | | #struct tagCMPYSpeaker
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE SpeakerType; //1-本服;2-跨服
|
| | | # BYTE IsUseGold; //是否使用钻石
|
| | | # BYTE ItemIndex; //使用物品说话时, 物品Index
|
| | | # BYTE TextLen; //字符长度
|
| | | # char Text[TextLen]; //size = TextLen
|
| | | #};
|
| | | def OnUsePYSpeaker(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | SpeakerType = clientData.SpeakerType
|
| | | IsUseGold = clientData.IsUseGold
|
| | | ItemIndex = clientData.ItemIndex
|
| | | TextLen = clientData.TextLen
|
| | | Text = clientData.Text
|
| | | |
| | | #GameWorld.Log("玩家喇叭聊天: SpeakerType=%s,IsUseGold=%s,ItemIndex=%s" |
| | | # % (SpeakerType, IsUseGold, ItemIndex), playerID)
|
| | | if not __CheckTalk(curPlayer, Text, TextLen, tick):
|
| | | def DoTalkCache(channelType, playerID, content, bubbleBox, familyID=0):
|
| | | # 聊天缓存
|
| | | if channelType not in ChannelCacheMax:
|
| | | return
|
| | | cacheMaxDict = IpyGameDataPY.GetFuncEvalCfg("TalkCache", 1, {})
|
| | | maxCount = min(ChannelCacheMax[channelType], cacheMaxDict.get(channelType, 0))
|
| | |
|
| | |
|
| | | if IsUseGold:
|
| | | bugleItemID = IpyGameDataPY.GetFuncCfg('BugleItem', SpeakerType)
|
| | | if not bugleItemID:
|
| | | GameWorld.ErrLog("功能配置表没有配置对应喇叭类型物品消耗!SpeakerType=%s,请检查BugleItem!" % SpeakerType)
|
| | | return
|
| | | costMoney = ItemCommon.GetAutoBuyItemNeedGold({bugleItemID:1})
|
| | | if not costMoney:
|
| | | return
|
| | | moneyType = IPY_GameWorld.TYPE_Price_Gold_Money
|
| | | infoDict = {"SpeakerType":SpeakerType, ChConfig.Def_Cost_Reason_SonKey:bugleItemID}
|
| | | if not PlayerControl.PayMoney(curPlayer, moneyType, costMoney, ChConfig.Def_Cost_UseSpeaker, infoDict, 1):
|
| | | return
|
| | | |
| | | # 检查使用喇叭道具
|
| | | elif not ChItem.DoSpeaker_UseItem(curPlayer, ItemIndex, SpeakerType):
|
| | | GameWorld.Log(" 喇叭道具不可用!", playerID)
|
| | | return
|
| | | |
| | | #通知世界服务器,使用小喇叭
|
| | | extraValue = 0
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | msgList = str([SpeakerType, Text, extraValue, extras])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, 'PYSpeaker', msgList, len(msgList))
|
| | |
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | | #// A2 16 自定义玩家聊天 #tagCMPyTalk
|
| | | #
|
| | | #struct tagCMPyTalk
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE TalkType; // 自定义聊天类型
|
| | | # WORD Len;
|
| | | # char Content[Len]; //size = Len
|
| | | #};
|
| | | ## 自定义玩家聊天
|
| | | # @param index
|
| | | # @param clientData
|
| | | # @param tick
|
| | | # @return
|
| | | def OnPyTalk(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | |
| | | #GameWorld.DebugLog("OnPyTalk, Name:%s" % curPlayer.GetPlayerName())
|
| | | |
| | | talkType = clientData.TalkType
|
| | | contentLen = clientData.Len
|
| | | content = clientData.Content
|
| | | |
| | | if talkType not in ShareDefine.TalkTypeList:
|
| | | GameWorld.ErrLog("OnPyTalk talkType(%s) is not define!" % talkType, curPlayer.GetPlayerID())
|
| | | return
|
| | | |
| | | #通用判断
|
| | | if not __CheckTalk(curPlayer, content, contentLen, tick):
|
| | | return
|
| | | |
| | | #说话
|
| | | extraValue = 0
|
| | | extras = GetTalkExtraValue(curPlayer)
|
| | | |
| | | isChatOK = False
|
| | | if talkType == ShareDefine.Def_TalkType_FBFaction:
|
| | | isChatOK = __ChatFBFaction(curPlayer, talkType, content, extraValue, extras)
|
| | | # 仙盟聊天存FamilyAction
|
| | | if channelType == IPY_GameWorld.tcFamily:
|
| | | familyActonMgr = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, ShareDefine.Def_ActionType_TalkCache)
|
| | | actionData = familyActonMgr.AddAction(maxCount)
|
| | | actionData.SetValue1(playerID)
|
| | | actionData.SetValue2(bubbleBox)
|
| | | actionData.GetUserDict().update({"content":content})
|
| | |
|
| | | if not isChatOK:
|
| | | return
|
| | | |
| | | #设置当前时间为玩家开始聊天时间
|
| | | curPlayer.SetLastChatTick(tick)
|
| | | #设置当前聊天内容为玩家本次聊天内容
|
| | | curPlayer.SetLastChatContent(content)
|
| | | |
| | | return True
|
| | | else:
|
| | | recTypeIDMgr = DBDataMgr.GetGameRecMgr().GetRecTypeIDMgr(ShareDefine.Def_GameRecType_TalkCache, channelType)
|
| | | recData = recTypeIDMgr.AddRecData(maxCount)
|
| | | recData.SetValue1(playerID)
|
| | | recData.SetValue2(bubbleBox)
|
| | | recData.GetUserDict().update({"content":content})
|
| | | |
| | | return
|
| | |
|
| | | ## py自定义聊天推送包
|
| | | def __GetPyTalkPack(curPlayer, talkType, content, extraValue, extras):
|
| | | pyTalk = ChPyNetSendPack.tagMCPyTalk()
|
| | | pyTalk.Clear()
|
| | | pyTalk.TalkType = talkType
|
| | | pyTalk.Name = curPlayer.GetPlayerName()
|
| | | pyTalk.NameLen = len(pyTalk.Name)
|
| | | pyTalk.PlayerID = curPlayer.GetPlayerID()
|
| | | pyTalk.Len = len(content)
|
| | | pyTalk.Content = content
|
| | | pyTalk.ExtraValue = extraValue
|
| | | pyTalk.Extras = extras
|
| | | return pyTalk
|
| | |
|
| | | ## 副本阵营聊天
|
| | | def __ChatFBFaction(curPlayer, talkType, content, extraValue, extras):
|
| | | curFaction = curPlayer.GetFaction()
|
| | | if not curFaction:
|
| | | return False
|
| | | def NotifyTalkCache(curPlayer):
|
| | | ##上线通知聊天缓存
|
| | |
|
| | | pyTalkPack = __GetPyTalkPack(curPlayer, talkType, content, extraValue, extras)
|
| | | |
| | | playerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | for index in range(playerManager.GetPlayerCount()):
|
| | | player = playerManager.GetPlayerByIndex(index)
|
| | | if not player:
|
| | | for channelType in ChannelCacheMax.keys():
|
| | | cacheList = []
|
| | | if channelType == IPY_GameWorld.tcFamily:
|
| | | familyID = curPlayer.GetFamilyID()
|
| | | if not familyID:
|
| | | continue
|
| | | familyActonMgr = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, ShareDefine.Def_ActionType_TalkCache)
|
| | | for index in range(familyActonMgr.Count()):
|
| | | actionData = familyActonMgr.At(index)
|
| | | talkTime = actionData.GetTime()
|
| | | playerID = actionData.GetValue1()
|
| | | bubbleBox = actionData.GetValue2()
|
| | | content = actionData.GetUserDict().get("content", "")
|
| | | if not content:
|
| | | content
|
| | | cacheList.append([talkTime, playerID, bubbleBox, content])
|
| | | else:
|
| | | recTypeIDMgr = DBDataMgr.GetGameRecMgr().GetRecTypeIDMgr(ShareDefine.Def_GameRecType_TalkCache, channelType)
|
| | | for index in range(recTypeIDMgr.GetCount()):
|
| | | recData = recTypeIDMgr.At(index)
|
| | | talkTime = recData.GetTime()
|
| | | playerID = recData.GetValue1()
|
| | | bubbleBox = recData.GetValue2()
|
| | | content = recData.GetUserDict().get("content", "")
|
| | | if not content:
|
| | | content
|
| | | cacheList.append([talkTime, playerID, bubbleBox, content])
|
| | | |
| | | if not cacheList:
|
| | | continue
|
| | |
|
| | | if player.GetFaction() != curFaction:
|
| | | packCacheList = []
|
| | | for talkTime, playerID, bubbleBox, content in cacheList:
|
| | | viewCache = PlayerViewCache.FindViewCache(playerID)
|
| | | if not viewCache:
|
| | | continue
|
| | | talkCache = ChPyNetSendPack.tagMCTalkCacheInfo()
|
| | | talkCache.PlayerID = playerID
|
| | | talkCache.Name = viewCache.GetPlayerName()
|
| | | talkCache.NameLen = len(talkCache.Name)
|
| | | talkCache.Content = content
|
| | | talkCache.Len = len(talkCache.Content)
|
| | | talkCache.BubbleBox = bubbleBox
|
| | | talkCache.LV = viewCache.GetLV()
|
| | | talkCache.Job = viewCache.GetJob()
|
| | | talkCache.RealmLV = viewCache.GetRealmLV()
|
| | | talkCache.Face = viewCache.GetFace()
|
| | | talkCache.FacePic = viewCache.GetFacePic()
|
| | | talkCache.ServerID = viewCache.GetServerID()
|
| | | talkCache.TalkTime = talkTime
|
| | | packCacheList.append(talkCache)
|
| | | |
| | | if not packCacheList:
|
| | | continue
|
| | |
|
| | | if PlayerTJG.GetIsTJG(player):
|
| | | continue
|
| | | clientPack = ChPyNetSendPack.tagMCTalkCacheList()
|
| | | clientPack.ChannelType = channelType
|
| | | clientPack.InfoList = packCacheList
|
| | | clientPack.Count = len(clientPack.InfoList)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | |
|
| | | NetPackCommon.SendFakePack(player, pyTalkPack)
|
| | | |
| | | return True
|
| | |
|
| | |
|
| | | #===============================================================================
|
| | | # //A2 26 语音聊天 #tagCMVoiceChat
|
| | | # |
| | | # struct tagCMVoiceChat
|
| | | # {
|
| | | # tagHead Head;
|
| | | # BYTE ChannelType; // 5 区域 --- 查看封包tagCGVoiceChat 1 世界 2 仙盟 3 私聊(好友) 4 队伍
|
| | | # BYTE TargetNameLen;
|
| | | # char TargetName[TargetNameLen]; //size = TargetNameLen
|
| | | # DWORD TargetID; // 默认发玩家ID,没有ID才发名称
|
| | | # WORD Len;
|
| | | # BYTE Content[Len]; //size = Len
|
| | | # };
|
| | | #===============================================================================
|
| | | def OnVoiceChat(index, clientPack, tick):
|
| | | # curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | # if GetGMToolForbidTalk(curPlayer):
|
| | | # return
|
| | | # if clientPack.ChannelType != ShareDefine.Def_ChannelChat_Area:
|
| | | # return
|
| | | # sendPack = ChPyNetSendPack.tagGCVoiceChat()
|
| | | # sendPack.Clear()
|
| | | # sendPack.ChannelType = clientPack.ChannelType
|
| | | # sendPack.SrcName = curPlayer.GetName()
|
| | | # sendPack.SrcNameLen = len(curPlayer.GetName())
|
| | | # sendPack.PlayerID = curPlayer.GetID()
|
| | | # sendPack.Len = clientPack.Len
|
| | | # sendPack.Content = clientPack.Content
|
| | | # sendPack.Extras = GetTalkExtraValue(curPlayer)
|
| | | # sendPack.ExtraValue = len(sendPack.Extras)
|
| | | # |
| | | # # 区域频道
|
| | | # |
| | | # #如果在普通地图, 就广播, 如果在副本就单个通知
|
| | | # if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull:
|
| | | # curPlayer.BroadCastAll(sendPack.GetBuffer(), len(sendPack.GetBuffer()))
|
| | | # else:
|
| | | # playerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | # |
| | | # for index in range(0 , playerManager.GetPlayerCount()):
|
| | | # #广播玩家
|
| | | # tempPlayer = playerManager.GetPlayerByIndex(index)
|
| | | # if not tempPlayer.GetPlayerID():
|
| | | # continue
|
| | | # |
| | | # if PlayerTJG.GetIsTJG(tempPlayer):
|
| | | # continue
|
| | | # |
| | | # NetPackCommon.SendFakePack(tempPlayer, sendPack)
|
| | | return
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.PlayerViewCache
|
| | | #
|
| | | # @todo:玩家缓存
|
| | | # @author hxp
|
| | | # @date 2025-5-22
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 玩家缓存
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2025-5-22 下午6:37:10"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ChConfig
|
| | | import GameWorld
|
| | | import PyMongoMain
|
| | | import PlayerControl
|
| | | import NetPackCommon
|
| | | import ChPyNetSendPack
|
| | | import IpyGameDataPY
|
| | | import ShareDefine
|
| | | import DBDataMgr
|
| | | import GameObj
|
| | |
|
| | | import random
|
| | | import time
|
| | |
|
| | | Key_UpdViewCacheTick = "UpdViewCacheTick"
|
| | |
|
| | | def OnDay():
|
| | | DelOutofTimeViewCacheData()
|
| | | return
|
| | |
|
| | | def OnPlayerLogout(curPlayer):
|
| | | if curPlayer.GetLV() < 10:
|
| | | return
|
| | | |
| | | curCache = UpdPlayerViewCache(curPlayer)
|
| | | if curCache and not IsSaveDBViewCache(curCache):
|
| | | DBDataMgr.GetPlayerViewCacheMgr().DelPlayerViewCache(curPlayer.GetPlayerID())
|
| | | |
| | | return
|
| | |
|
| | | def DelOutofTimeViewCacheData():
|
| | | ## 删除过期的查看缓存数据
|
| | | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | viewCacheMgr = DBDataMgr.GetPlayerViewCacheMgr()
|
| | | for index in range(viewCacheMgr.GetCount())[::-1]: # 有删除需倒序遍历
|
| | | viewCache = viewCacheMgr.At(index)
|
| | | playerID = viewCache.GetPlayerID()
|
| | | curPlayer = playerManager.FindPlayerByID(playerID)
|
| | | if curPlayer:
|
| | | continue
|
| | | if IsSaveDBViewCache(viewCache):
|
| | | continue
|
| | | viewCacheMgr.DelPlayerViewCache(playerID)
|
| | | |
| | | return
|
| | |
|
| | | def IsSaveDBViewCache(viewCache):
|
| | | ## 缓存数据是否入库
|
| | | if not viewCache:
|
| | | return False
|
| | | |
| | | playerID = viewCache.GetPlayerID()
|
| | | |
| | | #某个功能中不能删除的
|
| | | #...
|
| | | |
| | | |
| | | #排行版上的默认保留
|
| | | billboardMgr = DBDataMgr.GetBillboardMgr()
|
| | | for bType in ShareDefine.BillboardTypeAllList:
|
| | | if bType in ShareDefine.FamilyBillboardList:
|
| | | continue
|
| | | groupList = billboardMgr.GetBillboardGroupList(bType)
|
| | | for billboardType, groupValue1, groupValue2 in groupList:
|
| | | billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
|
| | | if billboardObj.FindByID(playerID):
|
| | | return True
|
| | | |
| | | # 以上是相关功能需要用到的数据,必定不能删除的
|
| | | |
| | | # 以下是保留近期活跃玩家,等级限制
|
| | | playerLV = viewCache.GetLV()
|
| | | if playerLV >= IpyGameDataPY.GetFuncCfg("PlayerViewCache", 1):
|
| | | maxDays = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 2)
|
| | | if not maxDays:
|
| | | maxDays = 7 # 默认7天
|
| | | MaxTime = maxDays * 3600 * 24
|
| | | curTime = int(time.time())
|
| | | passTime = curTime - viewCache.GetOffTime()
|
| | | if passTime < MaxTime:
|
| | | return True
|
| | | |
| | | return False
|
| | |
|
| | | def FindViewCache(playerID, isAdd=False):
|
| | | '''查找玩家缓存,如果不存在,则会有额外逻辑,如从redis、db直接找,
|
| | | 本服玩家理论上一定有查看缓存,因为如果不存在会直接从db读,除非该玩家数据被删除
|
| | | 跨服玩家理论上也一定有缓存,只是通过跨服或从子服查询,延迟获得
|
| | | 【注】外层调用依然要判断是否有数据
|
| | | '''
|
| | | |
| | | viewCacheMgr = DBDataMgr.GetPlayerViewCacheMgr()
|
| | | curCache = viewCacheMgr.GetPlayerViewCache(playerID)
|
| | | if curCache:
|
| | | updCache = __CheckUpdViewCache(playerID)
|
| | | if updCache:
|
| | | curCache = updCache
|
| | | |
| | | # 真实玩家
|
| | | elif playerID > ShareDefine.FackPlayerIDMax:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | # 本服在线玩家,直接生成新数据
|
| | | if curPlayer:
|
| | | curCache = viewCacheMgr.AddPlayerViewCache(playerID)
|
| | | UpdPlayerViewCache(curPlayer)
|
| | | |
| | | # 本服离线玩家
|
| | | elif GameWorld.GetDBPlayerAccIDByID(playerID):
|
| | | # 本服玩家,从redis或db读取重新加载读取,换句话说,本服玩家只要获取一定有查看缓存数据
|
| | | curCache = UpdPlayerViewCacheByDB(playerID)
|
| | | |
| | | # 跨服玩家
|
| | | else:
|
| | | pass
|
| | | # 跨服玩家,去子服拉取数据,理论上也一定有,但是如果需要拉数据,有一定延迟
|
| | | # 逻辑待扩展
|
| | | |
| | | # 假玩家,默认添加
|
| | | elif ShareDefine.FackPlayerIDStart <= playerID <= ShareDefine.FackPlayerIDMax:
|
| | | serverID = playerID % 100 + 1 # 1 ~ 100 服
|
| | | accID = "fake%s@test@s%s" % (playerID, serverID)
|
| | | fightPower = random.randint(1000000, 100000000) # 先随机,外层有需要的话再自己设置
|
| | | |
| | | curCache = viewCacheMgr.AddPlayerViewCache(playerID)
|
| | | curCache.SetPlayerName("%s%s" % (GameWorld.GbkToCode("神秘道友"), playerID))
|
| | | curCache.SetAccID(accID)
|
| | | curCache.SetLV(random.randint(100, 200))
|
| | | curCache.SetJob(random.randint(1, 2))
|
| | | curCache.SetRealmLV(random.randint(5, 15))
|
| | | curCache.SetFightPowerTotal(fightPower)
|
| | | curCache.SetServerID(serverID)
|
| | | curCache.SetOffTime(int(time.time()) - random.randint(1, 3600 * 24 * 10)) # 随机离线 0~10天
|
| | | |
| | | return curCache
|
| | |
|
| | | def __CheckUpdViewCache(playerID):
|
| | | if playerID <= ShareDefine.FackPlayerIDMax:
|
| | | return
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | lastUpdTick = curPlayer.GetDictByKey(Key_UpdViewCacheTick)
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | if lastUpdTick and tick - lastUpdTick < 60000:
|
| | | GameWorld.DebugLog("1分钟内只更新一次玩家缓存", playerID)
|
| | | return
|
| | | curPlayer.SetDict(Key_UpdViewCacheTick, tick)
|
| | | return UpdPlayerViewCache(curPlayer)
|
| | |
|
| | | def UpdPlayerViewCache(curPlayer, isOffline=False):
|
| | | '''更新玩家查看缓存数据,更新时机由外层自己判断,这里只做更新逻辑
|
| | | 1. 下线时强制更新一次,上线暂不更新,上线时由各功能如果有需要用到触发更新
|
| | | 2. 有需要用到缓存数据时,如果玩家在线,1分钟内多次获取时最多更新一次,没有获取缓存数据则不更新
|
| | | '''
|
| | | if not curPlayer:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | curCache = DBDataMgr.GetPlayerViewCacheMgr().GetPlayerViewCache(playerID)
|
| | | if not curCache:
|
| | | return
|
| | | |
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | curPlayer.SetDict(Key_UpdViewCacheTick, tick)
|
| | | GameWorld.DebugLog("更新玩家查看缓存数据! isOffline=%s" % isOffline, playerID)
|
| | | curCache.SetAccID(curPlayer.GetAccID())
|
| | | curCache.SetPlayerName(curPlayer.GetPlayerName())
|
| | | curCache.SetLV(curPlayer.GetLV())
|
| | | curCache.SetJob(curPlayer.GetJob())
|
| | | curCache.SetRealmLV(curPlayer.GetOfficialRank())
|
| | | curCache.SetFace(curPlayer.GetFace())
|
| | | curCache.SetFacePic(curPlayer.GetFacePic())
|
| | | curCache.SetFamilyID(curPlayer.GetFamilyID())
|
| | | curCache.SetFamilyName(curPlayer.GetFamilyName())
|
| | | curCache.SetFamilyEmblemID(PlayerControl.GetFamilyEmblemID(curPlayer))
|
| | | curCache.SetTitleID(PlayerControl.GetTitleID(curPlayer))
|
| | | curCache.SetFightPowerTotal(PlayerControl.GetFightPower(curPlayer))
|
| | | curCache.SetServerID(GameWorld.GetPlayerServerID(curPlayer))
|
| | | if isOffline:
|
| | | curCache.SetOffTime(int(time.time()))
|
| | | |
| | | plusDict = curCache.GetPlusDict()
|
| | | |
| | | #战斗属性
|
| | | plusDict.update({
|
| | | "MinAtk":curPlayer.GetMinAtk(),
|
| | | "MaxAtk":curPlayer.GetMaxAtk(),
|
| | | "Def":curPlayer.GetDef(),
|
| | | "MaxHP":GameObj.GetMaxHP(curPlayer),
|
| | | "Hit":curPlayer.GetHit(),
|
| | | "Miss":curPlayer.GetMiss(),
|
| | | "SuperHitRate":curPlayer.GetSuperHitRate(), # 暴击率
|
| | | })
|
| | | |
| | | # 功能数据
|
| | | |
| | | # 其他
|
| | | |
| | | return curCache
|
| | |
|
| | | def UpdPlayerViewCacheByDB(playerID):
|
| | | '''更新玩家查看缓存数据,直接从db数据更新,仅更新dbPlayer表有的属性,
|
| | | '''
|
| | | GameWorld.DebugLog("UpdPlayerViewCacheByDB", playerID)
|
| | | curCache = None
|
| | | dbPlayer = PyMongoMain.GetUserCtrlDB().findDBPlayer(playerID)
|
| | | if not dbPlayer:
|
| | | GameWorld.DebugLog("1111111111111111", playerID)
|
| | | return curCache
|
| | | viewCacheMgr = DBDataMgr.GetPlayerViewCacheMgr()
|
| | | curCache = viewCacheMgr.GetPlayerViewCache(playerID)
|
| | | if not curCache:
|
| | | curCache = viewCacheMgr.AddPlayerViewCache(playerID)
|
| | | familyID = dbPlayer.FamilyID
|
| | | GameWorld.DebugLog("db查找直接更新玩家查看缓存数据!", playerID)
|
| | | curCache.SetAccID(dbPlayer.AccID)
|
| | | curCache.SetPlayerName(dbPlayer.PlayerName)
|
| | | curCache.SetLV(dbPlayer.LV)
|
| | | curCache.SetJob(dbPlayer.Job)
|
| | | curCache.SetRealmLV(dbPlayer.OfficialRank)
|
| | | curCache.SetFace(dbPlayer.Face)
|
| | | curCache.SetFacePic(dbPlayer.FacePic)
|
| | | curCache.SetFamilyID(familyID)
|
| | | family = DBDataMgr.GetFamilyMgr().FindFamily(familyID)
|
| | | curCache.SetFamilyName(family.GetName() if family else "")
|
| | | curCache.SetFamilyEmblemID(family.GetEmblemID() if family else 0)
|
| | | #curCache.SetTitleID(PlayerControl.GetTitleID(curPlayer))
|
| | | curCache.SetFightPowerTotal(dbPlayer.FightPowerEx * ChConfig.Def_PerPointValue + dbPlayer.FightPower)
|
| | | curCache.SetServerID(GameWorld.GetAccIDServerID(dbPlayer.AccID))
|
| | | curCache.SetOffTime(GameWorld.ChangeTimeStrToNum(dbPlayer.LogoffTime) if dbPlayer.LogoffTime else 0)
|
| | | return curCache
|
| | |
|
| | | #//A2 12 查看玩家详细信息#tagCMViewPlayerInfo
|
| | | #struct tagCMViewPlayerInfo
|
| | | #{
|
| | | # tagHead Head;
|
| | | # DWORD PlayerID;
|
| | | # BYTE EquipClassLV; //大于0为查看指定境界阶装备信息, 0为查看默认信息
|
| | | #};
|
| | | def OnCMViewPlayerInfo(index, clientPack, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | |
| | | findPlayerID = clientPack.PlayerID
|
| | | #equipClassLV = clientPack.EquipClassLV
|
| | | |
| | | clientPack = GetPack_ViewCache(findPlayerID)
|
| | | if clientPack:
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | | if GameWorld.GetDBPlayerAccIDByID(findPlayerID):
|
| | | PlayerControl.NotifyCode(curPlayer, "ViewPlayer_OffLine")
|
| | | return
|
| | | |
| | | # 跨服玩家发送跨服查询,待扩展...
|
| | | |
| | | return
|
| | |
|
| | | def GetPack_ViewCache(playerID):
|
| | | ## 获取同步封包 - 玩家查看缓存
|
| | | curCache = FindViewCache(playerID)
|
| | | if not curCache:
|
| | | return
|
| | | clientPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult()
|
| | | clientPack.PlayerID = curCache.GetPlayerID()
|
| | | clientPack.PlayerName = curCache.GetPlayerName()
|
| | | clientPack.LV = curCache.GetLV()
|
| | | clientPack.Job = curCache.GetJob()
|
| | | clientPack.RealmLV = curCache.GetRealmLV()
|
| | | clientPack.Face = curCache.GetFace()
|
| | | clientPack.FacePic = curCache.GetFacePic()
|
| | | clientPack.TitleID = curCache.GetTitleID()
|
| | | clientPack.ServerID = curCache.GetServerID()
|
| | | clientPack.FightPower = curCache.GetFightPower()
|
| | | clientPack.FightPowerEx = curCache.GetFightPowerEx()
|
| | | clientPack.FamilyID = curCache.GetFamilyID()
|
| | | clientPack.FamilyName = curCache.GetFamilyName()
|
| | | clientPack.FamilyEmblemID = curCache.GetFamilyEmblemID()
|
| | | clientPack.PlusData = curCache.GetPlusData()
|
| | | clientPack.PlusDataSize = len(clientPack.PlusData)
|
| | | return clientPack
|
| | |
| | |
|
| | | import GameWorld
|
| | | import MirrorAttack
|
| | | import PlayerViewCacheTube
|
| | | import PyGameData
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | |
| | | return
|
| | | msgType = funResult[0]
|
| | | msgData = funResult[1]
|
| | | |
| | | if msgType == "PackDataSyncState":
|
| | | PlayerViewCacheTube.UpdPackDataSyncState(curPlayer, msgData)
|
| | | if msgData.get("PackDataCross"): # 如果跨服需要的,立即同步一次
|
| | | PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick)
|
| | | elif msgType == "PullPlayerPackData":
|
| | | msgInfo = msgData
|
| | | __DoPullPlayerPackData(curPlayer, msgInfo, tick)
|
| | | |
| | | elif msgType == "PullPlayerViewCache":
|
| | | msgInfo = msgData
|
| | | __DoPullPlayerViewCache(curPlayer, msgInfo, tick)
|
| | | |
| | | # |
| | | # if msgType == "PackDataSyncState":
|
| | | # PlayerViewCacheTube.UpdPackDataSyncState(curPlayer, msgData)
|
| | | # if msgData.get("PackDataCross"): # 如果跨服需要的,立即同步一次
|
| | | # PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick)
|
| | | # elif msgType == "PullPlayerPackData":
|
| | | # msgInfo = msgData
|
| | | # __DoPullPlayerPackData(curPlayer, msgInfo, tick)
|
| | | # |
| | | # elif msgType == "PullPlayerViewCache":
|
| | | # msgInfo = msgData
|
| | | # __DoPullPlayerViewCache(curPlayer, msgInfo, tick)
|
| | | # |
| | | return
|
| | |
|
| | | def __DoPullPlayerPackData(curPlayer, msgInfo, tick):
|
| | | pullFrom = msgInfo.get("pullFrom")
|
| | | # 0 或 非本服代表跨服需要
|
| | | if pullFrom == 0 or (pullFrom > 0 and pullFrom != GameWorld.GetServerGroupID()):
|
| | | PlayerViewCacheTube.SetPackDataCrossSyncState(curPlayer)
|
| | | else:
|
| | | PlayerViewCacheTube.SetPackDataSyncState(curPlayer)
|
| | | PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True, packMsg=msgInfo)
|
| | | # if pullFrom == 0 or (pullFrom > 0 and pullFrom != GameWorld.GetServerGroupID()):
|
| | | # PlayerViewCacheTube.SetPackDataCrossSyncState(curPlayer)
|
| | | # else:
|
| | | # PlayerViewCacheTube.SetPackDataSyncState(curPlayer)
|
| | | # PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True, packMsg=msgInfo)
|
| | | return
|
| | |
|
| | | def __DoPullPlayerViewCache(curPlayer, msgInfo, tick):
|
| | | viewFrom = msgInfo.get("viewFrom")
|
| | | # 0 或 非本服代表跨服需要
|
| | | if viewFrom == 0 or (viewFrom > 0 and viewFrom != GameWorld.GetServerGroupID()):
|
| | | PlayerViewCacheTube.SetViewCacheCrossSyncState(curPlayer)
|
| | | PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, packMsg=msgInfo, isOnlyViewCache=True)
|
| | | # if viewFrom == 0 or (viewFrom > 0 and viewFrom != GameWorld.GetServerGroupID()):
|
| | | # PlayerViewCacheTube.SetViewCacheCrossSyncState(curPlayer)
|
| | | # PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, packMsg=msgInfo, isOnlyViewCache=True)
|
| | | return
|
| | |
|
| | |
| | |
|
| | | g_pyGameDataManager = None
|
| | |
|
| | | g_dbPlayerIDMap = {} # 本服DBPlayer玩家表ID映射关系 {playerID:accID, ...}
|
| | |
|
| | | g_mapIDTxtInfo = {} # MapID.txt 加载的信息
|
| | | g_realmDiffPlayerDict = {} # 境界难度玩家信息 {realm:[playerID, ...], ...}
|
| | | g_realmDiffNPCRefresh = {} # {(lineID, realm):{refreshID:tagNPCRefresh, ...}}
|
| | |
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | #卡牌服务器表
|
| | | UCN_DBGameRec="tagDBGameRec"
|
| | | UCN_DBFamilyAction="tagDBFamilyAction"
|
| | | UCN_DBFamilyMem="tagDBFamilyMem"
|
| | | UCN_DBFamily="tagDBFamily"
|
| | |
| | |
|
| | | #MMO旧表
|
| | | UCN_DBPlayerPackData="tagDBPlayerPackData"
|
| | | UCN_DBGameRec="tagDBGameRec"
|
| | | UCN_DBPyFuncTeam="tagDBPyFuncTeam"
|
| | | UCN_DBPyFuncTeamMem="tagDBPyFuncTeamMem"
|
| | | UCN_DBPlayerRecData="tagDBPlayerRecData"
|
| | |
| | | self.Name = Str[:33]
|
| | |
|
| | |
|
| | |
|
| | | # 通用记录表新 #tagDBGameRec
|
| | | class tagDBGameRec(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ('RecType', ctypes.c_ushort),
|
| | | ('RecID', ctypes.c_ulong),
|
| | | ('Time', ctypes.c_double),
|
| | | ('Value1', ctypes.c_ulong),
|
| | | ('Value2', ctypes.c_ulong),
|
| | | ('Value3', ctypes.c_ulong),
|
| | | ('Value4', ctypes.c_ulong),
|
| | | ('Value5', ctypes.c_ulong),
|
| | | ('Value6', ctypes.c_ulong),
|
| | | ('Value7', ctypes.c_ulong),
|
| | | ('Value8', ctypes.c_ulong),
|
| | | ('UserDataLen', ctypes.c_ushort),
|
| | | ('UserData', ctypes.c_char_p),
|
| | | ('ADOResult', ctypes.c_ulong),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | Structure.__init__(self)
|
| | | self.clear()
|
| | |
|
| | | def clear(self):
|
| | | self.RecType = 0
|
| | | self.RecID = 0
|
| | | self.Time = 0.0
|
| | | self.Value1 = 0
|
| | | self.Value2 = 0
|
| | | self.Value3 = 0
|
| | | self.Value4 = 0
|
| | | self.Value5 = 0
|
| | | self.Value6 = 0
|
| | | self.Value7 = 0
|
| | | self.Value8 = 0
|
| | | self.UserDataLen = 0
|
| | | self.UserData = ''
|
| | |
|
| | | def readData(self, buf, pos = 0, length = 0):
|
| | | if not pos <= length:
|
| | | msg = error.formatMsg('error', error.ERROR_NO_148, '(pos = %s) > (length = %s)'%(pos, length))
|
| | | mylog.error(msg)
|
| | | return -1
|
| | | if len(buf) < pos + self.getLength():
|
| | | msg = error.formatMsg('error', error.ERROR_NO_149, 'len = %s while %s expected!'%(len(buf) - pos, self.getLength()))
|
| | | mylog.error(msg)
|
| | | self.clear()
|
| | | self.RecType, pos = CommFunc.ReadWORD(buf, pos)
|
| | | self.RecID, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Time, pos = CommFunc.ReadDouble(buf, pos)
|
| | | self.Value1, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value2, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value3, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value4, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value5, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value6, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value7, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value8, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.UserDataLen, pos = CommFunc.ReadWORD(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.UserDataLen)
|
| | | self.UserData = ctypes.c_char_p(tmp)
|
| | | return self.getLength()
|
| | |
|
| | | def getBuffer(self):
|
| | | buf = ''
|
| | | buf = CommFunc.WriteWORD(buf, self.RecType)
|
| | | buf = CommFunc.WriteDWORD(buf, self.RecID)
|
| | | buf = CommFunc.WriteDouble(buf, self.Time)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value1)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value2)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value3)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value4)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value5)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value6)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value7)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Value8)
|
| | | buf = CommFunc.WriteWORD(buf, self.UserDataLen)
|
| | | buf = CommFunc.WriteString(buf, self.UserDataLen, self.UserData)
|
| | | return buf
|
| | |
|
| | | def getLength(self):
|
| | | length = 0
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_double)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += self.UserDataLen
|
| | | return length
|
| | |
|
| | | def getRecord(self):
|
| | | '''组织存储记录'''
|
| | | rec = {}
|
| | | rec[u'RecType'] = self.RecType
|
| | | rec[u'RecID'] = self.RecID
|
| | | rec[u'Time'] = self.Time
|
| | | rec[u'Value1'] = self.Value1
|
| | | rec[u'Value2'] = self.Value2
|
| | | rec[u'Value3'] = self.Value3
|
| | | rec[u'Value4'] = self.Value4
|
| | | rec[u'Value5'] = self.Value5
|
| | | rec[u'Value6'] = self.Value6
|
| | | rec[u'Value7'] = self.Value7
|
| | | rec[u'Value8'] = self.Value8
|
| | | rec[u'UserDataLen'] = self.UserDataLen
|
| | | rec[u'UserData'] = fix_incomingText(self.UserData)
|
| | | return rec
|
| | |
|
| | | def readRecord(self, rec):
|
| | | '''由于MongoDB读出来是unicode,所有字符串需要进行转换'''
|
| | | self.RecType = rec.get(u'RecType', 0)
|
| | | self.RecID = rec.get(u'RecID', 0)
|
| | | self.Time = rec.get(u'Time', 0)
|
| | | self.Value1 = rec.get(u'Value1', 0)
|
| | | self.Value2 = rec.get(u'Value2', 0)
|
| | | self.Value3 = rec.get(u'Value3', 0)
|
| | | self.Value4 = rec.get(u'Value4', 0)
|
| | | self.Value5 = rec.get(u'Value5', 0)
|
| | | self.Value6 = rec.get(u'Value6', 0)
|
| | | self.Value7 = rec.get(u'Value7', 0)
|
| | | self.Value8 = rec.get(u'Value8', 0)
|
| | | self.UserDataLen = rec.get(u'UserDataLen', 0)
|
| | | self.UserData = fix_outgoingText(rec.get(u'UserData', u''))
|
| | |
|
| | | #Can not implement adoLoadStr method:No key defined!
|
| | | #Can not implement adoInsertStr method:No key defined!
|
| | | #Can not implement adoUpdateStr method:No key defined!
|
| | | #Can not implement adoUpdateStr method:No key defined!
|
| | | #Can not implement adoCheckUpdateStr method:No key defined!
|
| | | #Can not implement adoCheckUpdateExStr method:No key defined!
|
| | |
|
| | | def getAdoRecords(self, resultCollection):
|
| | | '''查询结果打包成二进制流'''
|
| | | result = ''
|
| | | result = CommFunc.WriteDWORD(result, resultCollection.count())
|
| | | for rec in resultCollection:
|
| | | self.readRecord(rec)
|
| | | result += self.getBuffer()
|
| | | return result
|
| | |
|
| | | #Can not implement adoQueryIndexStr method:No key defined!
|
| | |
|
| | | def adoQueryCustom(self, collection, queryDict):
|
| | | '''自定义查询'''
|
| | | resultCollection = collection.find(queryDict)
|
| | |
|
| | | return self.getAdoRecords(resultCollection)
|
| | |
|
| | |
|
| | | def adoQueryAll(self, collection):
|
| | | '''查询所有''' |
| | | resultCollection = collection.find()
|
| | | |
| | | return self.getAdoRecords(resultCollection)
|
| | |
|
| | | #Can not implement adoDeleteByIndexStr method:No key defined!
|
| | | def outputString(self):
|
| | | output = '''// 通用记录表新 #tagDBGameRec:
|
| | | RecType = %s,
|
| | | RecID = %s,
|
| | | Time = %s,
|
| | | Value1 = %s,
|
| | | Value2 = %s,
|
| | | Value3 = %s,
|
| | | Value4 = %s,
|
| | | Value5 = %s,
|
| | | Value6 = %s,
|
| | | Value7 = %s,
|
| | | Value8 = %s,
|
| | | UserDataLen = %s,
|
| | | UserData = %s,
|
| | | ADOResult = %s,
|
| | | '''%(
|
| | | self.RecType,
|
| | | self.RecID,
|
| | | self.Time,
|
| | | self.Value1,
|
| | | self.Value2,
|
| | | self.Value3,
|
| | | self.Value4,
|
| | | self.Value5,
|
| | | self.Value6,
|
| | | self.Value7,
|
| | | self.Value8,
|
| | | self.UserDataLen,
|
| | | self.UserData,
|
| | | self.ADOResult,
|
| | | )
|
| | | return output
|
| | |
|
| | | def dumpString(self):
|
| | | output = '''%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s'''%(
|
| | | self.RecType,
|
| | | self.RecID,
|
| | | self.Time,
|
| | | self.Value1,
|
| | | self.Value2,
|
| | | self.Value3,
|
| | | self.Value4,
|
| | | self.Value5,
|
| | | self.Value6,
|
| | | self.Value7,
|
| | | self.Value8,
|
| | | self.UserDataLen,
|
| | | self.UserData,
|
| | | )
|
| | | return output
|
| | |
|
| | |
|
| | |
| | | PyGameData.g_UserCtrlDBFirstInit = True
|
| | | self.__PlayerBackupSave()
|
| | | CheckGameVersion()
|
| | |
|
| | | #后续也要增加公共数据保存如家族等,考虑保存失败可以直接关闭地图
|
| | |
|
| | | self.loadDBPlayerIDMap()
|
| | | |
| | | return
|
| | | |
| | | def loadDBPlayerIDMap(self):
|
| | | ## 加载本服玩家映射关系
|
| | | col = self.db[UCN_DBPlayer]
|
| | | resultSet = col.find({}, {"PlayerID":1, "AccID":1, "_id":0})
|
| | | if resultSet and resultSet.count():
|
| | | for resultDict in resultSet:
|
| | | PyGameData.g_dbPlayerIDMap[resultDict["PlayerID"]] = resultDict["AccID"]
|
| | | GameWorld.Log("启动服务器加载DBPlayer玩家账号ID对应关系! %s, %s" % (len(PyGameData.g_dbPlayerIDMap), PyGameData.g_dbPlayerIDMap))
|
| | | return
|
| | | |
| | | def findDBPlayer(self, playerID):
|
| | | col = self.db[UCN_DBPlayer]
|
| | | dbPlayer = DataServerPlayerData.tagDBPlayer()
|
| | | dbPlayer.IsDeleted = 0
|
| | | if not dbPlayer.adoLoadCEx(col, {"PlayerID":playerID}):
|
| | | return
|
| | | return dbPlayer
|
| | |
|
| | | def requestLogicProcess(self, pack):
|
| | | db = self.db
|
| | |
| | |
|
| | | mylog.debug('RevoverBillProcess success...%s'%orderID)
|
| | | except:
|
| | | mylog.error("RevoverBillProcess error %s"%orderID)
|
| | | mylog.error("RevoverBillProcess error %s"%traceback.format_exc())
|
| | |
|
| | | def SavePlayerMapServerData(self, db, saveData):
|
| | | playerRec = DataServerPlayerData.tagDBPlayer()
|
| | |
| | | return 0, disDataBaseError, createPlayer.AccID, ''
|
| | |
|
| | | mylog.debug('insert role ok!accid = %s, PlayerName = %s'%(createPlayer.AccID, createPlayer.PlayerName))
|
| | | PyGameData.g_dbPlayerIDMap[newPlayerID] = createPlayer.AccID
|
| | | mylog.debug('PyGameData.g_dbPlayerIDMap = %s, %s'%(len(PyGameData.g_dbPlayerIDMap), PyGameData.g_dbPlayerIDMap))
|
| | | |
| | | #构造其他角色初始数据
|
| | | itemData = ''
|
| | | itemData = CommFunc.WriteDWORD(itemData, 0)
|
| | |
| | | data += DBFamilyAction.adoQueryAll(collection)
|
| | | mylog.info("tagDBFamilyAction ok")
|
| | |
|
| | | collection = db[UCN_DBGameRec]
|
| | | DBGameRec = DataServerPlayerData.tagDBGameRec()
|
| | | data += DBGameRec.adoQueryAll(collection)
|
| | | mylog.info("tagDBGameRec ok")
|
| | | |
| | | mylog.info('readGameWorldData len:%s' % len(data))
|
| | | return data
|
| | |
|
| | |
| | | gameDataReadPos = self.savegameServerWorldData(saveData, gameDataReadPos, UCN_DBFamily, DataServerPlayerData.tagDBFamily, db)
|
| | | gameDataReadPos = self.savegameServerWorldData(saveData, gameDataReadPos, UCN_DBFamilyMem, DataServerPlayerData.tagDBFamilyMem, db)
|
| | | gameDataReadPos = self.savegameServerWorldData(saveData, gameDataReadPos, UCN_DBFamilyAction, DataServerPlayerData.tagDBFamilyAction, db)
|
| | | gameDataReadPos = self.savegameServerWorldData(saveData, gameDataReadPos, UCN_DBGameRec, DataServerPlayerData.tagDBGameRec, db)
|
| | |
|
| | | mylog.info('saveGameWorldData ok!')
|
| | |
|
| | |
| | |
|
| | | BillboardTypeAllList = BillboardTypeList + CrossBillboardTypeList
|
| | |
|
| | | #仙盟榜单类型
|
| | | FamilyBillboardList = [Def_BT_BossTrialSubmitFamily, Def_BT_BossTrialSubmitFamilyBak, Def_CBT_FamilyGCZScore, Def_CBT_FamilyGCZRoundHurt]
|
| | |
|
| | | #职业对应战力排行榜类型
|
| | | JobFightPowerBillboardDict = {
|
| | | PlayerJob_Warrior:Def_BT_FightPower_Warrior,
|
| | |
| | | Def_BT_LV, Def_BT_FightPower_Horse, Def_BT_FightPower_Pet, Def_BT_TrialTower, Def_BT_OffLineEfficient,
|
| | | Def_BT_SkyTower, Def_BT_CharmTotal, Def_BT_CharmWeek, Def_BT_CharmDay
|
| | | ]
|
| | |
|
| | | #仙盟榜单类型
|
| | | FamilyBillboardList = [Def_BT_BossTrialSubmitFamily, Def_BT_BossTrialSubmitFamilyBak]
|
| | |
|
| | | ##---比率---
|
| | | #百分率
|
| | |
| | | 5006:6,
|
| | | }
|
| | |
|
| | | #聊天信息附加值
|
| | | (
|
| | | Def_TalkExtraValue_Bit_VipLv, # vip等级
|
| | | Def_TalkExtraValue_Bit_GM, #GM
|
| | | Def_TalkExtraValue_Bit_JOB, #job
|
| | | Def_TalkExtraValue_Bit_BubbleBox, #气泡框
|
| | | Def_TalkExtraValue_Bit_ServerGroupID, #服务器组ID
|
| | | Def_TalkExtraValue_Bit_LV, #等级
|
| | | ) = range(0, 6)
|
| | |
|
| | | #聊天信息附加值中某信息数据所占位置
|
| | | #{聊天信息附加值类型:[起始位置(从左往右), 结束位置(不包含)]}
|
| | | Def_TalkExtraValue_LenDict = {
|
| | | Def_TalkExtraValue_Bit_VipLv:[0, 2], # vip等级
|
| | | Def_TalkExtraValue_Bit_GM:[2, 3], # GM
|
| | | Def_TalkExtraValue_Bit_JOB:[3, 4], # job
|
| | | Def_TalkExtraValue_Bit_BubbleBox:[4, 6], # 气泡框
|
| | | Def_TalkExtraValue_Bit_ServerGroupID:[6, 13], # 服务器组ID
|
| | | Def_TalkExtraValue_Bit_LV:[13, 17], # 等级
|
| | | }
|
| | |
|
| | | # 聊天频道 暂用语音
|
| | | (Def_ChannelChat_World, # 世界
|
| | | Def_ChannelChat_Family, # 仙盟
|
| | | Def_ChannelChat_Private, # 私聊含好友
|
| | | Def_ChannelChat_Team, # 队伍
|
| | | Def_ChannelChat_Area, # 区域(当前地图或副本线)
|
| | | ) = range(1, 6)
|
| | |
|
| | | #背包类型
|
| | | (
|
| | | rptTempSwap, # 临时交换背包 28
|
| | |
| | | Def_GameRecType_FamilyGCZJoinFamily, # 仙盟攻城战参与仙盟信息, zoneID 303
|
| | | Def_GameRecType_FamilyGCZJoinMember, # 仙盟攻城战参与成员信息, zoneID 304
|
| | | Def_GameRecType_FamilyGCZCityWall, # 仙盟攻城战城池信息, zoneID 305
|
| | | ) = range(300, 1 + 305)
|
| | | Def_GameRecType_TalkCache, # 聊天缓存,频道 306
|
| | | ) = range(300, 1 + 306)
|
| | | #通用信息记录新 - 字典key配置,如果有配置,则可额外按对应记录Value值存储字典,方便快速取值,可配置Value编号 1~8,配空默认 Value1
|
| | | Def_GameRecValueKeyDict = {
|
| | | Def_GameRecType_Xiangong:[1],
|
| | |
| | | Def_ActionType_FamilyCTGAssist, #仙盟充值协助活动 14
|
| | | Def_ActionType_FamilyEmblem, #仙盟时效徽章信息 15
|
| | | Def_ActionType_Zhenbaoge, #珍宝阁 16
|
| | | ) = range(0, 17)
|
| | | Def_ActionType_TalkCache, #聊天缓存 17,最大条数配置决定
|
| | | ) = range(0, 18)
|
| | | |
| | | #家族某行为类型保存的条数
|
| | | ActionTypeSaveCnt = {
|
| | | Def_ActionType_FamilyPray:10 , #家族祈福
|
| | | Def_ActionType_FamilyArrest:7, #家族悬赏
|
| | | Def_ActionType_FamilyMember:1, #记录家族成员信息
|
| | | Def_ActionType_LeaderImpeachTime:1, # 族长下线了多久
|
| | | Def_ActionType_FamilyBossFB:1, # 记录家族boss副本信息
|
| | | Def_ActionType_FamilyStore:30, #仓库操作记录
|
| | | Def_ActionType_OfficerModelEquip:10, # 记录家族有职位的成员模型装备信息(盟主+副盟主*2+战斗队长*5)
|
| | | Def_ActionType_FamilyEvent:50, # 记录家族事件
|
| | | }
|
| | |
|
| | | # 家族行为事件类型定义; Def_ActionType_FamilyEvent; 存与事件记录Value1
|
| | | # 通用:time-时间;name-玩家;value1-事件类型
|