decode some message server, and reoganize code

This commit is contained in:
AleaJactaEst 2019-05-31 19:25:04 +02:00
parent bc4a1cbd09
commit 4b37c73acb

625
client.py
View file

@ -45,6 +45,8 @@ import hashlib
import time import time
INVALID_SLOT = 0xff
class BitStream(): class BitStream():
def __init__(self): def __init__(self):
self._pos = 0 self._pos = 0
@ -278,21 +280,7 @@ class BitStream():
self._read = readBefore self._read = readBefore
return ret return ret
def getTextMD5(dataRawXml): def TestBitStream():
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():
a = BitStream() a = BitStream()
a.pushBool(True) a.pushBool(True)
a.pushBool(False) a.pushBool(False)
@ -349,6 +337,94 @@ def Test():
print(b.readChar()) print(b.readChar())
print(b.readString()) print(b.readString())
print(b.toBytes()) 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(): class CFileChild():
def __init__(self, name, pos, size): def __init__(self, name, pos, size):
@ -440,6 +516,30 @@ class TConnectionState(IntEnum):
Disconnect = 8 # disconnect() called, or timeout, or connection closed by frontend Disconnect = 8 # disconnect() called, or timeout, or connection closed by frontend
Quit = 9 # quit() called 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): class Card(IntEnum):
BEGIN_TOKEN = 0 BEGIN_TOKEN = 0
@ -546,6 +646,7 @@ class CArgV5(Union):
("f64", c_double), ("f64", c_double),
("ex", CArgV4)] ("ex", CArgV4)]
class CArg:
# union # union
# { # {
# struct # struct
@ -576,7 +677,6 @@ class CArgV5(Union):
# } ex; # } ex;
# } _Value; # } _Value;
class CArg:
def __init__(self): def __init__(self):
self._value = CArgV5() self._value = CArgV5()
self._value.ii64 = 0 self._value.ii64 = 0
@ -1478,7 +1578,223 @@ class CPersistentDataRecord:
break 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: 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, def __init__(self,
khanat_host, khanat_host,
khanat_port_frontend, khanat_port_frontend,
@ -1491,8 +1807,7 @@ class ClientNetworkConnection:
self._ConnectionState = TConnectionState.NotInitialised self._ConnectionState = TConnectionState.NotInitialised
self.UserAddr, self.UserKey, self.UserId = None, None, None self.UserAddr, self.UserKey, self.UserId = None, None, None
self.frontend = (khanat_host, khanat_port_frontend) self.frontend = (khanat_host, khanat_port_frontend)
self._sock = socket.socket(socket.AF_INET, # Internet self._sock = None
socket.SOCK_DGRAM) # UDP
self._CurrentReceivedNumber = 0 self._CurrentReceivedNumber = 0
self._SystemMode = 0 self._SystemMode = 0
self._LastReceivedAck = 0 self._LastReceivedAck = 0
@ -1518,7 +1833,21 @@ class ClientNetworkConnection:
self.checkMessageNumber = checkMessageNumber self.checkMessageNumber = checkMessageNumber
self._LastAckBit = 0 self._LastAckBit = 0
self._AckBitMask = 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): def cookiesInit(self, UserAddr, UserKey, UserId):
self.UserAddr = UserAddr self.UserAddr = UserAddr
@ -1528,22 +1857,22 @@ class ClientNetworkConnection:
def reset(self): def reset(self):
self._CurrentSendNumber += 0 self._CurrentSendNumber += 0
def buildSystemHeader(self, msg): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::buildSystemHeader(NLMISC::CBitMemStream &msgout) def buildSystemHeader(self, msgout): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::buildSystemHeader(NLMISC::CBitMemStream &msgout)
msg.pushSint32(self._CurrentSendNumber) msgout.pushSint32(self._CurrentSendNumber)
msg.pushBool(True) # systemMode msgout.pushBool(True) # systemMode
def sendSystemLogin(self): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemLogin() def sendSystemLogin(self): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemLogin()
if self._sock is None: if self._sock is None:
raise ValueError raise ValueError
msg = BitStream() msgout = BitStream()
self.buildSystemHeader(msg) self.buildSystemHeader(msgout)
msg.pushUint8(0) # SYSTEM_LOGIN_CODE msgout.pushUint8(CLFECOMMON.SYSTEM_LOGIN_CODE)
msg.pushUint32(self.UserAddr) msgout.pushUint32(self.UserAddr)
msg.pushUint32(self.UserKey) msgout.pushUint32(self.UserKey)
msg.pushUint32(self.UserId) msgout.pushUint32(self.UserId)
msg.pushString(self.LanguageCode) msgout.pushString(self.LanguageCode)
self._sock.sendto(msg.toBytes(), self.frontend) self._sock.sendto(msgout.toBytes(), self.frontend)
self._CurrentSendNumber += 1 self._CurrentSendNumber += 1
self._ConnectionState = TConnectionState.Login self._ConnectionState = TConnectionState.Login
@ -1553,25 +1882,37 @@ class ClientNetworkConnection:
if self._sock is None: if self._sock is None:
raise ValueError raise ValueError
self._QuitId += 1 self._QuitId += 1
msg = BitStream() msgout = BitStream()
self.buildSystemHeader(msg) self.buildSystemHeader(msgout)
msg.pushUint8(8) # SYSTEM_LOGIN_CODE msgout.pushUint8(CLFECOMMON.SYSTEM_QUIT_CODE)
msg.pushSint32(self._QuitId) # _QuitId msgout.pushSint32(self._QuitId) # _QuitId
self._sock.sendto(msg.toBytes(), self.frontend) self._sock.sendto(msgout.toBytes(), self.frontend)
self._ConnectionState = TConnectionState.Quit self._ConnectionState = TConnectionState.Quit
def sendSystemAckSync(self): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemAckSync() def sendSystemAckSync(self): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemAckSync()
if self._sock is None: if self._sock is None:
raise ValueError raise ValueError
msg = BitStream() self.log.debug("sendSystemAckSync")
self.buildSystemHeader(msg) msgout = BitStream()
msg.pushUint8(2) # SYSTEM_ACK_SYNC_CODE self.buildSystemHeader(msgout)
msg.pushSint32(self._LastReceivedNumber) msgout.pushUint8(CLFECOMMON.SYSTEM_ACK_SYNC_CODE)
msg.pushSint32(self._LastAckInLongAck) msgout.pushSint32(self._LastReceivedNumber)
msg.pushSint32(self._LongAckBitField) # Signale le nombre de packet perdu msgout.pushSint32(self._LastAckInLongAck)
msg.pushSint32(self._LatestSync) self._LongAckBitField.writeSerial(msgout) # Signale le nombre de packet perdu
self.log.error("TODO") msgout.pushSint32(self._LatestSync)
# self._sock.sendto(msg.toBytes(), self.frontend)
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): def readDelta(self, msg):
propertyCount = msg.readUint16() propertyCount = msg.readUint16()
@ -1587,8 +1928,12 @@ class ClientNetworkConnection:
self.log.debug("serverTick:%d" % serverTick) self.log.debug("serverTick:%d" % serverTick)
#self.readDelta(msg) #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): 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) data, addr = self._sock.recvfrom(buffersize)
return data, addr return data, addr
@ -1605,7 +1950,10 @@ class ClientNetworkConnection:
self._LastReceivedPacketInBothModes = self._CurrentReceivedNumber - 1 self._LastReceivedPacketInBothModes = self._CurrentReceivedNumber - 1
if not self._SystemMode: if not self._SystemMode:
self.log.debug("Normal Mode")
self._LastReceivedAck = msg.readSint32(); self._LastReceivedAck = msg.readSint32();
else:
self.log.debug("System Mode")
if self._CurrentReceivedNumber > self._LastReceivedNumber+1: if self._CurrentReceivedNumber > self._LastReceivedNumber+1:
self.log.debug("lost messages server->client [%d; %d]" %(self._LastReceivedPacketInBothModes + 1, self._CurrentReceivedNumber - 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._AckBitMask = 0x00000000
self._LastAckBit = ackBit; self._LastAckBit = ackBit;
for i in range(self._LastReceivedNumber+1, self._CurrentReceivedNumber+1): for i in range(self._LastReceivedNumber+1, self._CurrentReceivedNumber+1):
if self._LongAckBitField & (i & (512-1)) > 1: self._LongAckBitField.clearBit(i & 511)
self._LongAckBitField = self._LongAckBitField ^ (i & (512-1)) self._LongAckBitField.set(self._CurrentReceivedNumber & 511, ackBool)
if ackBool:
self._LongAckBitField = self._LongAckBitField | (self._CurrentReceivedNumber & (512 - 1)) if self._LastAckInLongAck <= (self._CurrentReceivedNumber-512):
self._LongAckBitField %= 512 self._LastAckInLongAck = self._CurrentReceivedNumber-511;
self._LastReceivedNumber = self._CurrentReceivedNumber 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 return True
def receiveSystemProbe(self, msg): def receiveSystemProbe(self, msg):
@ -1645,6 +1994,7 @@ class ClientNetworkConnection:
self.log.debug("received STALLED") self.log.debug("received STALLED")
def receiveSystemSync(self, msg): def receiveSystemSync(self, msg):
self._LatestSyncTime = self._UpdateTime
self._Synchronize = msg.readUint32() self._Synchronize = msg.readUint32()
stime = msg.readSint64() stime = msg.readSint64()
self._LatestSync = msg.readUint32() self._LatestSync = msg.readUint32()
@ -1670,8 +2020,113 @@ class ClientNetworkConnection:
self._CurrentClientTime = self._UpdateTime - (self._LCT + self._MsPerTick) self._CurrentClientTime = self._UpdateTime - (self._LCT + self._MsPerTick)
self.sendSystemAckSync() self.sendSystemAckSync()
def receiveNormalMessage(self, msgin):
self.log.debug("received normal message Packet (%d)" % (msgin.needRead()))
self.impulseDecode(msgin)
def disconnect(self): 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): def update(self):
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # bool CNetworkConnection::update() # khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # bool CNetworkConnection::update()
@ -1679,6 +2134,36 @@ class ClientNetworkConnection:
#self._UpdateTicks = 0 #self._UpdateTicks = 0
self._ReceivedSync = False 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): def EmulateFirst(self, msgRawXml, databaseRawXml):
self.msgXml = ET.fromstring(msgRawXml) self.msgXml = ET.fromstring(msgRawXml)
#ET.dump(msgXml) #ET.dump(msgXml)
@ -1688,41 +2173,16 @@ class ClientNetworkConnection:
self._MsgXmlMD5 = getTextMD5(msgRawXml) self._MsgXmlMD5 = getTextMD5(msgRawXml)
self._DatabaseXmlMD5 = getTextMD5(databaseRawXml) self._DatabaseXmlMD5 = getTextMD5(databaseRawXml)
self.connect()
self.log.info("Client Login") self.log.info("Client Login")
self.sendSystemLogin() self.sendSystemLogin()
self.log.info("Receive Message") 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() 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 Quit")
self.log.info("Client Logout")
self.sendSystemQuit() self.sendSystemQuit()
@ -2041,5 +2501,6 @@ def main():
log.info("End") log.info("End")
if __name__ == "__main__": if __name__ == "__main__":
#Test() #TestBitStream()
#TestCBitSet()
main() main()