115 lines
3.5 KiB
Python
115 lines
3.5 KiB
Python
import time
|
|
import datetime
|
|
|
|
from tornado import gen
|
|
from tornado import httpclient
|
|
from tornado import httputil
|
|
from tornado import ioloop
|
|
from tornado import websocket
|
|
|
|
import cs_proto_pb2
|
|
import cs_msgid_pb2
|
|
|
|
def getSMMsgEnum(sm_msgid):
|
|
sm_e = cs_msgid_pb2._SMMESSAGEID_E
|
|
for e in sm_e.values:
|
|
if e.number == sm_msgid:
|
|
return e
|
|
return None
|
|
|
|
def getSMMsg(sm_msgid):
|
|
sm_e = getSMMsgEnum(sm_msgid)
|
|
msg = eval('cs_proto_pb2.' + sm_e.name[1:] + '()')
|
|
return msg
|
|
|
|
class VirtualClient(object):
|
|
|
|
def __init__(self, ws_url, account):
|
|
self.ws_url = ws_url
|
|
self.account = account
|
|
print(self.ws_url)
|
|
|
|
@gen.coroutine
|
|
def co_connect(self):
|
|
print("connect, account:%s" % self.account)
|
|
conn = yield websocket.websocket_connect(self.ws_url)
|
|
assert conn
|
|
ioloop.IOLoop.current().spawn_callback(self.co_receiveMessage, conn)
|
|
self.sendLogin(conn)
|
|
|
|
def sendMsg(self, conn, msg):
|
|
seqid = 1
|
|
print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
|
|
msgid = eval('cs_msgid_pb2._' + msg.DESCRIPTOR.name)
|
|
PACK_SIGN = 'KS'
|
|
enmsg = bytearray(msg.SerializeToString())
|
|
head = bytearray(12)
|
|
head[0] = len(enmsg) & 0xFF
|
|
head[1] = len(enmsg) >> 8 & 0xFF
|
|
head[2] = msgid & 0xFF
|
|
head[3] = msgid >> 8 & 0xFF
|
|
head[4] = 0
|
|
head[5] = 0
|
|
head[6] = 0
|
|
head[7] = 0
|
|
head[8] = ord('K')
|
|
head[9] = ord('S')
|
|
head[10] = 0
|
|
head[11] = 0
|
|
buff = head + enmsg
|
|
conn.write_message(bytes(buff), True)
|
|
print(time.time(), time.strftime('[%H:%M:%S]'), msg.DESCRIPTOR.name + '{')
|
|
print(str(msg), end='')
|
|
print('}', end='')
|
|
print('')
|
|
|
|
def sendLogin(self, conn):
|
|
msg = cs_proto_pb2.CMJoin()
|
|
msg.server_id = 2
|
|
msg.account_id = self.account
|
|
msg.baseskin = 14001
|
|
self.sendMsg(conn, msg)
|
|
|
|
def parsePacket(self, conn, recv_buf):
|
|
while len(recv_buf) >= 8:
|
|
pktlen = recv_buf[0] + (recv_buf[1] << 8)
|
|
msgid = recv_buf[2] + (recv_buf[3] << 8)
|
|
seqid = recv_buf[4] + \
|
|
(recv_buf[5] << 8) + \
|
|
(recv_buf[6] << 16) + \
|
|
(recv_buf[7] << 24)
|
|
sign = recv_buf[8] + (recv_buf[9] << 8)
|
|
resv = recv_buf[10] + (recv_buf[11] << 8)
|
|
if len(recv_buf) >= 12 + pktlen:
|
|
msgbody = recv_buf[12 : 12 + pktlen]
|
|
self.onReceiveUserPacket(conn, msgid, msgbody)
|
|
recv_buf = recv_buf[12 + pktlen:]
|
|
|
|
def onReceiveUserPacket(self, conn, msgid, msgbody):
|
|
try:
|
|
#print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
|
|
msg = getSMMsg(msgid)
|
|
ret = msg.ParseFromString(msgbody)
|
|
#print(len(msgbody))
|
|
#print(time.time(), time.strftime('[%H:%M:%S]'), msg.DESCRIPTOR.name + '{')
|
|
#print(str(msg), end='')
|
|
#print('}')
|
|
#print('')
|
|
except Exception as e:
|
|
print('onReceiveUserPacket', e)
|
|
|
|
@gen.coroutine
|
|
def co_receiveMessage(self, conn):
|
|
recv_buf = bytearray()
|
|
while True:
|
|
data = yield conn.read_message()
|
|
if data is None:
|
|
break
|
|
else:
|
|
recv_buf += data
|
|
self.parsePacket(conn, recv_buf)
|
|
|
|
@gen.coroutine
|
|
def run(self):
|
|
ioloop.IOLoop.current().spawn_callback(self.co_connect)
|