diff --git a/server/tools/robot/virtualclient/__init__.py b/server/tools/robot/virtualclient/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/tools/robot/virtualclient/new_robot.py b/server/tools/robot/virtualclient/new_robot.py new file mode 100644 index 0000000..0ac0a39 --- /dev/null +++ b/server/tools/robot/virtualclient/new_robot.py @@ -0,0 +1,36 @@ +from optparse import OptionParser + +from tornado import gen +from tornado import httpclient +from tornado import httputil +from tornado import ioloop +from tornado import websocket + +import virtualclient + +@gen.coroutine +def createVirtualClient(account, ws_url): + virtualclient.VirtualClient(ws_url, account).run() + +@gen.coroutine +def main(): + parser = OptionParser(usage="%prog [options]") + parser.add_option("-a", + "--accounts", + dest = "accounts", + help = "account info") + (options, args) = parser.parse_args() + + ws_url = args if args else 'ws://192.168.100.21:7101/websocket' + accounts = options.accounts.split(',') + accounts = [] + for i in range(500): + accounts.append('test' + str(i)) + for account in accounts: + ioloop.IOLoop.current().spawn_callback(createVirtualClient, account, ws_url) + + while True: + yield gen.sleep(0.1) + +if __name__ == '__main__': + ioloop.IOLoop.current().run_sync(main) diff --git a/server/tools/robot/virtualclient/robot.py b/server/tools/robot/virtualclient/robot.py new file mode 100644 index 0000000..4f65c3a --- /dev/null +++ b/server/tools/robot/virtualclient/robot.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +import websocket +import sys +import ssl +import json +import datetime +import urllib.request + +import cs_proto_pb2 +import cs_msgid_pb2 + +#from google.protobuf import json_format +import pprint + +try: + import thread +except ImportError: + import _thread as thread +import time + +def getSession(account_id): + url = 'https://login-test.kingsome.cn/webapp/index.php?c=Login&a=auth&' + params = { + 'openid': sys.argv[2], + 'token': sys.argv[2], + 'gameid': 1008, + 'channel': '6000' + } + real_url = url + urllib.parse.urlencode(params) + print(real_url) + req = urllib.request.Request(real_url) + data = urllib.request.urlopen(req).read() + print(data) + return json.loads(data.decode('utf-8'))['session_id'] + +def inputCommand(ws): + cmdline= input('') + idx = cmdline.find(' ') + if idx <= 0: + cmdline += '()' + else: + cmdline = cmdline[:idx] + '(' + cmdline[idx + 1:] + ')' + msg = eval('cs_proto_pb2.' + cmdline) + sendMsg(ws, msg) + inputCommand(ws) + +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 + +#g_remote_ip = "ws://127.0.0.1:" + sys.argv[1] +g_remote_ip = sys.argv[1] +g_account_id = '6000_2001_' + sys.argv[2] +g_session_id = getSession(g_account_id) +g_server_id = sys.argv[4] +g_seqid = 1000 +g_login_time = time.time() +g_active_player_id = 0 + +recv_buf = bytearray() + +def sendMsg(ws, msg): +# print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')) + global g_seqid + ++g_seqid + msgid = eval('cs_msgid_pb2._' + msg.DESCRIPTOR.name) + + enmsg = msg.SerializeToString() + pktlen_str = bytes([(len(enmsg) & 0xFF) , (len(enmsg) >> 8 & 0xFF)]) + msgid_str = bytes([(msgid & 0xFF) , (msgid >> 8 & 0xFF)]) + seqid_str = bytes([(g_seqid & 0xFF) , (g_seqid >> 8 & 0xFF) , \ + (g_seqid >> 16 & 0xFF) , (g_seqid >> 24 & 0xFF)]) + sign_str = bytes([ord('K'), ord('S')]) + reserved_str = bytes([0, 0]) + buff = pktlen_str + msgid_str + seqid_str + sign_str + reserved_str + enmsg + + ws.send (buff, 2) +# print(time.time(), time.strftime('[%H:%M:%S]'), msg.DESCRIPTOR.name + '{') +# print(str(msg),) +# print('}') +# print('') + +def sendCMMove(ws): + msg = cs_proto_pb2.CMMove() + msg.spectate = True + sendMsg(ws, msg) + +def onMessage(ws, message): + global recv_buf + +# print('onMessage', len(message)) + data = bytearray(message) + recv_buf += data + parserPacket(ws) + +def parserPacket(ws): + global 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] + onUserPacket(ws, msgid, msgbody) + recv_buf = recv_buf[12 + pktlen:] + +def procSMUpdate(msg): + global g_active_player_id + if msg.active_player_id != 0: + g_active_player_id = msg.active_player_id + print(g_active_player_id) + for part_obj in msg.part_objects: + if part_obj.object_type == 1 and part_obj.union_obj_1.obj_uniid == g_active_player_id: + pass +# print(part_obj) + for full_obj in msg.full_objects: + if full_obj.object_type == 1 and full_obj.union_obj_1.obj_uniid == g_active_player_id: + if full_obj.union_obj_1.dead: + print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')) + print(full_obj) + +def onUserPacket(ws, msgid, msgbody): + print('onUserPacket') + global g_login_time + if time.time() - g_login_time > 30: + sendCMMove(ws) + try: + if msgid == 1004: + msg = getSMMsg(msgid) + ret = msg.ParseFromString(msgbody) + procSMUpdate(msg) + if msgid != 1009 and msgid != 1005: + return + 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),) + print('}') + print('') + except Exception as e: + print('onUserPacket', e) + +def onError (ws, error): + print (error) + +def onClose (ws): + print ("### closed ###") + +def opOpen (ws): + print('opOpen', time.time()) + def run (*args): + global g_remote_ip + global g_account_id + global g_session_id + global g_server_id + msg = cs_proto_pb2.CMJoin() + msg.server_id = int(g_server_id) + msg.account_id = g_account_id + msg.name = "aozhwei12345678" + print(msg.DESCRIPTOR.name, 'zzzzz') + sendMsg(ws, msg) + while True: + inputCommand(ws) + time.sleep(500) + ws.close () + print ("thread terminating...") + thread.start_new_thread (run, ()) + +print(time.time()) +print(g_remote_ip) + +if __name__ == "__main__": +# websocket.enableTrace(True) + ws = websocket.WebSocketApp (g_remote_ip, + on_message = onMessage, + on_error = onError, + on_close = onClose + ) + ws.on_open = opOpen + ws.run_forever () diff --git a/server/tools/robot/virtualclient/virtualclient.py b/server/tools/robot/virtualclient/virtualclient.py new file mode 100644 index 0000000..56ff774 --- /dev/null +++ b/server/tools/robot/virtualclient/virtualclient.py @@ -0,0 +1,114 @@ +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)