mirror of
https://port.numenaute.org/aleajactaest/clientbot.git
synced 2024-12-18 15:38:43 +00:00
decode some message server, and reoganize code
This commit is contained in:
parent
bc4a1cbd09
commit
4b37c73acb
1 changed files with 572 additions and 111 deletions
683
client.py
683
client.py
|
@ -45,6 +45,8 @@ import hashlib
|
|||
import time
|
||||
|
||||
|
||||
INVALID_SLOT = 0xff
|
||||
|
||||
class BitStream():
|
||||
def __init__(self):
|
||||
self._pos = 0
|
||||
|
@ -278,21 +280,7 @@ class BitStream():
|
|||
self._read = readBefore
|
||||
return ret
|
||||
|
||||
def getTextMD5(dataRawXml):
|
||||
log = logging.getLogger('myLogger')
|
||||
dataNew = ''
|
||||
for data in dataRawXml:
|
||||
if data != '\r': # '\015' ignore caractère \r\n =>
|
||||
dataNew += data
|
||||
else:
|
||||
log.debug("***** data:%d" % (ord(data)))
|
||||
m = hashlib.md5()
|
||||
m.update(dataNew.encode('utf-8'))
|
||||
#print(m.hexdigest())
|
||||
#print(m.digest())
|
||||
return m.digest()
|
||||
|
||||
def Test():
|
||||
def TestBitStream():
|
||||
a = BitStream()
|
||||
a.pushBool(True)
|
||||
a.pushBool(False)
|
||||
|
@ -349,6 +337,94 @@ def Test():
|
|||
print(b.readChar())
|
||||
print(b.readString())
|
||||
print(b.toBytes())
|
||||
NL_BITLEN = 32
|
||||
class CBitSet:
|
||||
def __init__(self):
|
||||
self.data = self.resize(1024)
|
||||
self.NumBits = 0
|
||||
self.MaskLast = 0
|
||||
|
||||
def resize(self, numBits):
|
||||
self.data = [ 0 for _ in range(0, (numBits +NL_BITLEN - 1) // NL_BITLEN) ]
|
||||
self.NumBits = numBits
|
||||
nLastBits = self.NumBits & (NL_BITLEN-1)
|
||||
if nLastBits == 0:
|
||||
self.MaskLast = ~0
|
||||
else:
|
||||
self.MaskLast = (1 << nLastBits)-1
|
||||
self.clearAll()
|
||||
|
||||
def clearData(self):
|
||||
self.data = []
|
||||
self.NumBits = 0
|
||||
self.MaskLast = 0
|
||||
|
||||
def clearAll(self):
|
||||
for i in range(0, len(self.data)):
|
||||
self.data[i] = 0
|
||||
|
||||
def set(self, bitNumber, value):
|
||||
mask = bitNumber & (NL_BITLEN-1)
|
||||
mask = 1 << mask
|
||||
if value:
|
||||
self.data[bitNumber >> 5] |= mask
|
||||
else:
|
||||
self.data[bitNumber >> 5] &= ~mask
|
||||
|
||||
def get(self, bitNumber):
|
||||
mask= bitNumber&(NL_BITLEN-1);
|
||||
mask= 1<<mask;
|
||||
return self.data[bitNumber >> 5] & mask != 0
|
||||
|
||||
def setBit(self, bitNumber):
|
||||
self.set(bitNumber, True)
|
||||
|
||||
def clearBit(self, bitNumber):
|
||||
self.set(bitNumber, False)
|
||||
|
||||
def __str__(self):
|
||||
return '.'.join([hex(x) for x in self.data])
|
||||
def writeSerial(self, msgout):
|
||||
# v = 0 # currentVersion
|
||||
# if v >= 0xff:
|
||||
# msgout.pushUint8(0xff)
|
||||
# msgout.pushUint8(v)
|
||||
# else:
|
||||
# msgout.pushUint8(v)
|
||||
msgout.pushUint8(0) # currentVersion =0
|
||||
msgout.pushUint32(self.NumBits)
|
||||
msgout.pushUint32(len(self.data)) # il est lié à 'self.NumBits' dommage que l'on envoie celui-la
|
||||
for x in self.data:
|
||||
msgout.pushUint32(x)
|
||||
|
||||
def TestCBitSet():
|
||||
cBitSet = CBitSet()
|
||||
cBitSet.resize(1024)
|
||||
cBitSet.set(1, True)
|
||||
cBitSet.set(3, True)
|
||||
cBitSet.set(2, False)
|
||||
cBitSet.set(13, True)
|
||||
cBitSet.set(128, True)
|
||||
cBitSet.set(1023, True)
|
||||
print(cBitSet)
|
||||
print(cBitSet.get(3))
|
||||
cBitSet.set(3, False)
|
||||
print(cBitSet)
|
||||
print(cBitSet.get(3))
|
||||
|
||||
def getTextMD5(dataRawXml):
|
||||
log = logging.getLogger('myLogger')
|
||||
dataNew = ''
|
||||
for data in dataRawXml:
|
||||
if data != '\r': # '\015' ignore caractère \r\n =>
|
||||
dataNew += data
|
||||
else:
|
||||
log.debug("***** data:%d" % (ord(data)))
|
||||
m = hashlib.md5()
|
||||
m.update(dataNew.encode('utf-8'))
|
||||
#print(m.hexdigest())
|
||||
#print(m.digest())
|
||||
return m.digest()
|
||||
|
||||
class CFileChild():
|
||||
def __init__(self, name, pos, size):
|
||||
|
@ -440,6 +516,30 @@ class TConnectionState(IntEnum):
|
|||
Disconnect = 8 # disconnect() called, or timeout, or connection closed by frontend
|
||||
Quit = 9 # quit() called
|
||||
|
||||
class TActionCode(IntEnum):
|
||||
ACTION_POSITION_CODE = 0
|
||||
ACTION_GENERIC_CODE = 1
|
||||
ACTION_GENERIC_MULTI_PART_CODE = 2
|
||||
ACTION_SINT64 = 3
|
||||
ACTION_SYNC_CODE = 10
|
||||
ACTION_DISCONNECTION_CODE = 11
|
||||
ACTION_ASSOCIATION_CODE = 12
|
||||
ACTION_LOGIN_CODE = 13
|
||||
ACTION_TARGET_SLOT_CODE = 40
|
||||
ACTION_DUMMY_CODE = 99
|
||||
|
||||
class CLFECOMMON(IntEnum):
|
||||
SYSTEM_LOGIN_CODE = 0
|
||||
SYSTEM_SYNC_CODE = 1
|
||||
SYSTEM_ACK_SYNC_CODE = 2
|
||||
SYSTEM_PROBE_CODE = 3
|
||||
SYSTEM_ACK_PROBE_CODE = 4
|
||||
SYSTEM_DISCONNECTION_CODE = 5
|
||||
SYSTEM_STALLED_CODE = 6
|
||||
SYSTEM_SERVER_DOWN_CODE = 7
|
||||
SYSTEM_QUIT_CODE = 8
|
||||
SYSTEM_ACK_QUIT_CODE = 9
|
||||
NumBitsInLongAck = 512
|
||||
|
||||
class Card(IntEnum):
|
||||
BEGIN_TOKEN = 0
|
||||
|
@ -546,37 +646,37 @@ class CArgV5(Union):
|
|||
("f64", c_double),
|
||||
("ex", CArgV4)]
|
||||
|
||||
# union
|
||||
# {
|
||||
# struct
|
||||
# {
|
||||
# uint32 i32_1;
|
||||
# uint32 i32_2;
|
||||
# } i;
|
||||
#
|
||||
# sint32 i32;
|
||||
# sint64 i64;
|
||||
# float f32;
|
||||
# double f64;
|
||||
#
|
||||
# struct
|
||||
# {
|
||||
# uint32 ExType;
|
||||
# union
|
||||
# {
|
||||
# struct
|
||||
# {
|
||||
# uint32 ex32_1;
|
||||
# uint32 ex32_2;
|
||||
# };
|
||||
#
|
||||
# uint32 ExData32;
|
||||
# uint64 ExData64;
|
||||
# } ex;
|
||||
# } ex;
|
||||
# } _Value;
|
||||
|
||||
class CArg:
|
||||
# union
|
||||
# {
|
||||
# struct
|
||||
# {
|
||||
# uint32 i32_1;
|
||||
# uint32 i32_2;
|
||||
# } i;
|
||||
#
|
||||
# sint32 i32;
|
||||
# sint64 i64;
|
||||
# float f32;
|
||||
# double f64;
|
||||
#
|
||||
# struct
|
||||
# {
|
||||
# uint32 ExType;
|
||||
# union
|
||||
# {
|
||||
# struct
|
||||
# {
|
||||
# uint32 ex32_1;
|
||||
# uint32 ex32_2;
|
||||
# };
|
||||
#
|
||||
# uint32 ExData32;
|
||||
# uint64 ExData64;
|
||||
# } ex;
|
||||
# } ex;
|
||||
# } _Value;
|
||||
|
||||
def __init__(self):
|
||||
self._value = CArgV5()
|
||||
self._value.ii64 = 0
|
||||
|
@ -1478,7 +1578,223 @@ class CPersistentDataRecord:
|
|||
break
|
||||
|
||||
|
||||
|
||||
class CAction:
|
||||
def __init__(self, slot=INVALID_SLOT, code=0):
|
||||
self.Code = code
|
||||
self.PropertyCode = code
|
||||
self.Slot = slot
|
||||
self._Priority = 1
|
||||
self.Timeout = 0
|
||||
self.GameCycle = 0
|
||||
|
||||
def unpack(self, message):
|
||||
raise RuntimeError
|
||||
|
||||
def pack(self, message):
|
||||
raise RuntimeError
|
||||
|
||||
def serialIn(self, msgin):
|
||||
raise RuntimeError
|
||||
|
||||
def serialOut(self, msgout):
|
||||
raise RuntimeError
|
||||
|
||||
def size(self):
|
||||
raise RuntimeError
|
||||
|
||||
def getMaxSizeInBit(self):
|
||||
raise RuntimeError
|
||||
|
||||
def setPriority(self, prio):
|
||||
raise RuntimeError
|
||||
|
||||
def priority(self):
|
||||
raise RuntimeError
|
||||
|
||||
def getValue(self):
|
||||
raise RuntimeError
|
||||
|
||||
def setValue(self, value):
|
||||
raise RuntimeError
|
||||
|
||||
def isContinuous(self):
|
||||
raise RuntimeError
|
||||
|
||||
def reset(self):
|
||||
raise RuntimeError
|
||||
|
||||
def __str__(self):
|
||||
return "[%d,%d]" % (self.Code , self.Slot)
|
||||
|
||||
class CActionPosition(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
|
||||
class CActionSync(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
|
||||
class CActionDisconnection(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
|
||||
class CActionAssociation(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
|
||||
class CActionDummy(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
|
||||
class CActionLogin(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
|
||||
class CActionTargetSlot(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
|
||||
class CActionGeneric(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
self._Message = None
|
||||
|
||||
def unpack(self, message):
|
||||
size = message.readUint32()
|
||||
self._Message = message.readArrayUint8(size)
|
||||
|
||||
class CActionGenericMultiPart(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
self.PartCont = []
|
||||
self.Number = 0
|
||||
self.Part = 0
|
||||
self.NbBlock = 0
|
||||
|
||||
def unpack(self, message):
|
||||
self.Number = message.readUint8()
|
||||
self.Part = message.readUint16()
|
||||
self.NbBlock = message.readUint16()
|
||||
|
||||
size = message.readUint32()
|
||||
self.PartCont = message.readArrayUint8(size)
|
||||
|
||||
class CActionSint64(CAction):
|
||||
def __init__(self, slot, code):
|
||||
super().__init__(slot, code)
|
||||
|
||||
class CActionFactory:
|
||||
def __init__(self):
|
||||
self.RegisteredAction = []
|
||||
|
||||
def create(self, slot, code):
|
||||
if code == TActionCode.ACTION_POSITION_CODE:
|
||||
return CActionPosition(slot, code)
|
||||
elif code == TActionCode.ACTION_GENERIC_CODE:
|
||||
return CActionGeneric(slot, code)
|
||||
elif code == TActionCode.ACTION_GENERIC_MULTI_PART_CODE:
|
||||
return CActionGenericMultiPart(slot, code)
|
||||
elif code == TActionCode.ACTION_SINT64:
|
||||
return CActionSint64(slot, code)
|
||||
elif code == TActionCode.ACTION_SYNC_CODE:
|
||||
return CActionSync(slot, code)
|
||||
elif code == TActionCode.ACTION_DISCONNECTION_CODE:
|
||||
return CActionDisconnection(slot, code)
|
||||
elif code == TActionCode.ACTION_ASSOCIATION_CODE:
|
||||
return CActionAssociation(slot, code)
|
||||
elif code == TActionCode.ACTION_LOGIN_CODE:
|
||||
return CActionLogin(slot, code)
|
||||
elif code == TActionCode.ACTION_TARGET_SLOT_CODE:
|
||||
return CActionTargetSlot(slot, code)
|
||||
elif code == TActionCode.ACTION_DUMMY_CODE:
|
||||
return CActionDummy(slot, code)
|
||||
else:
|
||||
log = logging.getLogger('myLogger')
|
||||
log.warning('create() try to create an unknown action (%u)' % code)
|
||||
raise RuntimeError
|
||||
|
||||
def unpack(self, msgin):
|
||||
'''
|
||||
khanat-opennel-code/code/ryzom/common/src/game_share/action_factory.cpp : CAction *CActionFactory::unpack (NLMISC::CBitMemStream &message, NLMISC::TGameCycle /* currentCycle */ )
|
||||
'''
|
||||
actions = []
|
||||
if msgin.needRead() >= 8:
|
||||
shortcode = msgin.readBool()
|
||||
if shortcode:
|
||||
code = msgin.readSerial(2)
|
||||
else:
|
||||
code = msgin.readUint8()
|
||||
action = self.create(INVALID_SLOT, code)
|
||||
if action:
|
||||
try:
|
||||
action.unpack (msgin);
|
||||
except RuntimeError:
|
||||
log = logging.getLogger('myLogger')
|
||||
log.warning('Missing code to unpack (code :%u)' % code)
|
||||
raise RuntimeError
|
||||
actions.append(action)
|
||||
else:
|
||||
log = logging.getLogger('myLogger')
|
||||
log.warning('Unpacking an action with unknown code, skip it (%u)' % code)
|
||||
return actions
|
||||
|
||||
class CImpulseDecoder:
|
||||
'''
|
||||
see : khanat-opennel-code/code/ryzom/client/src/impulse_decoder.cpp
|
||||
'''
|
||||
def __init__(self):
|
||||
self.reset()
|
||||
self._CActionFactory = CActionFactory()
|
||||
|
||||
def decode(self, msgin, receivedPacket, receivedAck, nextSentPacket):
|
||||
actions = []
|
||||
for level in range(0, 3):
|
||||
if level == 0:
|
||||
lAck = self._LastAck0
|
||||
channel = 0
|
||||
elif level == 1:
|
||||
lAck = self._LastAck1
|
||||
channel = receivedPacket & 1
|
||||
elif level == 2:
|
||||
lAck = self._LastAck2
|
||||
channel = receivedPacket & 3
|
||||
keep = True
|
||||
checkOnce = False
|
||||
num = 0
|
||||
# lastAck = lAck[channel]
|
||||
while True:
|
||||
next = msgin.readBool()
|
||||
if not next:
|
||||
break
|
||||
if not checkOnce:
|
||||
checkOnce = True
|
||||
keep = receivedAck >= lAck[channel]
|
||||
if keep:
|
||||
lAck[channel] = nextSentPacket
|
||||
num += 1
|
||||
action = self._CActionFactory.unpack(msgin)
|
||||
if keep:
|
||||
actions.append(action)
|
||||
else:
|
||||
pass
|
||||
|
||||
return actions
|
||||
|
||||
def reset(self):
|
||||
self._LastAck0 = [-1]
|
||||
self._LastAck1 = [-1, -1]
|
||||
self._LastAck2 = [-1, -1, -1, -1]
|
||||
|
||||
class ClientNetworkConnection:
|
||||
'''
|
||||
Partie client de la gestion de la communication reseau avec le serveur:
|
||||
|
||||
client :
|
||||
code/ryzom/client/src/network_connection.cpp
|
||||
server :
|
||||
khanat-opennel-code/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp # void CFeReceiveSub::handleReceivedMsg( CClientHost *clienthost )
|
||||
'''
|
||||
def __init__(self,
|
||||
khanat_host,
|
||||
khanat_port_frontend,
|
||||
|
@ -1491,8 +1807,7 @@ class ClientNetworkConnection:
|
|||
self._ConnectionState = TConnectionState.NotInitialised
|
||||
self.UserAddr, self.UserKey, self.UserId = None, None, None
|
||||
self.frontend = (khanat_host, khanat_port_frontend)
|
||||
self._sock = socket.socket(socket.AF_INET, # Internet
|
||||
socket.SOCK_DGRAM) # UDP
|
||||
self._sock = None
|
||||
self._CurrentReceivedNumber = 0
|
||||
self._SystemMode = 0
|
||||
self._LastReceivedAck = 0
|
||||
|
@ -1518,7 +1833,21 @@ class ClientNetworkConnection:
|
|||
self.checkMessageNumber = checkMessageNumber
|
||||
self._LastAckBit = 0
|
||||
self._AckBitMask = 0
|
||||
self._LongAckBitField = 0
|
||||
self._LongAckBitField = CBitSet()
|
||||
self._LatestSyncTime = 0
|
||||
self._ImpulseDecoder = CImpulseDecoder()
|
||||
self._LongAckBitField.resize(1024)
|
||||
|
||||
def connect(self):
|
||||
try:
|
||||
self._sock = socket.socket(socket.AF_INET, # Internet
|
||||
socket.SOCK_DGRAM) # UDP
|
||||
except:
|
||||
self.log.error("Impossible to connect on khanat")
|
||||
return False
|
||||
self._ConnectionState = TConnectionState.Login
|
||||
self._LatestSyncTime = int(time.clock_gettime(1)*1000)
|
||||
return True
|
||||
|
||||
def cookiesInit(self, UserAddr, UserKey, UserId):
|
||||
self.UserAddr = UserAddr
|
||||
|
@ -1528,22 +1857,22 @@ class ClientNetworkConnection:
|
|||
def reset(self):
|
||||
self._CurrentSendNumber += 0
|
||||
|
||||
def buildSystemHeader(self, msg): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::buildSystemHeader(NLMISC::CBitMemStream &msgout)
|
||||
msg.pushSint32(self._CurrentSendNumber)
|
||||
msg.pushBool(True) # systemMode
|
||||
def buildSystemHeader(self, msgout): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::buildSystemHeader(NLMISC::CBitMemStream &msgout)
|
||||
msgout.pushSint32(self._CurrentSendNumber)
|
||||
msgout.pushBool(True) # systemMode
|
||||
|
||||
def sendSystemLogin(self): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemLogin()
|
||||
if self._sock is None:
|
||||
raise ValueError
|
||||
msg = BitStream()
|
||||
self.buildSystemHeader(msg)
|
||||
msg.pushUint8(0) # SYSTEM_LOGIN_CODE
|
||||
msg.pushUint32(self.UserAddr)
|
||||
msg.pushUint32(self.UserKey)
|
||||
msg.pushUint32(self.UserId)
|
||||
msg.pushString(self.LanguageCode)
|
||||
msgout = BitStream()
|
||||
self.buildSystemHeader(msgout)
|
||||
msgout.pushUint8(CLFECOMMON.SYSTEM_LOGIN_CODE)
|
||||
msgout.pushUint32(self.UserAddr)
|
||||
msgout.pushUint32(self.UserKey)
|
||||
msgout.pushUint32(self.UserId)
|
||||
msgout.pushString(self.LanguageCode)
|
||||
|
||||
self._sock.sendto(msg.toBytes(), self.frontend)
|
||||
self._sock.sendto(msgout.toBytes(), self.frontend)
|
||||
self._CurrentSendNumber += 1
|
||||
|
||||
self._ConnectionState = TConnectionState.Login
|
||||
|
@ -1553,25 +1882,37 @@ class ClientNetworkConnection:
|
|||
if self._sock is None:
|
||||
raise ValueError
|
||||
self._QuitId += 1
|
||||
msg = BitStream()
|
||||
self.buildSystemHeader(msg)
|
||||
msg.pushUint8(8) # SYSTEM_LOGIN_CODE
|
||||
msg.pushSint32(self._QuitId) # _QuitId
|
||||
self._sock.sendto(msg.toBytes(), self.frontend)
|
||||
msgout = BitStream()
|
||||
self.buildSystemHeader(msgout)
|
||||
msgout.pushUint8(CLFECOMMON.SYSTEM_QUIT_CODE)
|
||||
msgout.pushSint32(self._QuitId) # _QuitId
|
||||
self._sock.sendto(msgout.toBytes(), self.frontend)
|
||||
self._ConnectionState = TConnectionState.Quit
|
||||
|
||||
def sendSystemAckSync(self): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemAckSync()
|
||||
if self._sock is None:
|
||||
raise ValueError
|
||||
msg = BitStream()
|
||||
self.buildSystemHeader(msg)
|
||||
msg.pushUint8(2) # SYSTEM_ACK_SYNC_CODE
|
||||
msg.pushSint32(self._LastReceivedNumber)
|
||||
msg.pushSint32(self._LastAckInLongAck)
|
||||
msg.pushSint32(self._LongAckBitField) # Signale le nombre de packet perdu
|
||||
msg.pushSint32(self._LatestSync)
|
||||
self.log.error("TODO")
|
||||
# self._sock.sendto(msg.toBytes(), self.frontend)
|
||||
self.log.debug("sendSystemAckSync")
|
||||
msgout = BitStream()
|
||||
self.buildSystemHeader(msgout)
|
||||
msgout.pushUint8(CLFECOMMON.SYSTEM_ACK_SYNC_CODE)
|
||||
msgout.pushSint32(self._LastReceivedNumber)
|
||||
msgout.pushSint32(self._LastAckInLongAck)
|
||||
self._LongAckBitField.writeSerial(msgout) # Signale le nombre de packet perdu
|
||||
msgout.pushSint32(self._LatestSync)
|
||||
|
||||
self.log.debug("%s" % msgout.message())
|
||||
self.log.debug("sendSystemAckSync -> send")
|
||||
self._sock.sendto(msgout.toBytes(), self.frontend)
|
||||
self._LatestSyncTime = self._UpdateTime
|
||||
|
||||
def sendSystemDisconnection(self):
|
||||
if self._sock is None:
|
||||
raise ValueError
|
||||
msgout = BitStream()
|
||||
self.buildSystemHeader(msgout)
|
||||
msgout.pushUint8(CLFECOMMON.SYSTEM_DISCONNECTION_CODE)
|
||||
self._sock.sendto(msgout.toBytes(), self.frontend)
|
||||
|
||||
def readDelta(self, msg):
|
||||
propertyCount = msg.readUint16()
|
||||
|
@ -1587,8 +1928,12 @@ class ClientNetworkConnection:
|
|||
self.log.debug("serverTick:%d" % serverTick)
|
||||
#self.readDelta(msg)
|
||||
|
||||
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # bool CNetworkConnection::buildStream( CBitMemStream &msgin )
|
||||
def impulseDecode(self, msgin):
|
||||
actions = self._ImpulseDecoder.decode(msgin, self._CurrentReceivedNumber, self._LastReceivedAck, self._CurrentSendNumber )
|
||||
self.log.debug(str(actions))
|
||||
|
||||
def buildStream(self, buffersize=65536):
|
||||
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # bool CNetworkConnection::buildStream( CBitMemStream &msgin )
|
||||
data, addr = self._sock.recvfrom(buffersize)
|
||||
return data, addr
|
||||
|
||||
|
@ -1605,7 +1950,10 @@ class ClientNetworkConnection:
|
|||
self._LastReceivedPacketInBothModes = self._CurrentReceivedNumber - 1
|
||||
|
||||
if not self._SystemMode:
|
||||
self.log.debug("Normal Mode")
|
||||
self._LastReceivedAck = msg.readSint32();
|
||||
else:
|
||||
self.log.debug("System Mode")
|
||||
|
||||
if self._CurrentReceivedNumber > self._LastReceivedNumber+1:
|
||||
self.log.debug("lost messages server->client [%d; %d]" %(self._LastReceivedPacketInBothModes + 1, self._CurrentReceivedNumber - 1))
|
||||
|
@ -1628,13 +1976,14 @@ class ClientNetworkConnection:
|
|||
self._AckBitMask = 0x00000000
|
||||
self._LastAckBit = ackBit;
|
||||
for i in range(self._LastReceivedNumber+1, self._CurrentReceivedNumber+1):
|
||||
if self._LongAckBitField & (i & (512-1)) > 1:
|
||||
self._LongAckBitField = self._LongAckBitField ^ (i & (512-1))
|
||||
if ackBool:
|
||||
self._LongAckBitField = self._LongAckBitField | (self._CurrentReceivedNumber & (512 - 1))
|
||||
self._LongAckBitField %= 512
|
||||
self._LongAckBitField.clearBit(i & 511)
|
||||
self._LongAckBitField.set(self._CurrentReceivedNumber & 511, ackBool)
|
||||
|
||||
if self._LastAckInLongAck <= (self._CurrentReceivedNumber-512):
|
||||
self._LastAckInLongAck = self._CurrentReceivedNumber-511;
|
||||
|
||||
self._LastReceivedNumber = self._CurrentReceivedNumber
|
||||
self.log.debug("_CurrentReceivedNumber:%d, _LastReceivedNumber:%d, ackBit:%d, _AckBitMask:%d _LongAckBitField:%d" % (self._CurrentReceivedNumber, self._LastReceivedNumber, ackBit, self._AckBitMask, self._LongAckBitField))
|
||||
self.log.debug("_CurrentReceivedNumber:%d, _LastReceivedNumber:%d, ackBit:%d, _AckBitMask:%d _LongAckBitField:%s" % (self._CurrentReceivedNumber, self._LastReceivedNumber, ackBit, self._AckBitMask, self._LongAckBitField))
|
||||
return True
|
||||
|
||||
def receiveSystemProbe(self, msg):
|
||||
|
@ -1645,6 +1994,7 @@ class ClientNetworkConnection:
|
|||
self.log.debug("received STALLED")
|
||||
|
||||
def receiveSystemSync(self, msg):
|
||||
self._LatestSyncTime = self._UpdateTime
|
||||
self._Synchronize = msg.readUint32()
|
||||
stime = msg.readSint64()
|
||||
self._LatestSync = msg.readUint32()
|
||||
|
@ -1670,8 +2020,113 @@ class ClientNetworkConnection:
|
|||
self._CurrentClientTime = self._UpdateTime - (self._LCT + self._MsPerTick)
|
||||
self.sendSystemAckSync()
|
||||
|
||||
def receiveNormalMessage(self, msgin):
|
||||
self.log.debug("received normal message Packet (%d)" % (msgin.needRead()))
|
||||
self.impulseDecode(msgin)
|
||||
|
||||
def disconnect(self):
|
||||
pass
|
||||
self.log.info("Disconnect")
|
||||
self.sendSystemDisconnection()
|
||||
self._sock.close()
|
||||
selc._sock = None
|
||||
self._ConnectionState = TConnectionState.Disconnect
|
||||
|
||||
def stateLogin(self, msgin):
|
||||
self.decodeHeader(msgin)
|
||||
if self._SystemMode:
|
||||
message = msgin.readUint8()
|
||||
self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead()))
|
||||
if message == CLFECOMMON.SYSTEM_SYNC_CODE:
|
||||
self._ConnectionState = TConnectionState.Synchronize
|
||||
self.log.debug("Login->synchronize")
|
||||
self.receiveSystemSync(msgin)
|
||||
return True
|
||||
elif message == CLFECOMMON.SYSTEM_STALLED_CODE:
|
||||
self.log.debug("received STALLED")
|
||||
self._ConnectionState = TConnectionState.Stalled
|
||||
self.receiveSystemStalled(msgin)
|
||||
return True
|
||||
elif message == CLFECOMMON.SYSTEM_PROBE_CODE:
|
||||
self.log.debug("Login->probe")
|
||||
self._ConnectionState = TConnectionState.Probe
|
||||
self.receiveSystemProbe(msgin)
|
||||
return True
|
||||
elif message == CLFECOMMON.SYSTEM_SERVER_DOWN_CODE:
|
||||
self.disconnect()
|
||||
self.log.warning("BACK-END DOWN")
|
||||
return False
|
||||
else:
|
||||
self.log.warning("CNET: received system %d in state Login" % message)
|
||||
self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d] '%s'" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead(), msgin.showLastData()))
|
||||
else:
|
||||
self.log.warning("CNET: received normal in state Login")
|
||||
return False
|
||||
|
||||
def stateSynchronize(self, msgin):
|
||||
self.decodeHeader(msgin)
|
||||
if self._SystemMode:
|
||||
message = msgin.readUint8()
|
||||
self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead()))
|
||||
if message == CLFECOMMON.SYSTEM_PROBE_CODE:
|
||||
self.log.debug("synchronize->probe")
|
||||
self._ConnectionState = TConnectionState.Probe
|
||||
self.receiveSystemProbe(msgin)
|
||||
return True
|
||||
elif message == CLFECOMMON.SYSTEM_STALLED_CODE:
|
||||
self.log.debug("received STALLED")
|
||||
self._ConnectionState = TConnectionState.Stalled
|
||||
self.receiveSystemStalled(msgin)
|
||||
return True
|
||||
elif message == CLFECOMMON.SYSTEM_SYNC_CODE:
|
||||
self.log.debug("synchronize->synchronize")
|
||||
self.receiveSystemSync(msgin)
|
||||
elif message == CLFECOMMON.SYSTEM_SERVER_DOWN_CODE:
|
||||
self.disconnect()
|
||||
self.log.warning("BACK-END DOWN")
|
||||
return False
|
||||
else:
|
||||
self.log.warning("CNET: received system %d in state Synchronize" % message)
|
||||
self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d] '%s'" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead(), msgin.showLastData()))
|
||||
else:
|
||||
self._ConnectionState = TConnectionState.Connected
|
||||
self.log.warning("CNET: synchronize->connected")
|
||||
# _Changes.push_back(CChange(0, ConnectionReady));
|
||||
self.receiveNormalMessage(msgin);
|
||||
return True
|
||||
if self._UpdateTime - self._LatestSyncTime > 300:
|
||||
self.sendSystemAckSync();
|
||||
return False
|
||||
|
||||
def stateConnected(self, msgin):
|
||||
self.decodeHeader(msgin)
|
||||
if self._SystemMode:
|
||||
message = msgin.readUint8()
|
||||
self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead()))
|
||||
if message == CLFECOMMON.SYSTEM_PROBE_CODE:
|
||||
self.log.debug("Connected->probe")
|
||||
self._ConnectionState = TConnectionState.Probe
|
||||
self.receiveSystemProbe(msgin)
|
||||
return True
|
||||
elif message == CLFECOMMON.SYSTEM_SYNC_CODE:
|
||||
self.log.debug("Connected->synchronize")
|
||||
self.receiveSystemSync(msgin)
|
||||
return True
|
||||
elif message == CLFECOMMON.SYSTEM_STALLED_CODE:
|
||||
self.log.debug("received STALLED")
|
||||
self._ConnectionState = TConnectionState.Stalled
|
||||
self.receiveSystemStalled(msgin)
|
||||
return True
|
||||
elif message == CLFECOMMON.SYSTEM_SERVER_DOWN_CODE:
|
||||
self.disconnect()
|
||||
self.log.warning("BACK-END DOWN")
|
||||
return False
|
||||
else:
|
||||
self.log.warning("CNET: received system %d in state Connected" % message)
|
||||
self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d] '%s'" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead(), msgin.showLastData()))
|
||||
else:
|
||||
self.receiveNormalMessage(msgin);
|
||||
return True
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # bool CNetworkConnection::update()
|
||||
|
@ -1679,6 +2134,36 @@ class ClientNetworkConnection:
|
|||
#self._UpdateTicks = 0
|
||||
self._ReceivedSync = False
|
||||
|
||||
if not self._sock:
|
||||
return False
|
||||
|
||||
stateBroke = True
|
||||
while stateBroke:
|
||||
buffer, addr = self.buildStream()
|
||||
self.log.debug("received message: %s" % buffer)
|
||||
msgin = BitStream()
|
||||
msgin.fromBytes(buffer)
|
||||
if self._ConnectionState == TConnectionState.Login:
|
||||
self.log.debug("state:Login")
|
||||
stateBroke = self.stateLogin(msgin)
|
||||
elif self._ConnectionState == TConnectionState.Synchronize:
|
||||
self.log.debug("state:Synchronize")
|
||||
stateBroke = self.stateSynchronize(msgin)
|
||||
elif self._ConnectionState == TConnectionState.Connected:
|
||||
self.log.debug("state:Connected")
|
||||
stateBroke = self.stateConnected(msgin)
|
||||
elif self._ConnectionState == TConnectionState.Probe:
|
||||
self.log.debug("state:Probe")
|
||||
stateBroke = False
|
||||
elif self._ConnectionState == TConnectionState.Stalled:
|
||||
self.log.debug("state:Stalled")
|
||||
stateBroke = False
|
||||
elif self._ConnectionState == TConnectionState.Quit:
|
||||
self.log.debug("state:Quit")
|
||||
stateBroke = False
|
||||
else:
|
||||
stateBroke = False
|
||||
|
||||
def EmulateFirst(self, msgRawXml, databaseRawXml):
|
||||
self.msgXml = ET.fromstring(msgRawXml)
|
||||
#ET.dump(msgXml)
|
||||
|
@ -1688,41 +2173,16 @@ class ClientNetworkConnection:
|
|||
self._MsgXmlMD5 = getTextMD5(msgRawXml)
|
||||
self._DatabaseXmlMD5 = getTextMD5(databaseRawXml)
|
||||
|
||||
self.connect()
|
||||
self.log.info("Client Login")
|
||||
self.sendSystemLogin()
|
||||
|
||||
self.log.info("Receive Message")
|
||||
for _ in range(0, 20): # while True:
|
||||
for i in range(0, 20): # while True:
|
||||
self.log.debug('loop %d' % i)
|
||||
self.update()
|
||||
data, addr = self.buildStream()
|
||||
self.log.debug("received message: %s" % data)
|
||||
msg = BitStream()
|
||||
msg.fromBytes(data)
|
||||
self.decodeHeader(msg)
|
||||
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:bool CNetworkConnection::stateSynchronize()
|
||||
message = msg.readUint8()
|
||||
self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msg.sizeData(), msg.sizeRead(), msg.needRead()))
|
||||
if message == 1: # SYSTEM_SYNC_CODE
|
||||
self.log.debug("synchronize->synchronize")
|
||||
self.receiveSystemSync(msg)
|
||||
elif message == 3: # SYSTEM_PROBE_CODE
|
||||
self.log.debug("synchronize->probe")
|
||||
self._ConnectionState = TConnectionState.Probe
|
||||
self.receiveSystemProbe(msg)
|
||||
elif message == 6: # SYSTEM_STALLED_CODE
|
||||
self.log.debug("received STALLED")
|
||||
self._ConnectionState = TConnectionState.Stalled
|
||||
self.receiveSystemStalled(msg)
|
||||
elif message == 7: # SYSTEM_SERVER_DOWN_CODE
|
||||
self.disconnect()
|
||||
self.log.warning("BACK-END DOWN")
|
||||
else:
|
||||
self.log.warning("CNET: received system %d in state Synchronize" % message)
|
||||
self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d] '%s'" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msg.sizeData(), msg.sizeRead(), msg.needRead(), msg.showLastData()))
|
||||
|
||||
# self.impulseCallBack(data)
|
||||
|
||||
self.log.info("Client Logout")
|
||||
self.log.info("Client Quit")
|
||||
self.sendSystemQuit()
|
||||
|
||||
|
||||
|
@ -2041,5 +2501,6 @@ def main():
|
|||
log.info("End")
|
||||
|
||||
if __name__ == "__main__":
|
||||
#Test()
|
||||
#TestBitStream()
|
||||
#TestCBitSet()
|
||||
main()
|
||||
|
|
Loading…
Reference in a new issue