mirror of
https://port.numenaute.org/aleajactaest/clientbot.git
synced 2024-11-25 16:46:31 +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
625
client.py
625
client.py
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue