You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ryzom-core/ryzom/server/tools/nel_message.py

171 lines
3.4 KiB
Python

import logging
import socket
SockTimeOut=10
class CMemStream:
def __init__(self):
self.InputStream = False
self.Pos = 0
self.Buffer = b""
def setBuffer(self, Buffer):
self.InputStream = True
self.Buffer = Buffer
self.Pos = 0
def isReading(self):
return self.InputStream
def serialUInt8(self, val=b""):
if self.isReading():
val = ord(self.Buffer[self.Pos])
self.Pos += 1
return val
else:
self.Buffer += bytes([val & 0xFF])
self.Pos += 1
def serialUInt32(self, val=b""):
if self.isReading():
val = ord(self.Buffer[self.Pos])
self.Pos += 1
val += ord(self.Buffer[self.Pos])*256
self.Pos += 1
val += ord(self.Buffer[self.Pos])*256*256
self.Pos += 1
val += ord(self.Buffer[self.Pos])*256*256*256
self.Pos += 1
return val
else:
self.Buffer += bytes([val & 0xFF])
self.Buffer += bytes([(val>>8) & 0xFF])
self.Buffer += bytes([(val>>16) & 0xFF])
self.Buffer += bytes([(val>>24) & 0xFF])
self.Pos += 4
def serialString(self, val=b""):
if self.isReading():
size = self.serialUInt32()
val = self.Buffer[self.Pos:self.Pos+size]
self.Pos += len(val)
return val
else:
try:
#Convert to bytes if need
val = val.encode("utf-8")
except AttributeError:
pass
valLen = len(val)
self.serialUInt32(valLen)
self.Buffer += val
self.Pos += valLen
def serialEnum(self, val=""):
pass
class CMessage(CMemStream):
def __init__(self):
super().__init__()
def setName(self, name):
self.MsgName = name
class CCallbackClient():
ConSock = False
MsgNum = 0
def connect(self, addr, port, res):
global SockTimeOut
self.MsgNum = 0
self.ConSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.ConSock.connect((addr, port))#, $errno, $errstr, $SockTimeOut)
except socket.error:
print("Connection failed...")
return False
print("Connection enabled!")
return True
#TODO: set time out on the socket to 2 secondes
#stream_set_timeout(self.ConSock, $SockTimeOut)
def close(self):
if self.ConSock:
self.ConSock.close()
def sendMessage(self, message):
hd = CMemStream()
hd.serialUInt32(self.MsgNum) #number the packet
self.MsgNum += 1
messageType = 0
hd.serialUInt8(messageType)
hd.serialString(message.MsgName)
size = hd.Pos + message.Pos
Buffer = chr((size>>24)&0xFF)
Buffer += chr((size>>16)&0xFF)
Buffer += chr((size>>8)&0xFF)
Buffer += chr(size&0xFF)
Buffer = Buffer.encode("iso-8859-1")
Buffer += hd.Buffer
Buffer += message.Buffer
print(Buffer.decode("utf-8", errors="replace"))
sent = self.ConSock.send(Buffer)
if not sent:
raise RuntimeError("socket connection broken")
def waitMessage(self):
size = 0
val = self.ConSock.recv(1)
if val:
size = ord(val) << 24
else:
print("Error")
val = self.ConSock.recv(1)
if val:
size = ord(val) << 16
else:
print("Error")
val = self.ConSock.recv(1)
size += ord(val) << 8
val = self.ConSock.recv(1)
size += ord(val)
fake = self.ConSock.recv(5)
size -= 5 #remove the fake
Buffer = ""
while size > 0 and len(Buffer) != size:
Buffer += self.ConSock.recv(size - len(Buffer)).decode("utf-8", errors="replace")
msgin = CMemStream()
msgin.setBuffer(Buffer)
#decode msg name
name = ""
name = msgin.serialString(name)
logging.info("Message name = '%s'" % name)
message = CMessage()
message.setBuffer(msgin.Buffer[msgin.Pos:])
message.setName(name)
return message