Commit 5c506cfa authored by aleajactaest's avatar aleajactaest
Browse files

update spykhanat.py (it can generate yaml file with detail message decoded)

parent 390c448b
*.pcap
*.yaml
*.yml
*.log
*.err
......@@ -117,7 +117,7 @@ class ClientKhanat:
'Referer': 'http://' + self.khanat_host+':'+ str(self.khanat_port_login) + '/ams/index.php?page=register',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20100101 Firefox/6.0',
'Content-Type': 'application/x-www-form-urlencoded'}
'': 'application/x-www-form-urlencoded'}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
params = urllib.parse.urlencode({'Username': self.login, 'Password': self.password, 'ConfirmPass': self.password, 'Email': self.login+'@khaganat.net', 'TaC': 'on', 'function': 'add_user'})
......
This diff is collapsed.
......@@ -23,6 +23,7 @@ from ctypes import *
import sys
import inspect
import copy
import struct
LOGGER='BitStream'
......
......@@ -22,6 +22,7 @@
import logging
from tools import TPropIndex
from tools import TPVPMode
from tools import Enum
LOGGER='CActionFactory'
INVALID_SLOT = 0xff
......@@ -35,9 +36,23 @@ class CAction:
self.Timeout = 0
self.GameCycle = 0
self.world = world
self.Reference = []
self.Name = ""
def set_name(self, name):
self.Name = name
def get_name(self):
return self.Name
def add_reference(self, ref):
self.Reference.append(ref)
def get_reference(self):
return self.Reference
def get_parameter(self):
return {"Type": "CAction", "Code": self.Code, "Slot": self.Slot, "PropertyCode": self.PropertyCode, "GameCycle": self.GameCycle}
return {"Type": "CAction", "Code": self.Code, "Slot": self.Slot, "PropertyCode": self.PropertyCode, "GameCycle": self.GameCycle, "Reference": self.Reference}
def unpack(self, message):
raise RuntimeError
......@@ -216,7 +231,11 @@ class CActionGeneric(CAction):
def get_parameter(self):
ret = super().get_parameter()
ret["Type"] = "CActionGeneric"
ret["Message"] = self._Message.showAllData()
if not self._Message.checkOnlyZeroAtEnd():
ret["state"] = "message partially decoded"
else:
ret["state"] = 'message decoded'
ret["Message"] = self._Message.extractAllData()
return ret
def set(self, message):
......@@ -239,6 +258,11 @@ class CActionGeneric(CAction):
decodeImpulse.execute(self._Message, world)
self.decoded = True
def decodeImpulseSimple(self, decodeImpulseSimple, world, cGenericMultiPartTemp, Reference = None, Name = ""):
ret = decodeImpulseSimple.execute(self._Message, world, Reference, Name)
self.decoded = True
return ret
def __str__(self):
if self.decoded:
return "CActionGeneric" + super().__str__() + ' => ' + self._Message.showAllData()
......@@ -265,6 +289,7 @@ class CActionGenericMultiPart(CAction):
def get_parameter(self):
ret = super().get_parameter()
ret["Name"] = self.Name
ret["Type"] = "CActionGenericMultiPart"
ret["Number"] = "%d" % self.Number
ret["Part"] = "%d" % self.Part
......@@ -315,13 +340,21 @@ class CActionGenericMultiPart(CAction):
self.Part = 0
self.NbBlock = 0
def genericAction(self, decodeImpulse, world, cGenericMultiPartTemp):
def genericAction(self, decodeImpulse, world, cGenericMultiPartTemp, Reference, Name):
'''
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::genericAction (CActionGenericMultiPart *agmp)
'''
logging.getLogger(LOGGER).debug("Number:%d Part:%d NbBlock:%d" % (self.Number, self.Part, self.NbBlock))
cGenericMultiPartTemp.addGenericMultiPartTemp(self.Number)
cGenericMultiPartTemp.setGenericMultiPartTemp(self.Number, self.Part, self.NbBlock, self.PartCont, decodeImpulse, world)
cGenericMultiPartTemp.setGenericMultiPartTemp(self.Number, self.Part, self.NbBlock, self.PartCont, decodeImpulse, world, Reference, Name)
def decodeImpulseSimple(self, decodeImpulseSimple, world, cGenericMultiPartTemp, Reference = None, Name = ""):
logging.getLogger(LOGGER).debug("Number:%d Part:%d NbBlock:%d" % (self.Number, self.Part, self.NbBlock))
cGenericMultiPartTemp.addGenericMultiPartTemp(self.Number)
ret = cGenericMultiPartTemp.setGenericMultiPartTemp(self.Number, self.Part, self.NbBlock, self.PartCont, decodeImpulseSimple, world, Reference, Name)
#ret = decodeImpulseSimple.execute(self._Message, world)
self.decoded = True
return ret
def __str__(self):
return "CActionGenericMultiPart" + super().__str__() + "[" + str(self.Number) + ',' + str(self.Part) + ',' + str(self.NbBlock) + ',read:' + self.PartCont.showAllData() + ',write:' + self.PartCont.showAllDataWrite() + ']'
......@@ -445,3 +478,27 @@ class CActionBlock:
def __str__(self):
return "CActionBlock [Cycle:" + str(self.Cycle) + ', FirstPacket:' + str(self.FirstPacket) + ', Data:' + ', '.join([ str(x) for x in self.Actions]) + "]"
class CActionFake():
def __init__(self, Type, msgin, addon = None, Reference=None, Name=""):
self.Type = Type
self.Code = Enum.TActionCode.ACTION_NONE
self._Message = msgin
self.addon = addon
self.Reference = [ Reference ]
self.Name = Name
def get_name(self):
return self.Name
def get_parameter(self):
ret = {"Type": "CActionFake.%s" % self.Type}
if not self._Message.checkOnlyZeroAtEnd():
ret["state"] = "message partially decoded"
else:
ret["state"] = 'message decoded'
if self.addon:
for key in self.addon:
ret[key] = str(self.addon[key])
ret["Reference"] = self.Reference
ret["Message"] = self._Message.extractAllData()
return ret
......@@ -91,7 +91,7 @@ class CActionFactory:
action.Slot = slot
return action
def unpack(self, msgin):
def unpack(self, msgin, Reference = None, Name = None):
'''
khanat-opennel-code/code/ryzom/common/src/game_share/action_factory.cpp : CAction *CActionFactory::unpack (NLMISC::CBitMemStream &message, NLMISC::TGameCycle /* currentCycle */ )
'''
......@@ -113,6 +113,10 @@ class CActionFactory:
else:
log = logging.getLogger('myLogger')
log.warning('Unpacking an action with unknown code, skip it (%u)' % code)
if Reference:
action.add_reference(Reference)
if Name:
action.set_name(Name)
return action
......@@ -32,12 +32,19 @@ class CGenericMultiPartTemp():
self.BlockReceived = []
self.MsgDecoded = None
self.FirstRead = False
self.Reference = []
self.Name = None
def set(self, Number, Part, NbBlock, PartCont, decodeImpulse, world):
def set(self, Number, Part, NbBlock, PartCont, decodeImpulse, world, Reference = None, Name = None):
'''
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::CGenericMultiPartTemp::set (CActionGenericMultiPart *agmp, CNetworkConnection *parent)
'''
logging.getLogger(LOGGER).debug("set Number:%d Part:%d NbBlock:%d" % (Number, Part, NbBlock))
ret = None
if not self.Name:
self.Name = Name
if Reference:
self.Reference.append(Reference)
if self.NbBlock == 0xFFFFFFFF:
# Initialize
self.NbBlock = NbBlock
......@@ -49,7 +56,7 @@ class CGenericMultiPartTemp():
while len(self.BlockReceived) < NbBlock:
self.BlockReceived.append(False)
if self.BlockReceived[Part]:
logging.getLogger(LOGGER).warning('This part is already received, discard it %d' % Part)
logging.getLogger(LOGGER).debug('This part is already received, discard it %d' % Part)
return
self.Temp[Part] = PartCont
self.BlockReceived[Part] = True
......@@ -64,11 +71,12 @@ class CGenericMultiPartTemp():
self.NbBlock == 0xFFFFFFFF
for data in self.Temp:
bms.pushBitStream(data)
decodeImpulse.execute(bms, world)
ret = decodeImpulse.execute(bms, world)
logging.getLogger(LOGGER).debug("CGenericMultiPartTemp : data : %s" % bms.showAllData())
self.MsgDecoded = bms
else:
logging.getLogger(LOGGER).debug("CGenericMultiPartTemp : Wait other block")
return ret
def isAvailable(self):
if self.MsgDecoded and not self.FirstRead:
......@@ -87,5 +95,5 @@ class GenericMultiPartTemp():
def addGenericMultiPartTemp(self, Number):
self.data.setdefault(Number, CGenericMultiPartTemp())
def setGenericMultiPartTemp(self, Number, Part, NbBlock, PartCont, decodeImpulse, world):
self.data[Number].set(Number, Part, NbBlock, PartCont, decodeImpulse, world)
def setGenericMultiPartTemp(self, Number, Part, NbBlock, PartCont, decodeImpulse, world, Reference = None, Name = None):
self.data[Number].set(Number, Part, NbBlock, PartCont, decodeImpulse, world, Reference, Name)
......@@ -38,7 +38,7 @@ class CImpulseDecoder:
def decode(self, msgin, receivedPacket, receivedAck, nextSentPacket):
'''
khanat-opennel-code/code/ryzom/client/src/impulse_decoder.cpp:38 oid CImpulseDecoder::decode(CBitMemStream &inbox, TPacketNumber receivedPacket, TPacketNumber receivedAck, TPacketNumber nextSentPacket, vector<CLFECOMMON::CAction *> &actions)
khanat-opennel-code/code/ryzom/client/src/impulse_decoder.cpp:38 void CImpulseDecoder::decode(CBitMemStream &inbox, TPacketNumber receivedPacket, TPacketNumber receivedAck, TPacketNumber nextSentPacket, vector<CLFECOMMON::CAction *> &actions)
'''
logging.getLogger(LOGGER).debug("*" * 80)
logging.getLogger(LOGGER).debug("receivedPacket:%d receivedAck:%d nextSentPacket:%d" %(receivedPacket, receivedAck, nextSentPacket))
......
......@@ -351,6 +351,11 @@ class DecodeImpulse():
def impulseDatabaseInitPlayer(self, msgin, world):
logging.getLogger(LOGGER).debug("TODO")
def impulseSetConnectionAskName(self, msgin, world):
# _ = msgin.readUtf8String('Name')
_ = msgin.readUString('Name')
_ = msgin.readUint32('HomeSessionId')
def initializeNetwork(self):
self.GenericMsgHeaderMngr.setdefault('DB_UPD_PLR', self.impulseDatabaseUpdatePlayer)
self.GenericMsgHeaderMngr.setdefault('DB_INIT:PLR', self.impulseDatabaseInitPlayer)
......@@ -493,6 +498,9 @@ class DecodeImpulse():
self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SVR_EVENT_MIS_AVL", self.impulseServerEventForMissionAvailability )
self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SET_TIMER", self.impulseSetNpcIconTimer )
# Send by client
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:ASK_NAME", self.impulseSetConnectionAskName )
def sizeElement(self, keys = None):
head = self.msgXml
if not keys:
......@@ -540,6 +548,7 @@ class DecodeImpulse():
nbBit = getPowerOf2.getPowerOf2(len(head))
id = msgin.readSerial(nbBit, name='MsgXML', typeName='Number', emulate=True)
logging.getLogger(LOGGER).debug("XML DECODE : %3d -> %s" % (nbBit, ':'.join(listpath)) )
ele = head[id]
name = ele.attrib['name']
listpath.append(name)
......
......@@ -539,6 +539,8 @@ class TActionCode(IntEnum):
ACTION_LOGIN_CODE = 13
ACTION_TARGET_SLOT_CODE = 40
ACTION_DUMMY_CODE = 99
ACTION_NONE = 999
class Card(IntEnum):
BEGIN_TOKEN = 0
......@@ -550,6 +552,7 @@ class Card(IntEnum):
FLAG_TOKEN = 6
EXTEND_TOKEN = 7
class TType(IntEnum):
STRUCT_BEGIN = 0
STRUCT_END = 1
......@@ -563,3 +566,14 @@ class TType(IntEnum):
FLOAT64 = 9
EXTEND_TYPE = 10
NB_TYPE = 11
class NPC_ICON(IntEnum): # TNPCMissionGiverState
AwaitingFirstData = 0
NotAMissionGiver = 1
ListHasOutOfReachMissions = 2
ListHasAlreadyTakenMissions = 3
ListHasAvailableMission = 4
AutoHasUnavailableMissions = 5
AutoHasAvailableMission = 6
NbMissionGiverStates = 7
#!/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
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")
class ImpulseBotchatSetFilters(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('qualityMin', msgin.readUint32('qualityMin'))
self.param.setdefault('qualityMax', msgin.readUint32('qualityMax'))
self.param.setdefault('priceMin', msgin.readUint32('priceMin'))
self.param.setdefault('priceMax', msgin.readUint32('priceMax'))
self.param.setdefault('classMin', msgin.readUint8('classMin'))
self.param.setdefault('classMax', msgin.readUint8('classMax'))
self.param.setdefault('itemPart', msgin.readUint8('itemPart'))
self.param.setdefault('itemType', msgin.readUint8('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.param.setdefault('Name', msgin.readUString('Name'))
self.param.setdefault('HomeSessionId', msgin.readUint32('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.param.setdefault('Slot', msgin.readUint8('Slot'))
self.param.setdefault('SheetId', msgin.readUint32('SheetId'))
self.param.setdefault('CSessionId', msgin.readUint32('CSessionId'))
self.param.setdefault('name', msgin.readUString('name'))
self.param.setdefault('People', msgin.readUint8('People'))
self.param.setdefault('Sex', msgin.readUint8('Sex'))
self.param.setdefault('NbPointFighter', msgin.readUint8('NbPointFighter'))
self.param.setdefault('NbPointCaster', msgin.readUint8('NbPointCaster'))
self.param.setdefault('NbPointCrafter', msgin.readUint8('NbPointCrafter'))
self.param.setdefault('NbPointHarvester', msgin.readUint8('NbPointHarvester'))
self.param.setdefault('StartPoint', msgin.readSint32('StartPoint'))
self.param.setdefault('HairType', msgin.readSint8('HairType'))
self.param.setdefault('HairColor', msgin.readSint8('HairColor'))
self.param.setdefault('GabaritHeight', msgin.readSint8('GabaritHeight'))
self.param.setdefault('GabaritTorsoWidth', msgin.readSint8('GabaritTorsoWidth'))
self.param.setdefault('GabaritArmsWidth', msgin.readSint8('GabaritArmsWidth'))
self.param.setdefault('GabaritLegsWidth', msgin.readSint8('GabaritLegsWidth'))
self.param.setdefault('GabaritBreastSize', msgin.readSint8('GabaritBreastSize'))
self.param.setdefault('MorphTarget1', msgin.readSint8('MorphTarget1'))
self.param.setdefault('MorphTarget2', msgin.readSint8('MorphTarget2'))
self.param.setdefault('MorphTarget3', msgin.readSint8('MorphTarget3'))
self.param.setdefault('MorphTarget4', msgin.readSint8('MorphTarget4'))
self.param.setdefault('MorphTarget5', msgin.readSint8('MorphTarget5'))
self.param.setdefault('MorphTarget6', msgin.readSint8('MorphTarget6'))
self.param.setdefault('MorphTarget7', msgin.readSint8('MorphTarget7'))
self.param.setdefault('MorphTarget8', msgin.readSint8('MorphTarget8'))
self.param.setdefault('EyesColor', msgin.readSint8('EyesColor'))
self.param.setdefault('Tattoo', msgin.readSint8('Tattoo'))
self.param.setdefault('JacketColor', msgin.readSint8('JacketColor'))
self.param.setdefault('TrousersColor', msgin.readSint8('TrousersColor'))
self.param.setdefault('HatColor', msgin.readSint8('HatColor'))
self.param.setdefault('ArmsColor', msgin.readSint8('ArmsColor'))
self.param.setdefault('HandsColor', msgin.readSint8('HandsColor'))
self.param.setdefault('FeetColor', msgin.readSint8('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.param.setdefault('LanguageCode', msgin.readString('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.param.setdefault('SelectCharMsg', msgin.readUint8('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.param.setdefault('X', msgin.readSint32('X'))
self.param.setdefault('Y', msgin.readSint32('Y'))
self.param.setdefault('Z', msgin.readSint32('Z'))
self.param.setdefault('Heading', msgin.readFloat('Heading'))
self.param.setdefault('season', msgin.readSerial(3, 'season'))
self.param.setdefault('userRole', msgin.readSerial(3, 'userRole'))
self.param.setdefault('highestMainlandSessionId', msgin.readUint32('highestMainlandSessionId'))
self.param.setdefault('firstConnectedTime', msgin.readUint32('firstConnectedTime'))
self.param.setdefault('playedTime', msgin.readUint32('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.param.setdefault('shardId', msgin.readUint32('shardId'))
self.param.setdefault('webHost', msgin.readString('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.param.setdefault('valide', msgin.readUint8('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.param.setdefault('localTime', msgin.readUint32('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.param.setdefault('UseFemaleTitles', msgin.readSerial(1, 'UseFemaleTitles'))
class ImpulseNpsIconSetDesc(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:20976 void CCharacter::sendNpcMissionGiverIconDesc( const std::vector<uint32>& npcKeys )
'''
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('nb8', msgin.readUint8('nb8'))
nb8 = self.param['nb8']
for i in range(0, nb8):
self.param.setdefault('%d:npcAlias' % nb8, msgin.readUint32('npcAlias'))
self.param.setdefault('%d:state' % nb8, msgin.readUint32('state'))
class ImpulsePhraseDownload(ImpulseBase):
def __init__(self):
super().__init__()
def readSerialPhrase(self, msgin, id):
self.param.setdefault(id, msgin.readUtf8String(id))
size = msgin.readSint32(id + ':len')
self.param.setdefault(id + ':len', size)
for i in range(0, size):
self.param.setdefault('%s:compBricks:%d' % (id, i), msgin.readUint16('%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 = msgin.readSint32(id + ':len')
self.param.setdefault(id + ':len', size)
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, '%d:Phrase' % i)
self.param.setdefault('%d:KnownSlot' % i, msgin.readUint16('%d:KnownSlot' % i))
self.param.setdefault('%d:PhraseSheetId:id' % i, msgin.readUint32('%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 = msgin.readSint32(id + ':len')
self.param.setdefault(id + ':len', size)
for i in range(0, size):
self.param.setdefault('%d:MemoryLineId' % i, msgin.readUint8('MemoryLineId'))
self.param.setdefault('%d:MemorySlotId' % i, msgin.readUint8('MemorySlotId'))
self.param.setdefault('%d:PhraseId' % i, msgin.readUint16('PhraseId'))
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):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('X', msgin.readSint32('X'))
self.param.setdefault('Y', msgin.readSint32('Y'))
self.param.setdefault('Z', msgin.readSint32('Z'))
self.param.setdefault('Heading', msgin.readFloat('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.param.setdefault('phraseId', msgin.readUint32('phraseId'))
class ImpulseSringManagerReloadCache(ImpulseBase):
def __init__(self):
super().__init__()