PokerMasterDataProccesser.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import datetime
  2. import json
  3. import logging
  4. # 所有的下注选项
  5. OPTIONS = [101, 102, 103, 301, 302, 303, 304, 305]
  6. # 下注选项
  7. class BetOption:
  8. def __init__(self, option, odds, limit, total_bet=0):
  9. self.option = option
  10. if odds == 0:
  11. self.odds = 1
  12. self.odds = odds
  13. self.limitRed = limit
  14. self.total_bet = total_bet
  15. def __str__(self):
  16. return (f"BetOption(option={self.option}, odds={self.odds}, "
  17. f"limitRed={self.limitRed}, totalBet={self.total_bet})")
  18. # 用户信息
  19. class User:
  20. # 对应option的下注金额
  21. betOptionAmounts = {option: 0 for option in OPTIONS}
  22. finance = 0
  23. def __init__(self, bet_count, uid, amount):
  24. self.bet_count = bet_count
  25. self.uid = uid
  26. self.betAmount = amount
  27. class UserEncoder(json.JSONEncoder):
  28. def default(self, obj):
  29. if isinstance(obj, User):
  30. return {"uid": obj.uid, "bet_count": obj.bet_count, "betAmount": obj.betAmount, "finance": obj.finance}
  31. # 让基类的 default 方法抛出 TypeError
  32. return json.JSONEncoder.default(self, obj)
  33. def init_round_option_info():
  34. global round_option_info
  35. round_option_info = {option: BetOption(option, 0, 0) for option in OPTIONS}
  36. # 用于存储User对象的用户信息和次数,key为用户ID,value为User对象
  37. round_user_betinfo = {}
  38. round_option_info = {}
  39. # 本轮选项赔率和下注金额
  40. init_round_option_info()
  41. # 庄家的钱
  42. banker_finance = 0
  43. # 虚拟一个用户,用来记录同步下来的下注数据,不然结算会异常,但是这样统计个人数据的时候,就会有点出入,
  44. # 没办法,因为会被定时踢出
  45. DATA_SYN_NOTIFY_UID = -9999
  46. async def deal_message(message, broadcast_func):
  47. try:
  48. msg_type, data = parse_message(message)
  49. if msg_type == "BetNotify":
  50. await betNotify(data)
  51. elif msg_type == "GameDataSynNotify":
  52. await gameDataSynNotify(data)
  53. elif msg_type == "ShowOddsNotify":
  54. await ShowOddsNotify(data)
  55. elif msg_type == "KickNotify":
  56. await kickNotify(data, broadcast_func)
  57. elif msg_type == "GameRoundEndNotify":
  58. await gameRoundEndNotify(data)
  59. elif msg_type == "MergeAutoBetNotify":
  60. await MergeAutoBetNotify(data)
  61. else:
  62. logging.info(f"Received message: {message}")
  63. except Exception as e:
  64. logging.info(f"Received message: {message}")
  65. async def gameRoundEndNotify(data):
  66. global banker_finance
  67. print(f"收到结束下注GameRoundEndNotify")
  68. # 开始结算
  69. # 总收入
  70. current_round_income = 0
  71. for option in round_option_info.values():
  72. current_round_income += option.total_bet
  73. # 开奖结果
  74. option_results = data["optionResult"]
  75. for open_result in option_results:
  76. # 开奖结果
  77. option = open_result["option"]
  78. result = open_result["result"]
  79. # 这个是下注的选项信息
  80. option_info_option_ = round_option_info[option]
  81. odds_rate = option_info_option_.odds
  82. if result == 1: # 证明这个选项中奖了
  83. # 庄家结算
  84. final_out = option_info_option_.total_bet * odds_rate
  85. print(
  86. f"选项{option}中奖了, 赔率{odds_rate}, 该选项总下注{option_info_option_.total_bet / 100}¥, 赔付了{final_out / 100}¥")
  87. current_round_income -= final_out
  88. # 玩家结算
  89. for user in round_user_betinfo.values():
  90. if result == 1:
  91. user.finance += user.betOptionAmounts[option] * odds_rate
  92. else:
  93. user.finance -= user.betOptionAmounts[option]
  94. banker_finance += current_round_income
  95. # 格式化一下,避免数字位数导致各种缩进
  96. with open("庄家盈亏记录.log", "a") as f:
  97. finalxx = f"庄家金币: {banker_finance / 100}¥ 本轮总收入: {current_round_income / 100}¥"
  98. print(finalxx)
  99. f.write(finalxx + "\n")
  100. # 每把结束存储数据,然后清空数据
  101. with open("bet_finance.log", "a") as f:
  102. time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  103. # 将user_dict 转成json字符串
  104. f.write(f"{time}:{json.dumps(round_user_betinfo, cls=UserEncoder)}\n")
  105. round_user_betinfo.clear()
  106. init_round_option_info()
  107. async def kickNotify(data, broadcast_func):
  108. print(f"被踢下线了: {data}")
  109. await broadcast_func('''CMD:
  110. setTimeout(function(){
  111. let btnDownNode = cc.find("Layer/PushNotice_panel/close_button");
  112. if (btnDownNode && btnDownNode.getComponent(cc.Button)) {
  113. btnDownNode.getComponent(cc.Button).clickEvents[0].emit([btnDownNode]);
  114. } else {
  115. console.error("节点未找到或节点上没有cc.Button组件");
  116. }
  117. },3000);
  118. setTimeout(function(){
  119. let btnDownNode = cc.find("Canvas/container/content/smallGame/createScrollView/view/cotent/row1/pokerNode/porkermaster/allHand");
  120. if (btnDownNode && btnDownNode.getComponent(cc.Button)) {
  121. btnDownNode.getComponent(cc.Button).clickEvents[0].emit([btnDownNode]);
  122. } else {
  123. console.error("没有找到扑克大师游戏节点");
  124. }
  125. // 点击扑克大师游戏线路1
  126. let pokerMasterGameLine1 = cc.find("Canvas/container/content/smallGame/New Node/listPokerMasterContent/main/view/content/item/main");
  127. if (pokerMasterGameLine1 && pokerMasterGameLine1.getComponent(cc.Button)) {
  128. pokerMasterGameLine1.getComponent(cc.Button).clickEvents[0].emit([pokerMasterGameLine1]);
  129. } else {
  130. console.error("未找到扑克大师游戏游戏节点1");
  131. }
  132. },5000);
  133. ''')
  134. def ShowOddsNotify(data):
  135. option_odds = data["option_odds"]
  136. for optionInfo in option_odds:
  137. option_ = optionInfo["option"]
  138. odds_ = optionInfo["odds"] / 100
  139. limit_red_ = optionInfo["limitRed"]
  140. # 打印信息
  141. print(f"选项: {option_}, 赔率: {odds_}, 限红: {limit_red_}, 总下注: {0}")
  142. round_option_info[option_] = BetOption(option_, odds_, limit_red_, 0)
  143. async def gameDataSynNotify(data):
  144. # print(f"同步游戏数据: {data}")
  145. sync_user = User(0, DATA_SYN_NOTIFY_UID, 0)
  146. for optionInfo in data["optionInfo"]:
  147. option_ = optionInfo["option"]
  148. odds_ = optionInfo["odds"] / 100
  149. limit_red_ = optionInfo["limitRed"]
  150. total_bet_ = optionInfo["totalBet"]
  151. # 打印信息
  152. print(f"同步下注选项: {option_}, 赔率: {odds_}, 限红: {limit_red_}, 总下注: {total_bet_}")
  153. round_option_info[option_] = BetOption(option_, odds_, limit_red_, total_bet_)
  154. # 虚拟用户,用来记录同步下来的下注数据,后续用于赔付
  155. sync_user.betOptionAmounts[option_] = total_bet_
  156. round_user_betinfo[DATA_SYN_NOTIFY_UID] = sync_user
  157. print(f"同步后下注信息:", round_option_info)
  158. async def MergeAutoBetNotify(data):
  159. print("收到合并通知")
  160. bet_notifys = data["notify"]
  161. for bet_notify in bet_notifys:
  162. await betNotify(bet_notify)
  163. async def betNotify(data):
  164. # {"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}
  165. # print(f"下注: {data}")
  166. # 获取用户ID
  167. uid = data["uid"]
  168. option = data["detail"]["option"]
  169. bet_amount = data["detail"]["betAmount"]
  170. # 获取用户信息
  171. user = round_user_betinfo.get(uid)
  172. if user is None:
  173. # 如果用户信息不存在,创建一个新的User对象
  174. user = User(0, "", 0)
  175. round_user_betinfo[uid] = user
  176. # 更新用户信息
  177. user.bet_count += 1
  178. user.uid = uid
  179. user.betAmount += bet_amount
  180. # 更新本轮下注选项的金额
  181. user.betOptionAmounts[option] += bet_amount
  182. # 更新本轮全部选项的金额
  183. round_option_info[option].total_bet += bet_amount
  184. print(f"用户{uid}下注次数: {user.bet_count}, 总金额: {user.betAmount}")
  185. round_user_betinfo[uid] = user
  186. def parse_message(message):
  187. # 分割消息类型和JSON字符串
  188. msg_type, json_str = message.split(':', 1)
  189. # 将JSON字符串转换为字典
  190. data = json.loads(json_str)
  191. # 返回解析结果
  192. return msg_type, data