WebServer.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import asyncio
  2. import datetime
  3. import json
  4. import re
  5. import websockets
  6. import logging
  7. import threading
  8. logging.basicConfig(level=logging.INFO)
  9. ip = "192.168.137.1"
  10. port = 9999
  11. connected_clients = set()
  12. def parse_message(message):
  13. # 分割消息类型和JSON字符串
  14. msg_type, json_str = message.split(':', 1)
  15. # 将JSON字符串转换为字典
  16. data = json.loads(json_str)
  17. # 返回解析结果
  18. return msg_type, data
  19. class User:
  20. def __init__(self, bet_count, uid, betAmount):
  21. self.bet_count = bet_count
  22. self.uid = uid
  23. self.betAmount = betAmount
  24. class UserEncoder(json.JSONEncoder):
  25. def default(self, obj):
  26. if isinstance(obj, User):
  27. return {"uid": obj.uid, "bet_count": obj.bet_count, "betAmount": obj.betAmount}
  28. # 让基类的 default 方法抛出 TypeError
  29. return json.JSONEncoder.default(self, obj)
  30. # 用于存储User对象的用户信息和次数,key为用户ID,value为User对象
  31. user_dict = {}
  32. async def deal_message(message):
  33. try:
  34. msg_type, data = parse_message(message)
  35. if msg_type == "BetNotify":
  36. # {"uid":4174549,"detail":{"option":302,"betAmount":1000,"auto":false,"is_shot":false,"win_amt":0,"odds":0,"betGameCoin":0},"curCoin":767943,"selfBet":1000,"totalBet":67000,"curUsdt":0}
  37. print(f"下注: {data}")
  38. # 解析日期和小时
  39. now = datetime.datetime.now()
  40. date = now.strftime("%Y-%m-%d")
  41. hour = now.strftime("%H")
  42. minute = now.strftime("%M")
  43. # 获取用户ID
  44. uid = data["uid"]
  45. bet_amount = data["detail"]["betAmount"]
  46. # 获取用户信息
  47. user = user_dict.get(uid)
  48. if user is None:
  49. # 如果用户信息不存在,创建一个新的User对象
  50. user = User(0, "", 0)
  51. user_dict[uid] = user
  52. # 更新用户信息
  53. user.bet_count += 1
  54. user.uid = uid
  55. user.betAmount += bet_amount / 100
  56. print(f"用户{uid}下注次数: {user.bet_count}, 总金额: {user.betAmount}")
  57. user_dict[uid] = user
  58. elif msg_type == "GameDataSynNotify":
  59. print(f"同步游戏数据: {data}")
  60. elif msg_type == "KickNotify":
  61. print(f"被踢下线了: {data}")
  62. await broadcast('''CMD:
  63. setTimeout(function(){
  64. let btnDownNode = cc.find("Layer/PushNotice_panel/close_button");
  65. if (btnDownNode && btnDownNode.getComponent(cc.Button)) {
  66. btnDownNode.getComponent(cc.Button).clickEvents[0].emit([btnDownNode]);
  67. } else {
  68. console.error("节点未找到或节点上没有cc.Button组件");
  69. }
  70. },3000);
  71. setTimeout(function(){
  72. let btnDownNode = cc.find("Canvas/container/content/smallGame/createScrollView/view/cotent/row1/pokerNode/porkermaster/allHand");
  73. if (btnDownNode && btnDownNode.getComponent(cc.Button)) {
  74. btnDownNode.getComponent(cc.Button).clickEvents[0].emit([btnDownNode]);
  75. } else {
  76. console.error("节点未找到或节点上没有cc.Button组件");
  77. }
  78. },6000);
  79. ''')
  80. elif msg_type == "StopBetNotify":
  81. # 每把结束存储数据,然后清空数据
  82. with open("user_bet.log", "a") as f:
  83. time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  84. # 将user_dict 转成json字符串
  85. f.write(f"{time}:{json.dumps(user_dict, cls=UserEncoder)}\n")
  86. user_dict.clear()
  87. else:
  88. logging.info(f"Received message: {message}")
  89. except json.JSONDecodeError as e:
  90. logging.error(f"Error decoding JSON: {e}")
  91. except Exception as e:
  92. logging.info(f"Received message: {message}")
  93. async def echo(websocket, path):
  94. connected_clients.add(websocket)
  95. try:
  96. async for message in websocket:
  97. # with open("ws.log", "a") as f:
  98. # time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  99. # f.write(f"{time}:{message}\n")
  100. await deal_message(message)
  101. await websocket.send("Server says: 你好,服务端收到,连接建立成功")
  102. except websockets.ConnectionClosed as e:
  103. logging.warning(f"Connection closed: {e.reason}")
  104. except Exception as e:
  105. logging.error(f"Error: {e}", exc_info=True)
  106. finally:
  107. connected_clients.remove(websocket)
  108. async def broadcast(message):
  109. if connected_clients:
  110. await asyncio.wait([client.send(message) for client in connected_clients])
  111. else:
  112. print("No clients are connected.")
  113. def start_cli(loop):
  114. while True:
  115. # Enter command (1: Send custom message, 2: Send JS script from file): 翻译成中文并且print
  116. print("输入命令 (1: 发送自定义消息, 2: 发送JS脚本):")
  117. command = input("请输入:")
  118. if command == "1":
  119. message = input("Enter message to send: ")
  120. # 在当前运行的事件循环中安排broadcast任务
  121. loop.call_soon_threadsafe(asyncio.create_task, broadcast(message))
  122. elif command == "2":
  123. sendJsCommand(loop)
  124. else:
  125. print("Unknown command")
  126. def sendJsCommand(loop):
  127. with open("script.js", "r", encoding="utf-8") as file:
  128. script_content = file.read()
  129. # 去除script中注释的行注释或者块注释
  130. script_content = re.sub(r"//.*?$", "", script_content, flags=re.MULTILINE) # 去除行注释
  131. script_content = re.sub(r"/\*.*?\*/", "", script_content, flags=re.DOTALL) # 去除块注释
  132. # 可选:移除因为删除注释而产生的多余空行
  133. script_content = re.sub(r"\n\s*\n", "\n", script_content, flags=re.MULTILINE)
  134. # 在当前运行的事件循环中安排broadcast任务
  135. loop.call_soon_threadsafe(asyncio.create_task, broadcast(script_content))
  136. async def main():
  137. server = await websockets.serve(echo, ip, port)
  138. try:
  139. await server.wait_closed()
  140. except KeyboardInterrupt:
  141. logging.info("Server stopped by KeyboardInterrupt")
  142. if __name__ == '__main__':
  143. now = datetime.datetime.now()
  144. cache_date = now.strftime("%Y-%m-%d")
  145. cache_hour = now.strftime("%H")
  146. loop = asyncio.get_event_loop()
  147. # 在另一个线程中启动 CLI
  148. cli_thread = threading.Thread(target=start_cli, args=(loop,), daemon=True)
  149. cli_thread.start()
  150. try:
  151. loop.run_until_complete(main())
  152. except Exception as e:
  153. logging.error(f"Server error: {e}", exc_info=True)
  154. finally:
  155. loop.close()