mirror of
https://port.numenaute.org/aleajactaest/clientbot.git
synced 2024-11-25 00:26:33 +00:00
adding select profile
This commit is contained in:
parent
2e521c0267
commit
733000a09c
1 changed files with 123 additions and 24 deletions
139
client.py
139
client.py
|
@ -49,6 +49,13 @@ import inspect
|
|||
|
||||
INVALID_SLOT = 0xff
|
||||
|
||||
def convertUStringToString(name):
|
||||
ret = ''
|
||||
for car in name:
|
||||
if ord(car) >= 32 and ord(car)<=127:
|
||||
ret += car
|
||||
return ret
|
||||
|
||||
class BitStream():
|
||||
def __init__(self):
|
||||
self._pos = 0
|
||||
|
@ -485,13 +492,13 @@ class BitStream():
|
|||
source.putRead(0)
|
||||
need = 8 - (self._pos % 8)
|
||||
if need != 8:
|
||||
self.internalSerial(source.readSerial(need), need, decode=False)
|
||||
self.internalSerial(source.readSerial(need, decode=False), need, decode=False)
|
||||
while source.needRead() >= 8:
|
||||
self.pushUint8(source.readSerial(8, False), decode=False)
|
||||
self.pushUint8(source.readSerial(8, decode=False), decode=False)
|
||||
|
||||
need = source.needRead()
|
||||
if need > 0:
|
||||
self.internalSerial(source.readSerial(need, False), need, decode=False)
|
||||
self.internalSerial(source.readSerial(need, decode=False), need, decode=False)
|
||||
|
||||
source.putRead(srcRead)
|
||||
p2 = self._pos
|
||||
|
@ -657,7 +664,7 @@ class BitStream():
|
|||
ret = BitStream()
|
||||
v1 = self._read
|
||||
for i in range(0, size):
|
||||
ret.pushUint8(self.readUint8('', decode=False))
|
||||
ret.pushUint8(self.readUint8('', decode=False), decode=False)
|
||||
v2 = self._read
|
||||
self._groupRead.append((v1, v2, name, 'StreamUint8', ''))
|
||||
return ret
|
||||
|
@ -1190,6 +1197,66 @@ class TType(IntEnum):
|
|||
NB_TYPE = 11
|
||||
|
||||
|
||||
class TState(IntEnum):
|
||||
# initial state
|
||||
st_start = 0
|
||||
# display login screen and options
|
||||
st_login = 1
|
||||
# auto login using cmd lien parameters (used with patch reboot)
|
||||
st_auto_login = 2
|
||||
# display the shard list
|
||||
st_shard_list = 3
|
||||
# lauch the configurator and close ryzom
|
||||
st_start_config = 4
|
||||
# run the scan data thread
|
||||
st_scan_data = 5
|
||||
# display the eula and wait for validation
|
||||
st_display_eula = 6
|
||||
# check the data to determine need for patch
|
||||
st_check_patch = 7
|
||||
# display the list of optional patch category for patching
|
||||
st_display_cat = 8
|
||||
# run the patch process and display progress
|
||||
st_patch = 9
|
||||
# terminate the client and quit
|
||||
st_close_client = 10
|
||||
# display the reboot screen and wait validation
|
||||
st_reboot_screen = 11
|
||||
# restart the client with login bypass params
|
||||
st_restart_client = 12
|
||||
# connect to the FS (start the 'in game' mode)
|
||||
st_connect = 13
|
||||
# show the outgame browser
|
||||
st_browser_screen = 14
|
||||
# ingame state
|
||||
st_ingame = 15
|
||||
# leave the current shard (the exit action progress, Far TP part 1.1; Server Hop part 1-2)
|
||||
st_leave_shard = 16
|
||||
# let the main loop finish the current frame and leave it (Far TP part 1.2)
|
||||
st_enter_far_tp_main_loop = 17
|
||||
# disconnect from the FS (Far TP part 2)
|
||||
st_disconnect = 18
|
||||
# connect to a new FS (Far TP & Server Hop part 3.1)
|
||||
st_reconnect_fs = 19
|
||||
# after reconnecting, bypass character selection ui & select the same character (Far TP & Server Hop part 3.2)
|
||||
st_reconnect_select_char = 20
|
||||
# after reconnecting and receiving ready, send ready (Far TP part 3.3)
|
||||
st_reconnect_ready = 21
|
||||
# between global menu exit and sending ready (Server Hop part 3.3)
|
||||
st_exit_global_menu = 22
|
||||
# error while reconnecting
|
||||
st_reconnect_error = 23
|
||||
# Rate a ring session. should pop a web windows pointing the rate session page
|
||||
st_rate_session = 24
|
||||
# create account
|
||||
st_create_account = 25
|
||||
# try to login with alternate login system
|
||||
st_alt_login = 26
|
||||
# pseudo state to leave the state machine
|
||||
st_end = 27
|
||||
st_unknown = 28
|
||||
|
||||
|
||||
class EGender(IntEnum):
|
||||
male = 0
|
||||
female = 1
|
||||
|
@ -2112,7 +2179,7 @@ class CCharacterSummary():
|
|||
'''
|
||||
self.version = msgin.readUint8('version')
|
||||
self.Mainland = msgin.readUint32('Mainland')
|
||||
self.Name = msgin.readUString('Name')
|
||||
self.Name = convertUStringToString(msgin.readUString('Name'))
|
||||
self.People = msgin.readSint32('People')
|
||||
self.Location = msgin.readUint32('Location')
|
||||
self.sPropVisualA.read(msgin)
|
||||
|
@ -2171,7 +2238,7 @@ def CodeMsgXml(msgXml, key):
|
|||
for ele in head:
|
||||
if ele.attrib['name'] == id:
|
||||
found = True
|
||||
ret.append([nbBit, i])
|
||||
ret.append([nbBit, i, id])
|
||||
break
|
||||
i +=1
|
||||
if not found:
|
||||
|
@ -2237,6 +2304,8 @@ class World():
|
|||
self.UserPrivileges = ''
|
||||
self.FreeTrial = False
|
||||
self.HeadName = HeadName
|
||||
self.CurrentState = TState.st_unknown
|
||||
self.UseFemaleTitles = False
|
||||
|
||||
def CreaterCharacter(self, msgXml):
|
||||
'''
|
||||
|
@ -2295,8 +2364,8 @@ class World():
|
|||
msgout = BitStream()
|
||||
# GenericMsgHeaderMngr.pushNameToStream("CONNECTION:CREATE_CHAR", out))
|
||||
ref = CodeMsgXml(msgXml, 'CONNECTION:CREATE_CHAR')
|
||||
for size, value in ref:
|
||||
msgout.internalSerial(value, size)
|
||||
for size, value, id in ref:
|
||||
msgout.internalSerial(value, size, typeName=id)
|
||||
# khanat-opennel-code/code/ryzom/common/src/game_share/msg_client_server.h # void serialBitMemStream(NLMISC::CBitMemStream &f)
|
||||
msgout.pushUint8(Slot)
|
||||
msgout.pushUint32(SheetId)
|
||||
|
@ -2356,6 +2425,18 @@ class World():
|
|||
#msgout = CMessage("CREATE_CHAR")
|
||||
#msgout.serial(uid, bms)
|
||||
|
||||
def SelectChar(self, msgXml, PlayerSelectedSlot):
|
||||
'''
|
||||
khanat-opennel-code/code/ryzom/client/src/far_tp.cpp # void CFarTP::selectCharAndEnter()
|
||||
'''
|
||||
msgout = BitStream()
|
||||
ref = CodeMsgXml(msgXml, 'CONNECTION:SELECT_CHAR')
|
||||
for size, value, id in ref:
|
||||
msgout.internalSerial(value, size, typeName=id)
|
||||
msgout.pushUint8(PlayerSelectedSlot)
|
||||
return msgout
|
||||
|
||||
|
||||
class CPersistentDataRecord:
|
||||
def __init__(self, log):
|
||||
self.log = log
|
||||
|
@ -3197,6 +3278,10 @@ class DecodeImpulse():
|
|||
|
||||
|
||||
def impulsePhraseSend(self, msgin):
|
||||
dynId = msgin.readUint32('dynId')
|
||||
self.log.debug("dynId:%d" % dynId)
|
||||
StringId = msgin.readUint32('StringId')
|
||||
self.log.debug("dynId:%d StringId:%s" % (dynId, StringId))
|
||||
self.log.debug("TODO")
|
||||
|
||||
def impulseStringResp(self, msgin):
|
||||
|
@ -3240,8 +3325,7 @@ class DecodeImpulse():
|
|||
def impulseGuildUpdatePlayerTitle(self, msgin):
|
||||
self.log.debug("TODO")
|
||||
def impulseGuildUseFemaleTitles(self, msgin):
|
||||
self.log.debug("TODO")
|
||||
|
||||
self.world.UseFemaleTitles = msgin.readBool('UseFemaleTitles')
|
||||
|
||||
def impulseCloseTempInv(self, msgin):
|
||||
self.log.debug("TODO")
|
||||
|
@ -3514,11 +3598,11 @@ class DecodeImpulse():
|
|||
return ret
|
||||
|
||||
def execute(self, msgin):
|
||||
self.log.debug("execute")
|
||||
head = self.msgXml
|
||||
listpath = []
|
||||
while True:
|
||||
nbBit = getPowerOf2(len(head))
|
||||
# def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False):
|
||||
id = msgin.readSerial(nbBit, name='MsgXML', typeName='Number', emulate=True)
|
||||
|
||||
ele = head[id]
|
||||
|
@ -3527,6 +3611,7 @@ class DecodeImpulse():
|
|||
fullname = ':'.join(listpath)
|
||||
|
||||
id = msgin.readSerial(nbBit, name='MsgXML', typeName='XML <' + name + '>')
|
||||
self.log.debug(fullname)
|
||||
if fullname in self.GenericMsgHeaderMngr:
|
||||
self.log.debug("Found : %s" % fullname)
|
||||
self.GenericMsgHeaderMngr[fullname](msgin)
|
||||
|
@ -3688,7 +3773,7 @@ class CActionGeneric(CAction):
|
|||
decodeImpulse.execute(self._Message)
|
||||
|
||||
def __str__(self):
|
||||
return "CActionGeneric" + super().__str__() + "[" + self._Message.showAllData() + ']'
|
||||
return "CActionGeneric" + super().__str__() + "[read:" + self._Message.showAllData() + '/write:' + self._Message.showAllDataWrite() + ']'
|
||||
|
||||
def size(self):
|
||||
size = super().size()
|
||||
|
@ -3762,7 +3847,7 @@ class CActionGenericMultiPart(CAction):
|
|||
decodeImpulse.GenericMultiPartTemp.setGenericMultiPartTemp(self.Number, self.Part, self.NbBlock, self.PartCont, decodeImpulse)
|
||||
|
||||
def __str__(self):
|
||||
return "CActionGenericMultiPart" + super().__str__() + "[" + str(self.Number) + ',' + str(self.Part) + ',' + str(self.NbBlock) + ',' + self.PartCont.showAllData() + ']'
|
||||
return "CActionGenericMultiPart" + super().__str__() + "[" + str(self.Number) + ',' + str(self.Part) + ',' + str(self.NbBlock) + ',read:' + self.PartCont.showAllData() + ',write:' + self.PartCont.showAllDataWrite() + ']'
|
||||
|
||||
def size(self):
|
||||
size = super().size()
|
||||
|
@ -3879,7 +3964,7 @@ class CActionBlock:
|
|||
self.Cycle = 0
|
||||
self.FirstPacket = 0
|
||||
self.Actions = []
|
||||
self.Sucess = True
|
||||
self.Success = True
|
||||
|
||||
def serial(self, msgout, actionFactory):
|
||||
msgout.pushUint32(self.Cycle)
|
||||
|
@ -3908,6 +3993,8 @@ class CActionBlock:
|
|||
|
||||
def push_back(self, action):
|
||||
self.Actions.append(action)
|
||||
def __str__(self):
|
||||
return "CActionBlock [Cycle:" + str(self.Cycle) + ', FirstPacket:' + str(self.FirstPacket) + ', Data:' + ', '.join([ str(x) for x in self.Actions]) + "]"
|
||||
|
||||
|
||||
class CImpulseDecoder:
|
||||
|
@ -4040,6 +4127,7 @@ class ClientNetworkConnection:
|
|||
self._LastSendTime = 0
|
||||
self._ImpulseMultiPartNumber = 0
|
||||
self.clientTick = 0
|
||||
self.stepAction = 0
|
||||
|
||||
def signal_exit(self, sig, frame):
|
||||
self.log.warning("Receive signal to quit program")
|
||||
|
@ -4307,8 +4395,8 @@ class ClientNetworkConnection:
|
|||
self.log.debug("Message not read (%d) %s" % (msgin.needRead(), msgin.showLastData() ))
|
||||
|
||||
# remove all old actions that are acked
|
||||
while self._Actions and self._Actions[0].FirstPacket != 0 and self._Actions[0].FirstPacket :
|
||||
self.log.debug("remove old action")
|
||||
while self._Actions and self._Actions[0].FirstPacket != 0 and self._Actions[0].FirstPacket < self._LastReceivedAck:
|
||||
self.log.debug("remove old action [%d/%d] : %s" % (self._Actions[0].FirstPacket, self._LastReceivedAck, self._Actions[0]))
|
||||
self._Actions.pop(0)
|
||||
|
||||
self._CurrentServerTick = self._CurrentReceivedNumber * 2 + self._Synchronize
|
||||
|
@ -4657,6 +4745,7 @@ class ClientNetworkConnection:
|
|||
cycle = self._CurrentServerTick
|
||||
bitSize = 32*8 # block size is 32 (cycle) + 8 (number of actions
|
||||
if len(self._Actions) == 0 or self._Actions[-1].Cycle != 0:
|
||||
self.log.debug("No Action")
|
||||
pass
|
||||
else:
|
||||
block = self._Actions[-1]
|
||||
|
@ -4682,14 +4771,24 @@ class ClientNetworkConnection:
|
|||
# cmd = self.world.Commands.pop(0)
|
||||
|
||||
def analyze(self):
|
||||
if self.world.CurrentState == TState.st_connect:
|
||||
if self.world.CShardNames != []:
|
||||
if self.world.CharacterSummaries != [] and self.clientTick > 5:
|
||||
if self.stepAction == 0 and self.world.CharacterSummaries != [] and self.clientTick > 0:
|
||||
if self.world.CharacterSummaries[0].People == TPeople.Unknown:
|
||||
bms = self.world.CreaterCharacter(self.msgXml)
|
||||
self.push(bms)
|
||||
|
||||
self.stepAction = 1
|
||||
else:
|
||||
self.stepAction = 1
|
||||
elif self.stepAction == 1 and self.world.CharacterSummaries != []:
|
||||
if self.world.CharacterSummaries[0].People != TPeople.Unknown:
|
||||
self.log.info("Account defined %s" % self.world.CharacterSummaries[0].Name)
|
||||
bms = self.world.SelectChar(self.msgXml, 0)
|
||||
self.push(bms)
|
||||
self.stepAction = 2
|
||||
|
||||
def EmulateFirst(self, msgRawXml, databaseRawXml):
|
||||
self.world.CurrentState = TState.st_start
|
||||
self.msgXml = ET.fromstring(msgRawXml)
|
||||
#ET.dump(msgXml)
|
||||
self.databaseXml = ET.fromstring(databaseRawXml)
|
||||
|
@ -4701,16 +4800,16 @@ class ClientNetworkConnection:
|
|||
self.decodeImpulse.loadMsg(self.msgXml)
|
||||
self.decodeImpulse.loadDatabase(self.databaseXml)
|
||||
|
||||
#CodeMsgXml(self.msgXml, 'CONNECTION:CREATE_CHAR')
|
||||
self.connect()
|
||||
self.log.info("Client Login")
|
||||
self.sendSystemLogin()
|
||||
self.world.CurrentState = TState.st_connect
|
||||
|
||||
self.log.info("Receive Message")
|
||||
self.clientTick = 0
|
||||
for _ in range(0, 50):
|
||||
#while True:
|
||||
self.log.debug("%s [%s: %d] %s" % ("*" * 40, "Loop", self.clientTick,"*" * 40))
|
||||
self.log.debug("%s [%s: %d / %d] %s" % ("*" * 40, "Loop", self.clientTick, self.stepAction, "*" * 40))
|
||||
self.update()
|
||||
self.analyze()
|
||||
self.send()
|
||||
|
|
Loading…
Reference in a new issue