decode message CONNECTION:USER_CHARS

This commit is contained in:
AleaJactaEst 2019-06-14 00:07:41 +02:00
parent 042b01b7f5
commit 0b9c136718

203
client.py
View file

@ -185,14 +185,13 @@ class BitStream():
# ------------------------------------
def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False):
v1 = self._read
if nbits == 0:
return
elif nbits > 32:
raise "Out of range"
if self._read + nbits > self._pos:
raise "Stream Overflow"
if decode and not emulate:
self._groupRead.append((self._read, self._read+nbits, name, typeName))
if emulate:
oldRead = self._read
value = 0
@ -208,10 +207,14 @@ class BitStream():
self._read += nbits
if emulate:
self._read = oldRead
if decode and not emulate:
self._groupRead.append((v1, v1+nbits, name, typeName, value))
return value
def readBool(self, name):
v = self.readSerial(1, name=name, typeName='Bool')
v1 = self._read
v = self.readSerial(1, name=name, decode=False, typeName='Bool')
self._groupRead.append((v1, v1+1, name, 'Bool', 'True' if v != 0 else 'False'))
if v != 0:
return True
else:
@ -225,8 +228,8 @@ class BitStream():
v = self.readSerial(32, name=name, decode=decode, typeName='Sint32')
return c_int32(v).value
def readUint16(self, name):
v = self.readSerial(16, name=name, typeName='Uint16')
def readUint16(self, name, decode=True):
v = self.readSerial(16, name=name, decode=decode, typeName='Uint16')
return v
def readSint16(self, name):
@ -242,33 +245,38 @@ class BitStream():
return c_int8(v).value
def readUint64(self, name):
self._groupRead.append((self._read, self._read+64, name, 'Uint64'))
v1 = self._read
v = self.readSerial(32, decode=False)
v1 = self.readSerial(32, decode=False)
v2 = v | (v1 << 32)
self._groupRead.append((v1, v1+64, name, 'Uint64', v2))
return v2
def readSint64(self, name):
self._groupRead.append((self._read, self._read+64, name, 'Sint64'))
v1 = self._read
v = self.readSerial(32, decode=False)
v1 = self.readSerial(32, decode=False)
v2 = v | (v1 << 32)
self._groupRead.append((v1, v1+64, name, 'Sint64', c_int64(v2).value))
return c_int64(v2).value
def readFloat(self, name):
v = self.readSerial(32, name=name, typeName='Float')
v1 = self._read
v = self.readSerial(32, name=name, decode=False, typeName='Float')
v1 = struct.pack('I', v)
v2 = struct.unpack('<f',v1)[0]
self._groupRead.append((v1, v1+32, name, 'Float', v2))
return v2
def readDouble(self, name):
self._groupRead.append((self._read, self._read+64, name, 'Double'))
v1 = self._read
v = self.readSerial(32, decode=False)
v1 = struct.pack('I', v)
w = self.readSerial(32, decode=False)
w1 = struct.pack('I', w)
x = v1 + w1
x1 = struct.unpack('<d', x)[0]
self._groupRead.append((v1, v1+64, name, 'Double', x1))
return x1
def readChar(self, name, decode=True):
@ -287,7 +295,22 @@ class BitStream():
if v2 > self._pos:
raise ValueError
if v1 < v2:
self._groupRead.append((v1, v2, name + ':string', 'String'))
self._groupRead.append((v1, v2, name + ':string', 'String', tmp))
return tmp
def readUString(self, name):
tmp = ''
_size = self.readUint32(name + ':size', decode=True)
v1 = self._read
while _size > 0:
x = self.readUint16(name='', decode=False)
tmp += chr(x)
_size -= 1
v2 = self._read
if v2 > self._pos:
raise ValueError
if v1 < v2:
self._groupRead.append((v1, v2, name + ':ustring', 'UString', tmp))
return tmp
def readArrayUint8(self, size, name):
@ -296,7 +319,7 @@ class BitStream():
for i in range(0, size):
ret.append(self.readUint8('', decode=False))
v2 = self._read
self._groupRead.append((v1, v2, name, 'ArrayUint8'))
self._groupRead.append((v1, v2, name, 'ArrayUint8', ''))
return ret
def readBitStreamUint8(self, size, name):
@ -305,7 +328,7 @@ class BitStream():
for i in range(0, size):
ret.pushUint8(self.readUint8('', decode=False))
v2 = self._read
self._groupRead.append((v1, v2, name, 'StreamUint8'))
self._groupRead.append((v1, v2, name, 'StreamUint8', ''))
return ret
def readCont(self, name):
@ -315,7 +338,7 @@ class BitStream():
for i in range(0, size):
ret.pushBool(self.readSerial(1,name = '', decode=False))
v2 = self._read
self._groupRead.append((v1, v2, name + ':data', 'readCont'))
self._groupRead.append((v1, v2, name + ':data', 'readCont', ''))
return size, ret
# ------------------------------------
@ -395,8 +418,8 @@ class BitStream():
ret2 = ""
last = 0
for x, y, name, typeName in self._groupRead:
ret2 += "[<" + str(x) + ':' + str(y-1) + "> " + str(name) + ' (' + typeName + ') = ' + ret[x:y] + "]"
for x, y, name, typeName, value in self._groupRead:
ret2 += "[<" + str(x) + ':' + str(y-1) + "> " + str(name) + ' (' + typeName + ') : ' + ret[x:y] + ' => ' + str(value) + "]"
last = y
if last < self._pos:
ret2 += "{" + ret[last:] + "}"
@ -1414,7 +1437,7 @@ class ECharacterTitle(IntEnum):
Title00077 = 225 #
Title00078 = 226 #
Title00079 = 227 # // Wayfarer
WIND = Title00079 # // Title for player come from old Windermmer community
WIND = Title00079 # // Title for player come from old Windermmer community
FBT = 228 #
BeginGmTitle = 229 #
# SGM = BeginGmTitle #
@ -1435,17 +1458,17 @@ class SPropVisualA():
'''
khanat-opennel-code/code/ryzom/common/src/game_share/player_visual_properties.h # struct SPropVisualA
'''
self.Sex = False #: 1; // max: 2 current: 2
self.JacketModel = 0 #: 8; // max: 256 current: 93
self.JacketColor = 0 #: 3; // max: 8 current: 8
self.TrouserModel = 0 #: 8; // max: 256 current: 104
self.TrouserColor = 0 #: 3; // max: 8 current: 8
self.WeaponRightHand = 0 #: 10; // max: 1024 current: 457
self.WeaponLeftHand = 0 #: 8; // max: 256 current: 63
self.ArmModel = 0 #: 8; // max: 256 current: 94
self.ArmColor = 0 #: 3; // max: 8 current: 8
self.HatModel = 0 #: 9; // max: 512 current: 192
self.HatColor = 0 #: 3; // max: 8 current: 8
self.Sex = False #: 1; // max: 2 current: 2
self.JacketModel = 0 #: 8; // max: 256 current: 93
self.JacketColor = 0 #: 3; // max: 8 current: 8
self.TrouserModel = 0 #: 8; // max: 256 current: 104
self.TrouserColor = 0 #: 3; // max: 8 current: 8
self.WeaponRightHand = 0 #: 10; // max: 1024 current: 457
self.WeaponLeftHand = 0 #: 8; // max: 256 current: 63
self.ArmModel = 0 #: 8; // max: 256 current: 94
self.ArmColor = 0 #: 3; // max: 8 current: 8
self.HatModel = 0 #: 9; // max: 512 current: 192
self.HatColor = 0 #: 3; // max: 8 current: 8
def read(self, msgin):
self.Sex = msgin.readBool('Sex')
@ -1464,11 +1487,11 @@ class SPropVisualA():
class SPropVisualB():
def __init__(self):
self.Name = "" #: 16;
self.HandsModel = 0 #: 9; // max: 512 current: 90
self.HandsColor = 0 #: 3; // max: 8 current: 8
self.FeetModel = 0 #: 9; // max: 512 current: 94
self.FeetColor = 0 #: 3; // max: 8 current: 8
self.RTrail = 0 #: 4;
self.HandsModel = 0 #: 9; // max: 512 current: 90
self.HandsColor = 0 #: 3; // max: 8 current: 8
self.FeetModel = 0 #: 9; // max: 512 current: 94
self.FeetColor = 0 #: 3; // max: 8 current: 8
self.RTrail = 0 #: 4;
self.LTrail = 0 #: 3;
self.NotUsed = 0 # 17 : # not used -> just to complete 64 bit
def read(self, msgin):
@ -1484,21 +1507,21 @@ class SPropVisualB():
class SPropVisualC():
def __init__(self):
self.MorphTarget1 = 0 # : 3; // max: 8 current: 8
self.MorphTarget2 = 0 # : 3; // max: 8 current: 8
self.MorphTarget3 = 0 # : 3; // max: 8 current: 8
self.MorphTarget4 = 0 # : 3; // max: 8 current: 8
self.MorphTarget5 = 0 # : 3; // max: 8 current: 8
self.MorphTarget6 = 0 # : 3; // max: 8 current: 8
self.MorphTarget7 = 0 # : 3; // max: 8 current: 8
self.MorphTarget8 = 0 # : 3; // max: 8 current: 8
self.EyesColor = 0 # : 3; // max: 8 current: 8
self.Tattoo = 0 # : 7; // max: 128 current: 64
self.CharacterHeight = 0 # : 4; // max: 16 current: 16
self.TorsoWidth = 0 # : 4; // max: 16 current: 16
self.ArmsWidth = 0 # : 4; // max: 16 current: 16
self.LegsWidth = 0 # : 4; // max: 16 current: 16
self.BreastSize = 0 # : 4; // max: 16 current: 16
self.MorphTarget1 = 0 # : 3; // max: 8 current: 8
self.MorphTarget2 = 0 # : 3; // max: 8 current: 8
self.MorphTarget3 = 0 # : 3; // max: 8 current: 8
self.MorphTarget4 = 0 # : 3; // max: 8 current: 8
self.MorphTarget5 = 0 # : 3; // max: 8 current: 8
self.MorphTarget6 = 0 # : 3; // max: 8 current: 8
self.MorphTarget7 = 0 # : 3; // max: 8 current: 8
self.MorphTarget8 = 0 # : 3; // max: 8 current: 8
self.EyesColor = 0 # : 3; // max: 8 current: 8
self.Tattoo = 0 # : 7; // max: 128 current: 64
self.CharacterHeight = 0 # : 4; // max: 16 current: 16
self.TorsoWidth = 0 # : 4; // max: 16 current: 16
self.ArmsWidth = 0 # : 4; // max: 16 current: 16
self.LegsWidth = 0 # : 4; // max: 16 current: 16
self.BreastSize = 0 # : 4; // max: 16 current: 16
self.NotUsed = 0 # 10 : # not used -> just to complete 64 bit
def read(self, msgin):
self.MorphTarget1 = msgin.readSerial(3, 'MorphTarget1')
@ -1555,11 +1578,37 @@ class CCharacterSummary():
self.HasEditSession = msgin.readBool('HasEditSession')
self.InNewbieland = msgin.readBool('InNewbieland')
# f.serial (CharacterSlot);
# f.serial (InRingSession);
# f.serial (HasEditSession);
# if (serialNB)
# f.serial (InNewbieland);
class CSessionId():
def __init__(self):
self.id = 0
def read(self, msgin):
self.id = msgin.readUint32('id')
class CMainlandSummary():
def __init__(self):
self.Id = CSessionId()
self.Name = ""
self.Description = ""
self.LanguageCode = ""
self.Online = False
def read(self, msgin):
'''
khanat-opennel-code/code/ryzom/common/src/game_share/mainland_summary.h # void serial(NLMISC::IStream &f)
'''
self.Id.read(msgin)
self.Name = msgin.readUString('Name')
self.Description = msgin.readUString('Description')
self.LanguageCode = msgin.readString('LanguageCode')
self.Online = msgin.readBool('Online')
class CShardName():
def __init__(self, SessionId, DisplayName, ShortName):
self.SessionId = SessionId
self.DisplayName = DisplayName
self.ShortName = ShortName
class World():
@ -1570,6 +1619,10 @@ class World():
self.ServerPeopleActive = 255
self.ServerCareerActive = 255
self.CharacterSummaries = []
self.Mainlands = []
self.CShardNames = []
self.UserPrivileges = ''
self.FreeTrial = False
def addGenericMultiPartTemp(self, id):
self.GenericMultiPartTemp.setdefault(id, CGenericMultiPartTemp(self.log))
@ -2263,6 +2316,20 @@ class DecodeImpulse():
self.GenericMsgHeaderMngr = {}
self.initializeNetwork()
self.world = world
def updatePatcherPriorityBasedOnCharacters(self):
self.log.debug('Load character')
hasMainlandChar = False
for ele in self.world.CharacterSummaries:
if ele.Name == "":
continue
if not ele.InNewbieland:
hasMainlandChar = True
break
# requestDownloadThreadPriority(hasMainlandChar ? BGDownloader::ThreadPriority_Normal : BGDownloader::ThreadPriority_Low, false);
# khanat-opennel-code/code/ryzom/client/src/bg_downloader_access.cpp # void CBGDownloaderAccess::requestDownloadThreadPriority(BGDownloader::TThreadPriority newPriority, bool freezeUI)
msgout = BitStream()
self.log.debug("TODO")
def impulseDatabaseUpdatePlayer(self, msgin):
self.log.debug("TODO:%s" % msgin)
@ -2284,20 +2351,38 @@ class DecodeImpulse():
'''
self.world.ServerPeopleActive = msgin.readUint8('ServerPeopleActive')
self.world.ServerCareerActive = msgin.readUint8('ServerCareerActive')
# impulse.serialCont (CharacterSummaries);
self.world.CharacterSummaries = []
size = msgin.readUint32('CharacterSummaries:len')
for _ in range(0, size):
tmp = CCharacterSummary()
tmp.read(msgin)
self.world.CharacterSummaries.append(tmp)
#_, CharacterSummaries = msgin.readCont('CharacterSummaries')
_, shardNames = msgin.readCont('shardNames')
# impulse.serialCont (shardNames);
size = msgin.readUint32('shardNames:len')
shardNames = []
for i in range(0, size):
shardNames.append(msgin.readString('shardNames_' + str(i)))
# CShardNames::getInstance().loadShardNames(shardNames);
# int(shardNames[i*3+0]) = SessionId / shardNames[i*3+1] = DisplayName / shardNames[i*3+2] = ShortName
for i in range(0, size // 3):
tmp = CShardName(int(shardNames[i*3+0]), shardNames[i*3+1], shardNames[i*3+2])
self.world.CShardNames.append(tmp)
#_, shardNames = msgin.readCont('shardNames')
# readPrivileges(impulse);
UserPrivileges = msgin.readString('UserPrivileges')
FreeTrial = msgin.readBool('FreeTrial')
_, Mainlands = msgin.readCont('Mainlands')
self.log.debug("Mesage UserChars: %s" % msgin.showAllData())
self.log.debug("TODO")
self.world.UserPrivileges = msgin.readString('UserPrivileges')
self.world.FreeTrial = msgin.readBool('FreeTrial')
self.world.FreeTrial = False # We read and ignore this param :)
# impulse.serialCont(Mainlands);
self.Mainlands = []
size = msgin.readUint32('Mainlands:len')
for _ in range(0, size):
tmp = CMainlandSummary()
tmp.read(msgin)
self.world.Mainlands.append(tmp)
self.updatePatcherPriorityBasedOnCharacters(); # Load player config from server to client
def impulseUserChar(self, msgin):
self.log.debug("TODO")