def forwarding_0(keyname, _conn, data): """ 选择一个 :param keyname: :param _conn: :param data: :return: """ session_id = "%s,%d" % (server_name, _conn.transport.sessionno) gate_name = get_gate_name(_conn.transport.sessionno) print "aaaaaaaaaaaaaaaaaaaaaAA:", data data = convert_to_json(data) logger.debug(u"forwarding_0: %s, %s", str(keyname), str(data)) defered = forward_to_gate(gate_name, keyname, session_id, data) def on_time_out(a, b): logger.warn("%s is time out!" % gate_name) for node in GlobalObject().json_config["remoteport"]: if node["rootname"] == gate_name: node["is_available"] = False return forward_to_gate(get_gate_name(_conn.transport.sessionno), keyname, session_id, data) defered.addTimeout(200, reactor, on_time_out) return defered
def param_check(self, **kwargs): # 参数验证 act_params = kwargs.get("act_params") if 1 != len(act_params): # 同时只允许有一个玩家发生点杠操作 logger.debug(u"act_diangang_error:%s", str(act_params)) return seat_id = act_params.keys()[0] params = act_params[seat_id] card_val = self.game_data.last_chu_card_val if not card_val or -1 == self.game_data.last_chu_card_seat_id: logger.error("dian_gang params error: %s", str([seat_id, params])) return hand_card = self.players[seat_id].hand_card if 3 != hand_card.hand_card_info[Card.cal_card_type(card_val)][ Card.cal_card_digit(card_val)]: logger.error("dian_gang params error: %s", str([seat_id, params])) return self.seat_id = seat_id self.hand_card = self.game_data.players[seat_id].hand_card return 1
def get_last_card(self, seat_id, card_list): if not self.game_data.game_config.test_mode: self.notify_player_card_change(seat_id, code=CANT_USE_TEST) return logger.debug(u"获取最后一张牌:%s", str([seat_id, card_list])) last_card = self.game_data.card_dealer.get_the_last_card() self.notify_player(seat_id, [last_card])
def cache_act(self, seat_id, act_type, act_params): """ 缓存动作,用于判断动作优先级 :param seat_id: :param act_type: :param act_params: :return: """ if not self.game_data.cur_players_to_act.get(seat_id, []): notify_single_user(self.game_data.desk_id, seat_id, command_id=PUSH_CALL_CARD, data={"desc": "current user can't do anything"}, code=CUR_USER_CANT_SPEAK) return if act_type not in self.game_data.cur_players_to_act[seat_id]: return act_params.update(self.game_data.cur_players_acted[seat_id] [act_type]) # 待执行动作结果中可能存储了部分局部信息 self.game_data.del_player_to_act(seat_id) self.game_data.add_player_acted(seat_id, act_type, act_params) logger.debug( u"cache__act: %s", str([ self.game_data.cur_players_to_act, self.game_data.cur_players_acted ])) return 1
def bu_hua(self, seat_id, card_list=[]): """检查是否补花""" hua_card = [] tmp_card_list = copy.deepcopy(card_list) for c in tmp_card_list: if CardType.HUA == Card.cal_card_type(c): hua_card.append(c) card_list.remove(c) if not hua_card: return 0 logger.debug(u"发牌补花:%d", len(hua_card)) new_cards = [] temp_hua = copy.deepcopy(hua_card) while temp_hua: cards = self.card_dealer.draw_cards(num=len(temp_hua), is_last=True) temp_hua = [] for c in cards: if CardType.HUA == Card.cal_card_type(c): temp_hua.append(c) hua_card.append(c) else: new_cards.append(c) card_list.extend(new_cards) # 将补花数量添加进手牌中 hua_card_vals 中 self.players[seat_id].hand_card.hua_card_vals.extend(hua_card) for p in self.players: if p.seat_id == seat_id: notify_single_user(self.desk_id, p.seat_id, messageids.PUSH_GAME_DEAL_BU_HUA, data={"seat_id": seat_id, "hua_card": hua_card, "bu_cards": new_cards}) else: notify_single_user(self.desk_id, p.seat_id, messageids.PUSH_GAME_DEAL_BU_HUA, data={"seat_id": seat_id, "hua_card": hua_card, "bu_cards": [BLACK]*len(new_cards)}) return 1
def notify_some_player(self, desk_id, seat_id, act_info={}, interval=1000, max_player_num=4, exclude=[]): """ 推送给桌子上的某些用户, 用于玩家执行动作后的推送 :param desk_id: 桌子ID :param seat_id: 执行动作的玩家位置 :param act_info: 详细动作参数 {act_type:[card_val]} :param interval: 延迟时间 :param exclude: 可以排除推送的作为ID, [seat_id,1] :return: """ logger.debug(u"通知桌子上某些玩家: %s", str([exclude, act_info, interval])) target_seat_id = act_info.get("seat_id") act = act_info.keys()[0] for i in xrange(max_player_num): if not i in exclude: if i != target_seat_id and act == 60: act_info["card_list"] = [] notify_single_user(desk_id, i, PUSH_OTHER_PLAYER_CALL_CARD, act_info)
def notify_player(self, desk_id, seat_id, act_info={}, interval=1000, t_type=TimerType.NORMAL, command_id=PUSH_CALL_CARD, code=200): """ :param desk_id: :param seat_id: :param act_info: 玩家可进行的操作信息{act_type:params, ...} :param interval: :return: """ logger.debug(u"通知玩家进行操作: %s", str([seat_id, act_info, interval])) data = {"seat_id": seat_id, "act_info": act_info} notify_single_user(desk_id, seat_id, command_id, data, code) timer_manager_ins.add_timer( desk_id, seat_id, interval, t_type=t_type, call_type=CallbackFuncType.FUNC_AUTO_PLAYER_ACT, call_params={ "seat_id": seat_id, "act_info": act_info })
def system_act(self, act_type, act_params={}): print "system_act act_params=", act_params if act_type not in self.handler.keys(): logger.debug(u"system_act param error:%s", str([act_type, act_params])) return return self.handler.get(act_type)(act_params)
def param_check(self, **kwargs): # 参数验证 act_params = kwargs.get("act_params") if 1 > len(act_params) or not self.game_data.next_speaker_callback: logger.debug(u"act_guo_error:%s", str([act_params, self.game_data.next_speaker_callback])) return self.seat_id = act_params.keys()[0] return 1
def forwarding_game(key, session_id, data): """ 消息转发给游戏节点 :param key: 消息id :param session_id: :param data: json串, 里面必须包含userid :return: """ logger.debug(u"forwarding_game:%s", str([key, session_id, data])) user_id = data.get("user_id", -1) passwd = data.get("passwd", -1) if -1 == user_id and key not in [USER_OFFLINE]: print "forwarding_game user_id =", user_id return if USER_LOGIN == key: logger.debug(u"forwarding_game2:%s", str([key, session_id, data])) return process_login(user_id, passwd, session_id, data) if session_id in ROUTE_CACHE.keys(): room_name = ROUTE_CACHE[session_id]["room"] data.update({"gate_name": GATE_NAME}) return GlobalObject().root.callChildByName(room_name, "forwarding_game", key, session_id, data) route_info = route_ins.get_route(user_id, session_id=session_id) print "route_info:", route_info if 200 == route_info.get('code'): data.update({"gate_name": GATE_NAME}) room_name = route_info['info'].get("room") return GlobalObject().root.callChildByName(room_name, "forwarding_game", key, session_id, data) else: return
def execute(self, seat_id, act, card_list): """ 执行测试换牌 :param act_params: :return: """ logger.debug(u"測試换牌: %s", str([seat_id, act, card_list])) return self.handlers.get(act)(seat_id, card_list)
def execute(self, desk_id, seat_id, call_type, call_params): tid = self.tmhash(desk_id, seat_id) if not self.timer_dict.get(tid, None): return self.kill_timer(desk_id, seat_id, is_force=True) logger.debug(u"kill_timer:%s", str([desk_id, seat_id, call_type, call_params])) return CallbackManager.get_instance(desk_id).execute( call_type, call_params)
def call_player_act(self, call_params={}): from game.mahjong.models.playeract.player_act_manager import PlayerActManager seat_id = call_params.get("seat_id") act_type = call_params.get("act_type") act_params = call_params.get("act_params") if -1 == seat_id: logger.debug(u"call_player_act: error:%s", str(call_params)) return return PlayerActManager.get_instance(self.desk_id).execute_player_act( seat_id, act_type, act_params=act_params)
def handle_player_act(self, seat_id, act_type, act_params): """ 玩家选择进行的操作 :param seat_id: :param act_type: :param act_params: :return: """ logger.debug(u"handle_player_act: %s", [seat_id, act_type, act_params]) return PlayerActManager.get_instance(self.desk_id).player_act( seat_id, act_type, act_params)
def execute_system_act(self, act_type, act_params): """ 执行系统指定的行为 :param act_type: :param act_params: :return: """ logger.debug(u"execute_system_act: %s", [act_type, act_params]) ret = SystemActManager.get_instance(self.desk_id).system_act( act_type, act_params=act_params) self.go_next_act(act_type)
def execute(self, cur_seat_id, card_val): """ 执行检查 :param cur_seat_id: :param card_val: :return: """ logger.debug(u"检查是否有其他玩家可以操作: %s", str([cur_seat_id, card_val])) for i in xrange(self.max_player_num): if i == cur_seat_id: continue self._check(i, card_val)
def execute(self, act_params={}): """ 执行补杠 :param act_params: :return: """ logger.debug(u"补杠: %s", str(act_params)) for step in self.game_config.player_act_step.get(Act.BU_GANG): for name, cfg in step.items(): ret = self.step_handlers.get(name)(act_params=act_params, config_params=cfg) if not ret: logger.error("step:%s", step) return return 1
def notify_other_player(self, **kwargs): # 记录玩家动作 act_info = { "seat_id": self.seat_id, "act_type": Act.CHU, "card_list": [self.chu_cardval] } self.notify_other_player_act_executed( self.seat_id, act_info=act_info, max_player_num=self.game_data.max_player_num) logger.debug( u"seat_id=%s, hand_card=%s len=%s" % (self.seat_id, self.players[self.seat_id].hand_card.hand_card_vals, len(self.players[self.seat_id].hand_card.hand_card_vals))) return 1
def execute(self, act_params={}): """ 执行吃牌 :param act_params: :return: """ logger.debug(u"吃牌: %s", str(act_params)) print "CHI EXECUTE self.game_config.player_act_step=", self.game_config.player_act_step print "CHI_step=", self.game_config.player_act_step.get(Act.CHI) for step in self.game_config.player_act_step.get(Act.CHI): for name, cfg in step.items(): ret = self.step_handlers.get(name)(act_params=act_params, config_params=cfg) if not ret: logger.error("step:%s", step) return return 1
def huan_card(self, seat_id, test_params): if not self.game_data.game_config.test_mode: self.notify_player_card_change(seat_id, code=CANT_USE_TEST) return logger.debug(u"换牌:%s", str([seat_id, test_params])) old_card = test_params.get("source_card")[0] new_card = test_params.get("target_card")[0] if not old_card or not new_card: self.notify_player_card_change(seat_id, code=NEED_S_CARD_T_CARD) return if not self.players[seat_id].hand_card.has_card(old_card): self.notify_player_card_change(seat_id, code=CARD_NOT_IN_HAND_CARD) return self.players[seat_id].hand_card.del_hand_card_by_val(card_val=old_card) self.players[seat_id].hand_card.add_hand_card_by_vals( card_vals=[new_card]) self.notify_player_card_change(seat_id)
def execute(self): """ 初始发牌 :return: """ logger.debug(u"初始发牌: %s", str([])) card_results = [] for i in xrange(self.max_player_num): drew_card_vals = self.card_dealer.draw_cards(num=13) # 处理测试初始化发牌 if GlobalConfig().test_sure_next_cards.get(self.desk_id): test_cards = GlobalConfig().test_sure_next_cards[self.desk_id][i] if test_cards: min_len = min(len(test_cards),len(drew_card_vals)) for index in xrange(min_len): drew_card_vals[index] = test_cards[index] # 测试初始化发牌结束 card_results.append(drew_card_vals) for x in self.players: result = [] for y in self.players: if x.seat_id == y.seat_id: data = {"seat_id": y.seat_id, "card_list": card_results[y.seat_id]} else: data = {"seat_id": y.seat_id, "card_list": [BLACK]*13} result.append(data) notify_single_user(self.desk_id, x.seat_id, messageids.PUSH_DEAL_CARD, data={"card_list": result}) for x in self.players: if self.game_config.draw_card_bu_hua: self.bu_hua(x.seat_id, card_results[x.seat_id]) # 发牌时候同时将牌添加入手牌 print "card_results[%s] = %s len=%s" % (x.seat_id, card_results[x.seat_id], len(card_results[x.seat_id])) self.players[x.seat_id].hand_card.add_hand_card_by_vals(card_results[x.seat_id]) # 添加玩家动作, Waite_answer # for i in xrange(self.game_data.max_player_num): # self.game_data.add_player_to_act(i, Act.WAITE_ANSWER) # 添加超时回调 self.game_data.next_speaker_callback = {"type": CallbackFuncType.FUNC_NOTIFY_PLAYER_ACT, "call_params": { "seat_id": self.game_data.banker_seat_id, "interval": self.get_act_wait_time(self.game_data.banker_seat_id, Act.WAITE_ANSWER), "act_info": {}}} return 1
def call_auto_player_act(self, call_params={}): from game.mahjong.models.playeract.player_act_manager import PlayerActManager seat_id = call_params.get("seat_id") act_info = call_params.get("act_info", {}) if not act_info or -1 == seat_id: logger.debug(u"call_auto_player_act: error:%s", str(call_params)) return acts = act_info.keys() tmp = list( set(acts).intersection(self.game_data.game_config.auto_act_list)) if tmp: # 自动执行的操作 tmp.sort(reverse=True) a = tmp[0] b = act_info.get(tmp[0]) print "auto_player_act:", seat_id, a, b return PlayerActManager.get_instance(self.desk_id).player_act( seat_id, tmp[0], act_params=act_info.get(tmp[0]))
def player_act(self, seat_id, act_type, act_params={}): """ 玩家发送过来的操作只有在所有玩家的操作都达到后,才会真正决定是否执行 :return: """ # 如果是 watie_answer直接执行 if act_type == Act.WAITE_ANSWER: if not self.game_data.state_machine.is_waite_answer: self.game_data.state_machine.change_state( GameingStatus.REV_FIRST_ANSWER) self.handler[act_type]() return # 保存玩家回馈的动作参数变动 self.game_data.add_player_acted(seat_id, act_type, act_params) print "player_act:", seat_id, act_type, act_params if act_type not in self.handler.keys() or not self.cache_act( seat_id, act_type, act_params): logger.debug(u"player_act error:act_type=%s", str(act_type)) return if 0 == len(self.game_data.cur_players_to_act): # 所有玩家都已进行过操作, 开始执行缓存中的操作, 只执行优先级最高的 max_priority_act = Act.GUO need_run_act = {"act_type": max_priority_act, "detail": {}} # {"act_type": Act.GUO, "detail":{seat_id: act_params, ...}} for tmp_seatid, info in self.game_data.cur_players_acted.items(): acted_type = info.keys()[0] if info[acted_type] >= need_run_act["act_type"]: need_run_act["act_type"] = info[acted_type] need_run_act["detail"][tmp_seatid] = info[acted_type] self.game_data.cur_players_acted = {} # 钩子是否截获行为判断 if not self.hook.hook(seat_id, act_type, act_params): return 2 return self.handler[act_type](need_run_act["detail"]) else: # 動作暫時緩存,等待其他玩家操作 if act_type == self.get_cur_player_max_act(): logger.debug(u"获得最高优先级动作, 立刻出发执行效果! 最高优先级动作=%s" % act_type) ret = self.handler[act_type]( self.game_data.cur_players_acted[seat_id][act_type]) # 動作暫時緩存,等待其他玩家操作 return 2
def param_check(self, **kwargs): # 参数验证 act_params = kwargs.get("act_params") if 1 != len(act_params): # 同时只允许有一个玩家发生吃牌操作 logger.debug(u"act_ting_error:%s", str(act_params)) return seat_id = act_params.keys()[0] params = act_params[seat_id] chu_card = params.get("chu_card") if 0 > seat_id or seat_id >= self.max_player_num or chu_card not in self.players[ seat_id].can_ting_info.keys(): logger.error("ting params error: %s", str([seat_id, params])) return self.chu_card_val = chu_card self.seat_id = seat_id return 1
def param_check(self, **kwargs): # 参数验证 act_params = kwargs.get("act_params") if 1 != len(act_params): # 同时只允许有一个玩家发生自摸操作 logger.debug(u"act_zimo_error:%s", str(act_params)) return seat_id = act_params.keys()[0] params = act_params[seat_id] hand_card_vals = self.players[seat_id].hand_card.hand_card_vals # if 2 != len(hand_card_vals) % 3 or not self.players[seat_id].can_hu_result: if 2 != len(hand_card_vals) % 3: logger.error("dian_hu params error: %s", str([seat_id, params])) return self.seat_id = seat_id self.hand_card = self.players[seat_id].hand_card return 1
def get_gate_name(sessionno): """ 获取一个可用的消息转发gate节点 :param sessionno: int :return: """ gate_configs = GlobalObject().json_config["remoteport"] available_gates = [ x["rootname"] for x in gate_configs if x.get("is_available") ] if sessionno in session_gate_map.keys(): gate = session_gate_map.get(sessionno) if gate in available_gates: return gate logger.debug(u"get_gate_name:%s", str([sessionno, available_gates])) gate = random.choice(available_gates) session_gate_map[sessionno] = gate return gate
def execute(self, act_params={}): """ 执行自摸 :param act_params: :return: """ logger.debug(u"自摸胡牌: %s", str(act_params)) for step in self.game_config.player_act_step.get(Act.ZI_MO): for name, cfg in step.items(): ret = self.step_handlers.get(name)(act_params=act_params, config_params=cfg) if not ret: logger.error("step:%s", step) return self.settle(settle_type_list=[SettleType.HU]) if self.game_config.is_hu_end: # 当回合胡牌后结束当局游戏 self.end_game() return 1
def notify_some_player_ting(self, desk_id, seat_id, act_info={}, interval=1000, max_player_num=4): """ 推送给桌子上的某些用户, 用于玩家执行听牌后的推送 :param desk_id: 桌子ID :param seat_id: 执行动作的玩家位置 :param act_info: 详细动作参数 {act_type:[card_val]} :param interval: 延迟时间 :return: """ logger.debug(u"通知桌子上某些玩家: %s", str([desk_id, seat_id, act_info, interval])) act = act_info.keys()[0] for i in xrange(max_player_num): notify_single_user(desk_id, i, PUSH_OTHER_PLAYER_CALL_CARD, act_info)
def sure_next_cards(self, seat_id, test_params): if not self.game_data.game_config.test_mode: self.notify_player_card_change(seat_id, code=CANT_USE_TEST) return card_list = test_params.get("target_card") if not isinstance(card_list, list): self.notify_player_card_change(seat_id, TEST_PARAMS_ERROR) return logger.debug(u"确定接下来的牌:%s", str([seat_id, card_list])) if GlobalConfig().test_sure_next_cards.get(self.desk_id): GlobalConfig().test_sure_next_cards[self.desk_id][seat_id].extend( card_list) else: GlobalConfig().test_sure_next_cards[self.desk_id] = [ [] for _ in xrange(self.game_data.max_player_num) ] GlobalConfig().test_sure_next_cards[self.desk_id][seat_id].extend( card_list) self.notify_player_next(seat_id)
def add_timer(self, desk_id, seat_id, interval, t_type=TimerType.NORMAL, call_type=None, call_params={}): """ 添加定时任务 :param desk_id: :param seat_id: :param interval: :param call_type: :param args: :param kwargs: :return: """ logger.debug( u"add_timer: %s", str([desk_id, seat_id, interval, t_type, call_type, call_params])) tid = self.tmhash(desk_id, seat_id) t_task = self.timer_dict.get(tid, None) print "add_timer", tid, t_task if t_task is not None: self.kill_timer(desk_id, seat_id) self.timer_dict[tid] = { "type": t_type, "end_time": time.time() + interval, "call_type": call_type, "params": call_params, "call": self.call_later(interval, self.execute, desk_id, seat_id, call_type, call_params) } return 1