mirror of
https://port.numenaute.org/aleajactaest/clientbot.git
synced 2024-11-25 08:36:18 +00:00
835 lines
36 KiB
Python
835 lines
36 KiB
Python
#!/usr/bin/python3
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# module Impulse
|
|
#
|
|
# Copyright (C) 2019 AleaJactaEst
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import logging
|
|
from tools import getPowerOf2
|
|
from tools import BitStream
|
|
from tools import Enum
|
|
# from tools import Enum
|
|
|
|
ItemPropStr = [
|
|
"SHEET", # 32
|
|
"QUALITY", # 10
|
|
"QUANTITY", # 10
|
|
"USER_COLOR", # 3
|
|
"CREATE_TIME", # 32
|
|
"SERIAL", # 32
|
|
"LOCKED", # 10
|
|
"WEIGHT", # 16
|
|
"NAMEID", # 32
|
|
"ENCHANT", # 10
|
|
"RM_CLASS_TYPE", # 3
|
|
"RM_FABER_STAT_TYPE", # 5
|
|
"PRICE", # 32
|
|
"RESALE_FLAG", # 2
|
|
"PREREQUISIT_VALID", # 1
|
|
"WORNED" # 1
|
|
]
|
|
DataBitSize = [32, 10, 10, 3, 32, 32, 10, 16, 32, 10, 3, 5, 32, 2, 1, 1]
|
|
|
|
LOGGER='Impulse'
|
|
|
|
class ImpulseNoElement(Exception):
|
|
pass
|
|
|
|
|
|
class ImpulseBase:
|
|
def __init__(self):
|
|
self.name = ""
|
|
self.id = ""
|
|
self.param = {}
|
|
#self.Reference = []
|
|
|
|
def set_name(self, name):
|
|
self.name = name.replace(':', '_')
|
|
|
|
def get_name(self):
|
|
return self.name
|
|
|
|
def add_reference(self, ref):
|
|
#self.Reference.append(ref)
|
|
self.param.setdefault('Reference', [])
|
|
self.param['Reference'].append(ref)
|
|
|
|
def get_reference(self):
|
|
return self.param['Reference']
|
|
|
|
def get_parameter(self):
|
|
return self.param
|
|
|
|
def add_parameter(self, key, value):
|
|
self.param.setdefault(key, [])
|
|
self.param[key].append(value)
|
|
|
|
def add_value(self, key, value):
|
|
self.param.setdefault(key, "")
|
|
self.param[key] = value
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).error("Not define")
|
|
|
|
def readBool(self, msgin, id):
|
|
value = msgin.readBool(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readUint8(self, msgin, id):
|
|
value = msgin.readUint8(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readSint8(self, msgin, id):
|
|
value = msgin.readSint8(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readUint16(self, msgin, id):
|
|
value = msgin.readUint16(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readSint16(self, msgin, id):
|
|
value = msgin.readSint16(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readUint32(self, msgin, id):
|
|
value = msgin.readUint32(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readSint32(self, msgin, id):
|
|
value = msgin.readSint32(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readUint64(self, msgin, id):
|
|
value = msgin.readUint64(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readSint64(self, msgin, id):
|
|
value = msgin.readSint64(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readSerial(self, msgin, nbBits, id):
|
|
if nbBits == 1:
|
|
value = msgin.readSerial(nbBits, id, typeName="bool/1 bit")
|
|
else:
|
|
value = msgin.readSerial(nbBits, id, typeName="%d bits" % nbBits)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readUString(self, msgin, id):
|
|
value = msgin.readUString(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readUtf8String(self, msgin, id):
|
|
value = msgin.readUtf8String(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readString(self, msgin, id):
|
|
value = msgin.readString(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readFloat(self, msgin, id):
|
|
value = msgin.readFloat(id)
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
|
|
def readVersion(self, msgin, id):
|
|
value = msgin.readUint8(id)
|
|
if value == 255: #0xFF: # 0xFF
|
|
value = msgin.readUint32(id + '_extended')
|
|
self.param.setdefault(id, value)
|
|
return value
|
|
def readDatabases(self, world, decodeDatabase):
|
|
return None
|
|
|
|
class ImpulseBotchatSetFilters(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint32(msgin, 'qualityMin')
|
|
self.readUint32(msgin, 'qualityMax')
|
|
self.readUint32(msgin, 'priceMin')
|
|
self.readUint32(msgin, 'priceMax')
|
|
self.readUint8(msgin, 'classMin')
|
|
self.readUint8(msgin, 'classMax')
|
|
self.readUint8(msgin, 'itemPart')
|
|
self.readUint8(msgin, 'itemType')
|
|
|
|
|
|
class ImpulseConnectionAskName(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUString(msgin, 'Name')
|
|
self.readUint32(msgin, 'HomeSessionId')
|
|
|
|
|
|
class ImpulseConnectionCreateChar(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint8(msgin, 'Slot')
|
|
self.readUint32(msgin, 'SheetId')
|
|
self.readUint32(msgin, 'CSessionId')
|
|
self.readUString(msgin, 'name')
|
|
self.readUint8(msgin, 'People')
|
|
self.readUint8(msgin, 'Sex')
|
|
self.readUint8(msgin, 'NbPointFighter')
|
|
self.readUint8(msgin, 'NbPointCaster')
|
|
self.readUint8(msgin, 'NbPointCrafter')
|
|
self.readUint8(msgin, 'NbPointHarvester')
|
|
self.readSint32(msgin, 'StartPoint')
|
|
self.readSint8(msgin, 'HairType')
|
|
self.readSint8(msgin, 'HairColor')
|
|
self.readSint8(msgin, 'GabaritHeight')
|
|
self.readSint8(msgin, 'GabaritTorsoWidth')
|
|
self.readSint8(msgin, 'GabaritArmsWidth')
|
|
self.readSint8(msgin, 'GabaritLegsWidth')
|
|
self.readSint8(msgin, 'GabaritBreastSize')
|
|
self.readSint8(msgin, 'MorphTarget1')
|
|
self.readSint8(msgin, 'MorphTarget2')
|
|
self.readSint8(msgin, 'MorphTarget3')
|
|
self.readSint8(msgin, 'MorphTarget4')
|
|
self.readSint8(msgin, 'MorphTarget5')
|
|
self.readSint8(msgin, 'MorphTarget6')
|
|
self.readSint8(msgin, 'MorphTarget7')
|
|
self.readSint8(msgin, 'MorphTarget8')
|
|
self.readSint8(msgin, 'EyesColor')
|
|
self.readSint8(msgin, 'Tattoo')
|
|
self.readSint8(msgin, 'JacketColor')
|
|
self.readSint8(msgin, 'TrousersColor')
|
|
self.readSint8(msgin, 'HatColor')
|
|
self.readSint8(msgin, 'ArmsColor')
|
|
self.readSint8(msgin, 'HandsColor')
|
|
self.readSint8(msgin, 'FeetColor')
|
|
|
|
|
|
class ImpulseConnectionReady(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readString(msgin, 'LanguageCode')
|
|
|
|
|
|
class ImpulseConnectionSelectChar(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint8(msgin, 'SelectCharMsg')
|
|
|
|
|
|
class ImpulseConnectionUserChar(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readSint32(msgin, 'X')
|
|
self.readSint32(msgin, 'Y')
|
|
self.readSint32(msgin, 'Z')
|
|
self.readFloat(msgin, 'Heading')
|
|
self.readSerial(msgin, 3, 'season')
|
|
self.readSerial(msgin, 3, 'userRole')
|
|
self.readUint32(msgin, 'highestMainlandSessionId')
|
|
self.readUint32(msgin, 'firstConnectedTime')
|
|
self.readUint32(msgin, 'playedTime')
|
|
|
|
|
|
class ImpulseConnectionShardId(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint32(msgin, 'shardId')
|
|
self.readString(msgin, 'webHost')
|
|
|
|
|
|
class ImpulseConnectionValidName(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint8(msgin, 'valide')
|
|
|
|
|
|
class ImpulseDebugPing(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint32(msgin, 'localTime')
|
|
|
|
|
|
class ImpulseGuildFemaleTitles(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readSerial(msgin, 1, 'UseFemaleTitles')
|
|
|
|
|
|
class ImpulseNpcIconSetDesc(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.data = BitStream.BitStream()
|
|
|
|
def read(self, name, msgin, world):
|
|
'''
|
|
khanat-opennel-code/code/ryzom/server/src/entities_game_service/player_manager/character.cpp:20976 void CCharacter::sendNpcMissionGiverIconDesc( const std::vector<uint32>& npcKeys )
|
|
'''
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
nb8 = self.readUint8(msgin, 'nb8')
|
|
self.data.pushUint8(nb8)
|
|
for i in range(0, nb8):
|
|
npcAlias = self.readUint32(msgin, 'NpcIconSetDesc_%d_npcAlias' % nb8)
|
|
self.data.pushUint32(npcAlias)
|
|
state = self.readUint32(msgin, 'NpcIconSetDesc_%d_state' % nb8)
|
|
self.data.pushUint32(state)
|
|
|
|
def readDatabases(self, world, decodeDatabase):
|
|
return decodeDatabase.execute(self.data, world)
|
|
|
|
|
|
class ImpulsePhraseDownload(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def readSerialPhrase(self, msgin, id):
|
|
self.readUtf8String(msgin, id)
|
|
size = self.readSint32(msgin, id + '_len')
|
|
for i in range(0, size):
|
|
self.readUint16(msgin, '%s_compBricks_%d' % (id, i))
|
|
|
|
def readSerialPhrases(self, msgin, id):
|
|
"""
|
|
khanat-opennel-code/code/ryzom/server/src/entities_game_service/player_manager/character.cpp:13586 void CCharacter::sendPhrasesToClient()
|
|
khanat-opennel-code/code/nel/include/nel/misc/stream.h:1089 void serialVector(T &cont)
|
|
khanat-opennel-code/code/ryzom/common/src/game_share/sphrase_com.cpp:57 void CSPhraseCom::serial(NLMISC::IStream &impulse)
|
|
"""
|
|
size = self.readSint32(msgin, id + '_len')
|
|
for i in range(0, size):
|
|
#self.param.setdefault('%d:Phrase' % i, msgin.readUtf8String('%d:Phrase:Name' % i))
|
|
#self.param.setdefault('%d:Phrase' % i, msgin.readString('%d:Phrase' % i))
|
|
self.readSerialPhrase(msgin, '%s_%d_Phrase' % (id, i))
|
|
self.readUint16(msgin, '%s_%d_KnownSlot' % (id, i))
|
|
self.readUint32(msgin, '%s_%d_PhraseSheetId' % (id, i))
|
|
#self.param.setdefault('%d:PhraseSheetId:Type' % i, msgin.readUint32('%d:PhraseSheetId:IdInfos:Type' % i))
|
|
#self.param.setdefault('%d:PhraseSheetId:Type' % i, msgin.readUint32('%d:PhraseSheetId:IdInfos:Id' % i))
|
|
|
|
def readSerialMemorizedPhrases(self, msgin, id):
|
|
size = self.readSint32(msgin, id + '_len')
|
|
for i in range(0, size):
|
|
self.readUint8(msgin, '%s_%d_MemoryLineId' % (id, i))
|
|
self.readUint8(msgin, '%s_%d_MemorySlotId' % (id, i))
|
|
self.readUint16(msgin, '%s_%d_PhraseId' % (id, i))
|
|
# tmp = {}
|
|
# for i in range(0, size):
|
|
# data = {}
|
|
# data.setdefault('MemoryLineId', msgin.readUint8('%d:MemoryLineId' % i))
|
|
# data.setdefault('MemorySlotId', msgin.readUint8('%d:MemorySlotId' % i))
|
|
# data.setdefault('PhraseId', msgin.readUint16('%d:PhraseId' %i))
|
|
# tmp.setdefault('MemorizedPhrase_%d' % i, data)
|
|
# self.param.setdefault("MemorizedPhrase", tmp)
|
|
|
|
def read(self, name, msgin, world):
|
|
"""
|
|
khanat-opennel-code/code/ryzom/server/src/entities_game_service/player_manager/character.cpp:13586 void CCharacter::sendPhrasesToClient()
|
|
"""
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
# return
|
|
#self.param.setdefault(id + 'phrases', msgin.readString('phrases'))
|
|
#self.param.setdefault(id + 'memorizedPhrases', msgin.readString('memorizedPhrases'))
|
|
self.readSerialPhrases(msgin, 'KnownPhrases')
|
|
self.readSerialMemorizedPhrases(msgin, 'MemorizedPhrases')
|
|
#logging.getLogger(LOGGER).error("[Client -> Server] msg:%s" % msgin.showAllData())
|
|
#raise ValueError
|
|
|
|
|
|
class ImpulsePosition(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
# khanat-opennel-code/code/ryzom/server/src/gpm_service/client_messages.cpp void cbClientPosition( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId )
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readBool(msgin, '')
|
|
self.readSint32(msgin, 'X')
|
|
self.readSint32(msgin, 'Y')
|
|
self.readSint32(msgin, 'Z')
|
|
self.readFloat(msgin, 'Heading')
|
|
|
|
|
|
class ImpulseSringDynString(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint32(msgin, 'phraseId')
|
|
|
|
|
|
class ImpulseSringManagerReloadCache(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint32(msgin, 'timestamp')
|
|
|
|
|
|
class ImpulseSringManagerPhraseSend(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
id = 'SringManagerPhrase'
|
|
#self.param.setdefault('%s_seqNum' %(id), msgin.readUint32('%s_seqNum' % (id)))
|
|
#self.param.setdefault('%s_id'%(id), msgin.readUint32('%s_id'%(id)))
|
|
self.readUint32(msgin, '%s_dynId' % id)
|
|
self.readUint32(msgin, '%s_StringId' % id)
|
|
i = 0
|
|
while msgin.needRead() >= 32:
|
|
self.readUint32(msgin, '%s_StringId_%d' % (id, i))
|
|
i += 1
|
|
|
|
class ImpulseSringManagerStringResp(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint32(msgin, 'stringId')
|
|
self.readUtf8String(msgin, 'strUtf8')
|
|
|
|
|
|
class ImpulseSringManagerStringRq(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint32(msgin, 'stringId')
|
|
|
|
|
|
class impulseGuildUpdatePlayerTitle(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readBool(msgin, 'bUnblock')
|
|
id = "vTitle"
|
|
size = self.readSint32(msgin, '%s_len' % id)
|
|
for i in range(0, size):
|
|
self.readUint16(msgin, '%s_%d' % (id, i))
|
|
|
|
class impulseDeathRespawnPoint(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
id = "CRespawnPointsMsg"
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readBool(msgin, '%s_NeedToReset' % id)
|
|
size = self.readSint32(msgin, '%s_len' % id)
|
|
for i in range(0, size):
|
|
self.readSint32(msgin, '%s_%d_x' % (id, i))
|
|
self.readSint32(msgin, '%s_%d_y' % (id, i))
|
|
|
|
class impulseEncyclopediaInit(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read_thema(self, id, msgin):
|
|
size_thema = self.readSint32(msgin, '%s_thema_len' % (id))
|
|
for ii in range(0, size_thema):
|
|
self.readUint32(msgin, '%s_thema_%d_Name' % (id, ii))
|
|
StateNbTask = self.readUint8(msgin, '%s_thema_%d_StateNbTask' % (id, ii))
|
|
State = StateNbTask & 0x3;
|
|
NbTask = StateNbTask >> 2 ;
|
|
if State == 2:
|
|
self.readUint32(msgin, '%s_thema_%d_RewardText' % (id, ii))
|
|
self.readUint32(msgin, '%s_thema_%d_RewardSheet' % (id, ii))
|
|
for iii in range(0, NbTask):
|
|
self.readUint32(msgin, '%s_thema_%d_Task_%d_Name' % (id, ii, iii))
|
|
self.readUint32(msgin, '%s_thema_%d_Task_%d_NPCName' % (id, ii, iii))
|
|
self.readUint16(msgin, '%s_thema_%d_RiteTaskStatePacked' % (id, ii))
|
|
|
|
def read_album(self, id, msgin):
|
|
self.readUint32(msgin, '%s_Album_Name' % (id))
|
|
self.readUint32(msgin, '%s_Album_RewardBrick' % (id))
|
|
self.readUint8(msgin, '%s_Album_State' % (id))
|
|
self.read_thema(id, msgin)
|
|
|
|
def read(self, name, msgin, world):
|
|
id = "EncyclopediaInit"
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
type = self.readSint32(msgin, '%s_Type' % id)
|
|
if type == 0: # UpdateInit
|
|
id += '_AllAlbums'
|
|
size = self.readSint32(msgin, '%s_len' % id)
|
|
for i in range(0, size):
|
|
self.read_album(id, msgin)
|
|
elif type == 1: # UpdateAlbum
|
|
id += '_UpdateAlbum'
|
|
self.read_album(id, msgin)
|
|
else: # type == 2: # UpdateThema
|
|
id += '_UpdateThema'
|
|
self.readUint32(msgin, '%s_AlbumName' % (id))
|
|
self.read_thema(id, msgin)
|
|
|
|
class impulseInitInventory(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
# khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void updateInventoryFromStream (NLMISC::CBitMemStream &impulse, const CInventoryCategoryTemplate *templ, bool notifyItemSheetChanges)
|
|
# khanat-opennel-code/code/ryzom/server/src/entities_game_service/inventory_updater.cpp void CInventoryUpdaterForCharacter::sendAllUpdates( const NLMISC::CEntityId& destEntityId )
|
|
id = "InitInventory"
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
#self.readSint32(msgin, '%s_pos' % id)
|
|
self.readUint32(msgin, '%s_serverTick' % id)
|
|
for invId in range(0, Enum.TInventoryId.NbInventoryIds):
|
|
hasContent = self.readBool(msgin, '%s_%d_hasContent' % (id, invId))
|
|
if hasContent == False:
|
|
continue;
|
|
nbChanges = self.readSerial(msgin, 3, '%s_%d_nbChanges' % (id, invId)) # INVENTORIES::LowNumberBits = 3
|
|
if nbChanges == 7: # == INVENTORIES::LowNumberBound = 7
|
|
nbChanges = self.readSerial(msgin, 32, '%s_%d_nbChanges_next' % (id, invId)) # INVENTORIES::LowNumberBits = 3
|
|
for itu in range(0, nbChanges):
|
|
iuInfoVersion = self.readSerial(msgin, 1, '%s_%d_%d_itu_iuInfoVersion' % (id, invId, itu))
|
|
if iuInfoVersion == 1:
|
|
_ = self.readSerial(msgin, 10, '%s_%d_%d_itu_iuInfoVersion_slotIndex' % (id, invId, itu)) # ICInventoryCategoryTemplate::SlotBitSize = 10
|
|
#self.param.setdefault('%s_%d_infoVersion' % (id, i), msgin.readUint8('%s_%d_infoVersion' % (id, i)))
|
|
else:
|
|
iuAll = self.readSerial(msgin, 1, '%s_%d_%d_iuAll' % (id, invId, itu))
|
|
if iuAll == 1:
|
|
_ = self.readSerial(msgin, 10, '%s_%d_%d_iuAll_slotIndex' % (id, invId, itu)) # ICInventoryCategoryTemplate::SlotBitSize = 10
|
|
for ii in range(0, 6):
|
|
#ItemSlot = msgin.readSerial( DataBitSize[ii], '%s_%d_ItemSlot_%s' % (id, i, ItemPropStr[ii]))
|
|
self.readSerial(msgin, DataBitSize[ii], '%s_%d_%d_iuAll_ItemProp_%s' % (id, invId, itu, ItemPropStr[ii]))
|
|
for ii in range(6, Enum.TItemPropId.NbItemPropId):
|
|
b = self.readBool(msgin, '%s_%d_%d_iuAll_ItemProp_%s_compressed' %(id, invId, itu, ItemPropStr[ii]))
|
|
if b:
|
|
pass
|
|
else:
|
|
#ItemProp = msgin.readSerial(DataBitSize(ii), '%s_%d_ItemSlot_%d_ItemProp' %(id , i, ii))
|
|
self.readSerial(msgin, DataBitSize[ii], '%s_%d_%d_iuAll_ItemProp_%s_ItemProp' %(id, invId, itu, ItemPropStr[ii]))
|
|
else:
|
|
iuOneProp = self.readSerial(msgin, 1, '%s_%d_%d_iuOneProp' % (id, invId, itu))
|
|
if iuOneProp == 1:
|
|
# bms.serial( _SlotIndex, CInventoryCategoryTemplate::SlotBitSize ); 10
|
|
_ = self.readSerial(msgin, 10, '%s_%d_%d_iuOneProp_SlotIndex' %(id, invId, itu))
|
|
ItemPropIdUint32 = self.readSerial(msgin, 4, '%s_%d_%d_iuOneProp_ItemPropId' %(id, invId, itu))
|
|
_ = self.readSerial(msgin, DataBitSize[ItemPropIdUint32], '%s_%d_%d_iuOneProp_ItemPropValue' %(id, invId, itu))
|
|
# bms.serial( _OneProp );
|
|
# bms.serial((uint32&)ItemPropIdUint32, NbBitsForItemPropId);
|
|
# bms.serial((uint32&)ItemPropValue, CItemSlot::DataBitSize[ItemPropId]);
|
|
else: # iuReset
|
|
_ = self.readSerial(msgin, 10, '%s_%d_%d_iuReset_SlotIndex' %(id, invId, itu))
|
|
#self.param.setdefault('%s_%d_y' % (id, i), msgin.readSint32('%s_%d_y' % (id, i)))
|
|
|
|
|
|
class ImpulseConnectionUserChars(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
# khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseUserChars(NLMISC::CBitMemStream &impulse)
|
|
# khanat-opennel-code/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp void sendCharactersSummary( CPlayer *player, bool AllAutorized, uint32 bitfieldOwnerOfActiveAnimSession, uint32 bitfieldOwnerOfEditSession )
|
|
id = "ConnectionUserChars"
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
_ = self.readUint8(msgin, '%s_ServerPeopleActive' % id)
|
|
_ = self.readUint8(msgin, '%s_ServerCareerActive' % id)
|
|
CharacterSummaries_Len = self.readUint32(msgin, '%s_CharacterSummaries_Len' % id)
|
|
for i in range(0, CharacterSummaries_Len):
|
|
self.readVersion(msgin, "%s_CharacterSummaries_%d_Version" % (id, i))
|
|
self.readUint32(msgin, '%s_CharacterSummaries_%d_Mainland' % (id, i))
|
|
self.readUString(msgin, '%s_CharacterSummaries_%d_Name' % (id, i))
|
|
self.readSint32(msgin, '%s_CharacterSummaries_%d_People' % (id, i))
|
|
self.readUint32(msgin, '%s_CharacterSummaries_%d_Location' % (id, i))
|
|
self.readUint64(msgin, '%s_CharacterSummaries_%d_VisualPropA' % (id, i))
|
|
self.readUint64(msgin, '%s_CharacterSummaries_%d_VisualPropB' % (id, i))
|
|
self.readUint64(msgin, '%s_CharacterSummaries_%d_VisualPropC' % (id, i))
|
|
self.readUint32(msgin, '%s_CharacterSummaries_%d_SheetId' % (id, i))
|
|
self.readSint32(msgin, '%s_CharacterSummaries_%d_Title' % (id, i))
|
|
self.readUint8(msgin, '%s_CharacterSummaries_%d_CharacterSlot' % (id, i))
|
|
self.readBool(msgin, '%s_CharacterSummaries_%d_InRingSession' % (id, i))
|
|
self.readBool(msgin, '%s_CharacterSummaries_%d_HasEditSession' % (id, i))
|
|
self.readBool(msgin, '%s_CharacterSummaries_%d_InNewbieland' % (id, i))
|
|
shardNames_Len = self.readUint32(msgin, '%s_ShardNames_Len' % id)
|
|
for i in range(0, shardNames_Len):
|
|
self.readString(msgin, '%s_ShardNames_%d' % (id, i))
|
|
_ = self.readString(msgin, '%s_Privileges' % id)
|
|
self.readBool(msgin, '%s_FreeTrial' % (id))
|
|
Mainlands_Len = self.readUint32(msgin, '%s_Mainlands_Len' % id)
|
|
for i in range(0, Mainlands_Len):
|
|
self.readUint32(msgin, '%s_Mainlands_%d_id' % (id, i))
|
|
self.readUString(msgin, '%s_Mainlands_%d_Name' % (id, i))
|
|
self.readUString(msgin, '%s_Mainlands_%d_Description' % (id, i))
|
|
self.readString(msgin, '%s_Mainlands_%d_LanguageCode' % (id, i))
|
|
self.readBool(msgin, '%s_Mainlands_%d_Online' % (id, i))
|
|
|
|
|
|
class impulseDatabaseInitPlayer(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
# khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseDatabaseInitPlayer(NLMISC::CBitMemStream &impulse)
|
|
# khanat-opennel-code/code/ryzom/server/src/simulation_service/simulated_editor.cpp void impulseDatabaseInitPlayer(NLMISC::CBitMemStream &impulse)
|
|
id = "DatabaseInitPlayer"
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint32(msgin, '%s_serverTick' % id)
|
|
propertyCount = self.readUint16(msgin, '%s_propertyCount' % id)
|
|
for i in range(0, propertyCount):
|
|
_ = self.readUint32(msgin, '%s_property' % id)
|
|
|
|
|
|
class ImpulseConnectionDeleteChar(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
# khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseDatabaseInitPlayer(NLMISC::CBitMemStream &impulse)
|
|
# khanat-opennel-code/code/ryzom/server/src/simulation_service/simulated_editor.cpp void impulseDatabaseInitPlayer(NLMISC::CBitMemStream &impulse)
|
|
id = "ConnectionDeleteChar"
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
self.readUint8(msgin, '%s_slot' % id)
|
|
|
|
|
|
class impulseTeamContactInit(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
id = "TeamContactInit"
|
|
logging.getLogger(LOGGER).debug("read")
|
|
self.name = name.replace(':', '_')
|
|
friend_string_ids_len = self.readUint32(msgin, '%s_friend_string_ids_len' % id)
|
|
for i in range(0, friend_string_ids_len):
|
|
_ = self.readUint32(msgin, '%s_friend_string_ids_%d' % (id, i))
|
|
nb_state = self.readUint32(msgin, '%s_nb_state' % id)
|
|
for i in range(0, nb_state):
|
|
_ = self.readUint32(msgin, '%s_friend_online_status_%d' % (id, i))
|
|
ignore_list_len = self.readUint32(msgin, '%s_ignore_list_len' % id)
|
|
for i in range(0, ignore_list_len):
|
|
_ = self.readUString(msgin, '%s_ignore_list_%d' % (id, i))
|
|
|
|
|
|
class impulseNpcIconGetDesc(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
# khanat-opennel-code/code/ryzom/server/src/frontend_service/id_impulsions.cpp void cbImpulsionGetNpcIconDesc( CEntityId& sender, CBitMemStream &bms, TGameCycle gamecycle, uint16 serviceId )
|
|
id = "ClientNpcIcon"
|
|
logging.getLogger(LOGGER).debug("read %s" % id)
|
|
self.name = name.replace(':', '_')
|
|
nb8 = self.readUint8(msgin, '%s_nb8' % id)
|
|
for i in range(0, nb8):
|
|
_ = self.readUint32(msgin, '%s_NPCIconCacheKey_%d' % (id, i))
|
|
|
|
|
|
class impulseUserBars(ImpulseBase):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def read(self, name, msgin, world):
|
|
# khanat-opennel-code/code/ryzom/server/src/entities_game_service/player_manager/character.cpp void CCharacter::barUpdate()
|
|
id = "UserBars"
|
|
logging.getLogger(LOGGER).debug("read %s" % id)
|
|
self.name = name.replace(':', '_')
|
|
_ = self.readUint8(msgin, '%s_barsenttoplayermsgnumber' % id)
|
|
_ = self.readSint32(msgin, '%s_oldchascore1barsenttoplayer' % id)
|
|
_ = self.readSint32(msgin, '%s_oldchascore2barsenttoplayer' % id)
|
|
_ = self.readSint32(msgin, '%s_oldchascore3barsenttoplayer' % id)
|
|
_ = self.readSint32(msgin, '%s_oldchascore4barsenttoplayer' % id)
|
|
|
|
|
|
class DecodeImpulseSimple:
|
|
def __init__(self):
|
|
'''
|
|
khanat-opennel-code/code/ryzom/client/src/net_manager.cpp # void initializeNetwork()
|
|
'''
|
|
self.msgXml = None
|
|
self.databaseXml = None
|
|
self.GenericMsgHeaderMngr = {}
|
|
self.initializeNetwork()
|
|
|
|
def initializeNetwork(self):
|
|
# Send by client
|
|
self.GenericMsgHeaderMngr.setdefault( "BOTCHAT:SET_FILTERS", ImpulseBotchatSetFilters )
|
|
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:ASK_NAME", ImpulseConnectionAskName )
|
|
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:CREATE_CHAR", ImpulseConnectionCreateChar )
|
|
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:DELETE_CHAR", ImpulseConnectionDeleteChar )
|
|
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:READY", ImpulseConnectionReady )
|
|
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:SELECT_CHAR", ImpulseConnectionSelectChar )
|
|
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:SHARD_ID", ImpulseConnectionShardId )
|
|
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:USER_CHAR", ImpulseConnectionUserChar )
|
|
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:USER_CHARS", ImpulseConnectionUserChars )
|
|
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:VALID_NAME", ImpulseConnectionValidName )
|
|
self.GenericMsgHeaderMngr.setdefault( "DEBUG:PING", ImpulseDebugPing )
|
|
self.GenericMsgHeaderMngr.setdefault( "DEATH:RESPAWN_POINT", impulseDeathRespawnPoint)
|
|
self.GenericMsgHeaderMngr.setdefault( "GUILD:UPDATE_PLAYER_TITLE", impulseGuildUpdatePlayerTitle)
|
|
self.GenericMsgHeaderMngr.setdefault( "GUILD:USE_FEMALE_TITLES", ImpulseGuildFemaleTitles )
|
|
self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SET_DESC", ImpulseNpcIconSetDesc )
|
|
self.GenericMsgHeaderMngr.setdefault( "PHRASE:DOWNLOAD", ImpulsePhraseDownload )
|
|
self.GenericMsgHeaderMngr.setdefault( "POSITION", ImpulsePosition )
|
|
self.GenericMsgHeaderMngr.setdefault( "STRING:DYN_STRING", ImpulseSringDynString )
|
|
self.GenericMsgHeaderMngr.setdefault( "STRING_MANAGER:RELOAD_CACHE", ImpulseSringManagerReloadCache )
|
|
self.GenericMsgHeaderMngr.setdefault( "STRING_MANAGER:PHRASE_SEND", ImpulseSringManagerPhraseSend )
|
|
self.GenericMsgHeaderMngr.setdefault( "STRING_MANAGER:STRING_RESP", ImpulseSringManagerStringResp )
|
|
self.GenericMsgHeaderMngr.setdefault( "STRING_MANAGER:STRING_RQ", ImpulseSringManagerStringRq )
|
|
self.GenericMsgHeaderMngr.setdefault( "ENCYCLOPEDIA:INIT", impulseEncyclopediaInit )
|
|
self.GenericMsgHeaderMngr.setdefault( "DB_INIT:INV", impulseInitInventory)
|
|
self.GenericMsgHeaderMngr.setdefault( "DB_INIT:PLR", impulseDatabaseInitPlayer)
|
|
self.GenericMsgHeaderMngr.setdefault( "TEAM:CONTACT_INIT", impulseTeamContactInit)
|
|
self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:GET_DESC", impulseNpcIconGetDesc)
|
|
self.GenericMsgHeaderMngr.setdefault( "USER:BARS", impulseUserBars)
|
|
|
|
def execute(self, msgin, world, references = [], name=""):
|
|
'''
|
|
khanat-opennel-code/code/ryzom/client/src/net_manager.cpp:3746 void impulseCallBack(NLMISC::CBitMemStream &impulse, sint32 packet, void *arg)
|
|
khanat-opennel-code/code/ryzom/common/src/game_share/generic_xml_msg_mngr.cpp:121 void CGenericXmlMsgHeaderManager::execute(CBitMemStream &strm)
|
|
khanat-opennel-code/code/ryzom/common/src/game_share/generic_xml_msg_mngr.h:431 CNode *select(NLMISC::CBitMemStream &strm)
|
|
|
|
uint32 index = 0;
|
|
uint NbBits;
|
|
|
|
strm.serialAndLog2(index, node->NbBits);
|
|
'''
|
|
logging.getLogger(LOGGER).debug("execute")
|
|
head = self.msgXml
|
|
listpath = []
|
|
while True:
|
|
nbBit = getPowerOf2.getPowerOf2(len(head))
|
|
#logging.getLogger(LOGGER).error("nbBit : %d " % nbBit)
|
|
#for child in head:
|
|
# print(child.tag, child.attrib)
|
|
try:
|
|
id = msgin.readSerial(nbBit, name='MsgXML', typeName='Number', emulate=True)
|
|
except BitStream.OverflowError:
|
|
raise ImpulseNoElement
|
|
|
|
if id is None:
|
|
raise ImpulseNoElement
|
|
try:
|
|
ele = head[id]
|
|
except IndexError as e:
|
|
logging.getLogger(LOGGER).error("Error to decode message: %s" % msgin.showAllData() )
|
|
raise e
|
|
command = ele.attrib['name']
|
|
listpath.append(command)
|
|
fullname = ':'.join(listpath)
|
|
|
|
id = msgin.readSerial(nbBit, name='MsgXML', typeName='XML <' + command + '>')
|
|
if fullname in self.GenericMsgHeaderMngr:
|
|
logging.getLogger(LOGGER).debug("Found : %s" % fullname)
|
|
impulse = self.GenericMsgHeaderMngr[fullname]()
|
|
impulse.read(fullname, msgin, world)
|
|
logging.getLogger(LOGGER).debug("MessageXML decoded: %s" % msgin.showAllData() )
|
|
impulse.add_value("command", fullname)
|
|
for reference in references:
|
|
impulse.add_reference(reference)
|
|
impulse.add_value("Message", msgin.extractAllData())
|
|
# check we decode all message
|
|
nbBitNotRead = msgin.needRead()
|
|
if nbBitNotRead == 0:
|
|
return impulse
|
|
elif nbBitNotRead < 8:
|
|
a = msgin.readSerial(nbBitNotRead, decode=False)
|
|
if a == 0:
|
|
return impulse
|
|
logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s [size:%d, not read:%d]" % (fullname, msgin.showAllData(), nbBitNotRead, a))
|
|
elif nbBitNotRead < 32:
|
|
a = msgin.readSerial(nbBitNotRead, decode=False)
|
|
if a == 0:
|
|
return impulse
|
|
logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s [size:%d, not read:%d]" % (fullname, msgin.showAllData(), nbBitNotRead, a))
|
|
logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s [size:%d]" % (fullname, msgin.showAllData(), nbBitNotRead))
|
|
return None
|
|
else:
|
|
#logging.getLogger(LOGGER).debug("Non trouve")
|
|
for ele in head:
|
|
if ele.attrib['name'] == command:
|
|
head = ele
|
|
break
|
|
if head != ele:
|
|
logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s" % (fullname, msgin.showAllData() ))
|
|
return None
|
|
# End While
|
|
logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s" % (fullname, msgin.showAllData() ))
|
|
return None
|
|
|
|
def loadMsg(self, msgXml):
|
|
logging.getLogger(LOGGER).debug("msgXml")
|
|
self.msgXml = msgXml
|
|
|
|
def loadDatabase(self, databaseXml):
|
|
self.databaseXml = databaseXml
|