async def send_message(self, node_name, command_id, data, session_id=None, to=None):
        """
        向指定连接发送消息
        :param node_name: string
        :param command_id: int
        :param message:
        :return:
        """
        if node_name not in self.conns.keys():
            logger.warn("can not find connection {}".format(node_name))
            return

        if ConnectionStatus.ESTABLISHED != self.conns[node_name]["status"]:
            # 连接断开状态
            logger.warn("connection is unavailable {}".format(node_name))
            for reconnect_times in range(3):
                await asyncio.sleep(5)
                if ConnectionStatus.ESTABLISHED == self.conns[node_name]["status"]:
                    break
                if 2 == reconnect_times:
                    logger.error("exceed max reconnect times {}".format(node_name))
                    return

        # if not isinstance(data, str):
        #     data = ujson.dumps(data)
        # print(data, data.encode("utf8"), type(data))
        await self.conns[node_name]["conn"].send_message(command_id, data, session_id=session_id , to=to)
        logger.debug("rpcserver send {0}".format(data))
        return 1
Exemple #2
0
def find_available_node(next_node_type, to=None):
    """
    寻找一个可用的节点,如果没有,则异步等待直到找到为止
    :param next_node_type:
    :param to: string, node name
    :return: connect node object id
    """
    logger.debug("find_available_node:{}".format(
        [next_node_type, to, RpcConnectionManager().conns]))
    while True:
        if to and to in RpcConnectionManager().conns.keys() and ConnectionStatus.ESTABLISHED == \
                RpcConnectionManager().conns[to]["status"]:
            # 如果明确传输的目标,且和目标节点有直接可用的rpc连接,则直接通过该连接发送消息;
            next_node = to
        else:
            if not next_node_type or NodeType.ROUTE == next_node_type:
                # 选取一个可用的route节点
                next_node = RpcConnectionManager().get_available_connection(
                    NodeType.ROUTE)
            else:
                next_node = RpcConnectionManager().get_available_connection(
                    next_node_type)
                if not next_node:
                    # 如果没有可用的next_node_type类型对应的节点, 则转发往路由节点
                    next_node = RpcConnectionManager(
                    ).get_available_connection(NodeType.ROUTE)

            if not next_node:
                logger.error("all route node dead!!!")
                # print("eeeeeeeee:", next_node_type, to, next_node)
                raise Exception()
                time.sleep(1)
                continue

        return next_node
Exemple #3
0
async def push_message(next_node_type,
                       command_id,
                       message,
                       session_id=None,
                       to=None):
    """
    向其他节点推送消息
    :param next_node_type: int, 接下来发往的节点类型
    :param command_id: int
    :param message: string, 消息内容
    :param session_id: string, 会话ID()
    :param to: string, 消息最终发往哪里,为空时则根据消息ID发送
    :return: None
    """
    if next_node_type == GlobalObject().type:
        # 参数错误,自己给自己发消息
        logger.error("send_message:", next_node_type, command_id, message,
                     session_id, to)
        raise Exception()

    next_node = SessionCache().get_node(session_id, next_node_type)
    if not next_node:
        next_node = find_available_node(next_node_type, to=to)
    SessionCache().add_cache(session_id,
                             node_type=next_node_type,
                             node_id=next_node)
    logger.debug("push_message:{}".format(
        [next_node, command_id, message, session_id, to]))
    await call_remote_service(next_node,
                              command_id,
                              message,
                              session_id=session_id,
                              to=to)
Exemple #4
0
 async def update_remote_rpc_config(self):
     """
     更新远程rpc连接
     :param server_type: int, 待更新的服务节点类型
     :param addr_info: dict, {host: port1, host2: port2, ...}
     :return:
     """
     for server_type, addr_info in GlobalObject().remote_ports.items():
         remote_names = [
             RpcConnectionManager.gen_node_name(k, v)
             for k, v in addr_info.items()
         ]
         for r in RpcConnectionManager().conns.keys():
             if r not in remote_names:
                 if RpcConnectionManager(
                 ).conns[r]["status"] == ConnectionStatus.ESTABLISHED:
                     RpcConnectionManager(
                     ).conns[r]["conn"].transport.close()
                 RpcConnectionManager().conns.pop(r)
         for k, v in addr_info.items():
             name = RpcConnectionManager.gen_node_name(k, v)
             if name not in RpcConnectionManager().conns.keys() \
                     or RpcConnectionManager().conns[name]["status"] != ConnectionStatus.ESTABLISHED:
                 RpcConnectionManager().add_type_node(server_type, k, v)
                 RpcConnectionManager().store_connection(k, v, None)
                 try:
                     await self.loop.create_connection(RpcPushProtocol,
                                                       host=k,
                                                       port=v)
                     logger.info("success connect to {}:{}".format(k, v))
                 except ConnectionRefusedError as e:
                     logger.error("try connect to {}:{} failed!")
Exemple #5
0
    def param_check(self, **kwargs):  # 参数验证
        act_params = kwargs.get("act_params")
        if 1 != len(act_params):
            # 同时只允许有一个玩家发生暗杠操作
            logger.debug(u"act_an_gang_error:%s", str(act_params))
            return

        seat_id = list(act_params.keys())[0]
        params = act_params[seat_id]
        # TODO 此处需要接受参数 用户选择暗杠牌值
        used_card = params.get("used_card")[0]
        # card_val = self.game_data.last_chu_card_val

        if not used_card:
            logger.error("an_gang params error: %s", str([seat_id, params]))
            return

        hand_card = self.players[seat_id].hand_card
        if 4 != hand_card.hand_card_info[Card.cal_card_type(used_card)][
                Card.cal_card_digit(used_card)]:
            logger.error("an_gang params error: %s", str([seat_id, params]))
            return

        self.seat_id = seat_id
        self.used_card = used_card
        return 1
Exemple #6
0
    def set_user_point(self, change_num):
        self.point += change_num
        ret, info = MUser.update_user_point(self.user_id, change_num)

        if self.point != info.get("point", ""):
            logger.error("set_user_point error! ({0}, {1})".format(
                self.user_id, change_num))
        return self.point
Exemple #7
0
def notify_web_server_restart():
    url = "http://127.0.0.1:8889/mj/restart_delete_room_info"
    params = {}
    r = requests.get(url, params)
    if r.status_code != 200:
        logger.error("web server left_room error paras = %s" % params)
        print("delete error!!")
        return
    data = json.loads(r.text)
    if data.get("ret"):
        raise Exception("web server left_room error ret = %s" % data.get("ret"))

    print("delete success!!")
Exemple #8
0
 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.DIAN_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
Exemple #9
0
    def decode_aes(self, msg):
        try:
            decode_msg = unpad(self.aes_obj.decrypt(msg))
        except Exception as e:
            logger.error("decode_aes error {}".format([msg]))
            return None

        msg_len = len(decode_msg)
        if msg_len == 0:
            return decode_msg

        try:
            json.loads(decode_msg)
        except ValueError:
            return None
        return decode_msg
Exemple #10
0
    def execute(self):
        """
        定庄
        :return:
        """
        logger.debug(u"定庄: %s", str([]))
        dice = []
        if -1 == self.game_data.banker_seat_id:
            # 初始时
            dice = self.get_random_dice()
            self.game_data.banker_seat_id = (dice[0] + dice[1] -
                                             1) % self.max_player_num
        else:
            if not self.game_data.hu_player_static:
                # 上局为流局/荒庄, 则随机定庄
                dice = self.get_random_dice()
                self.game_data.banker_seat_id = (dice[0] + dice[1] -
                                                 1) % self.max_player_num
            else:
                source = -1
                for seat_id, params in self.game_data.hu_player_static.items():
                    self.game_data.banker_seat_id = seat_id
                    source = params.get("source", -1)
                if 1 < len(self.game_data.hu_player_static):
                    # 一炮多响, 点炮的人做庄
                    if -1 == source:
                        logger.error("gen_banker error: %s",
                                     str(self.game_data.hu_player_static))
                        raise Exception()
                    self.game_data.banker_seat_id = source
        # 重置胡牌相关信息
        self.game_data.reset_hu_static()

        notify_all_desk_player(self.desk_id,
                               message_ids.PUSH_GEN_BANK,
                               data={
                                   "bank_seat_id":
                                   self.game_data.banker_seat_id,
                                   "dice": dice
                               })
        # 清理上一局信息
        self.game_data.reset_game_data()
        # 洗牌
        self.card_dealer.shuffle_card()
        # 将庄家位置存入game_data
        self.game_data.last_chu_card_seat_id = self.game_data.banker_seat_id
Exemple #11
0
 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
Exemple #12
0
    def param_check(self, seat_id, params, config_params):  # 参数验证
        hook_seat_id = params.get("hook_seat_id", -1)

        if not self.game_data.last_chu_card_val:
            logger.error("dian_hu params error: %s", str([seat_id, params]))
            return

        hand_card_vals = self.players[seat_id].hand_card.hand_card_vals
        # if 1 != len(hand_card_vals) % 3 or not self.players[seat_id].can_hu_result:
        if 1 != len(hand_card_vals) % 3:
            logger.error("dian_hu params error: %s", str([seat_id, params]))
            return

        self.seat_id = seat_id
        self.hook_seat_id = hook_seat_id
        self.hand_card = self.game_data.players[seat_id].hand_card
        self.dian_hu_card = self.game_data.last_chu_card_val
        return 1
Exemple #13
0
    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 = list(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
Exemple #14
0
    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 = list(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
Exemple #15
0
    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
Exemple #16
0
async def call_target(command_id, data, session_id):
    """
    调用注册的消息处理
    :param command_id:
    :param data:
    :param session_id:
    :return:
    """
    obj = RegisterEvent.events.get(command_id, None)
    obj = obj if obj else RegisterEvent.events.get(DEFAULT_ID,
                                                   None)  # 如果没有,则进入默认消息处理
    if not obj:
        logger.error("command_id {} not register!".format(command_id))
        return

    handler = obj.get("handler")(data, command_id, session_id)
    ret = await handler.execute()
    logger.debug("local call target result={}".format(ret))
    if ret and obj.get("need_return"):  # 空消息不做推送
        to, _ = session_id.split("_")
        await push_message(None, command_id, ret, session_id, to)
Exemple #17
0
    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 = list(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
Exemple #18
0
 def execute(self, act_params={}):
     """
     执行点炮胡牌
     :param act_params:
     :return:
     """
     logger.debug(u"点炮胡牌: %s", str(act_params))
     for seat_id, params in act_params.items():
         for step in self.game_config.player_act_step.get(Act.DIAN_HU):
             for name, cfg in step.items():
                 ret = self.step_handlers.get(name)(seat_id=seat_id,
                                                    params=params,
                                                    config_params=cfg)
                 if not ret:
                     logger.error("step:%s", step)
                     return
         if not self.game_config.has_tong_pao:
             # 如果不能通炮胡,则只取第一个胡牌的玩家
             break
     self.settle(settle_type_list=[SettleType.HU])
     if self.game_config.is_hu_end:
         # 当回合胡牌后结束当局游戏
         self.end_game()
     return 1
Exemple #19
0
 async def execute(self, *args, **kwargs):
     logger.info("login_handler:{}  {}".format(args, kwargs))
     user_id = self.params.get("user_id", -1)
     passwd = self.params.get("passwd", "")
     if -1 == user_id or not passwd:
         return {}
     login_result = route_ins.login(user_id=user_id,
                                    passwd=passwd,
                                    new_sessionid=self.session_id,
                                    data=self.params)
     print("login_result:", login_result)
     if 200 == login_result.get('code'):
         info = login_result.get("info")
         old_session = info.get("old_session")
         if old_session and self.session_id != old_session:
             # 踢掉之前用户
             to, _ = old_session.split("_")
             data = error_response(USER_LOGIN_OTHER_DEVICE)
             await push_message(NodeType.PROXY, USER_LOGIN_OTHER_DEVICE,
                                data, old_session, to)
         return login_result
     else:
         logger.error("process_login: unknown error:%s", str(login_result))
         return login_result
Exemple #20
0
    def param_check(self, **kwargs):      # 参数验证
        act_params = kwargs.get("act_params")
        # if 1 != len(act_params):
        #     # 同时只允许有一个玩家发生补杠牌操作
        #     logger.debug(u"act_bugang_error:%s", str(act_params))
        #     return

        seat_id = list(act_params.keys())[0]
        params = act_params[seat_id]
        # TODO 此处需要接受参数 用户选择暗杠牌值
        used_card = params.get("used_card")[0]

        if not used_card:
            logger.error("bu_gang card_val is none error: %s", str([self.seat_id, params]))
            return

        hand_card = self.players[seat_id].hand_card
        if 1 != used_card and [used_card, used_card, used_card] not in hand_card.peng_card_vals:
            logger.error("bu_gang card_val not in peng_card_val error: %s", str([self.seat_id, params]))
            return

        self.bugang_cardval = used_card
        self.seat_id = seat_id
        return 1
Exemple #21
0
 def execute(self, seat_id, card_num=1, is_last=False):
     """
     执行摸牌
     :param seat_id:
     :param card_num:
     :param is_last:
     :return:
     """
     logger.debug(u"摸牌: %s", str([seat_id, card_num, is_last]))
     print("### sid=%s draw_card len=%s hand-card =%s ," %
           (seat_id, len(self.players[seat_id].hand_card.hand_card_vals),
            self.players[seat_id].hand_card.hand_card_vals))
     for step in self.game_config.draw_card_step:
         for name, cfg in step.items():
             ret = self.step_handlers.get(name)(seat_id=seat_id,
                                                card_num=card_num,
                                                is_last=is_last,
                                                config_params=cfg)
             if not ret:
                 logger.error("step:%s", step)
                 return
             elif ret != 1:
                 return 0
     return 1
Exemple #22
0
 async def schedule(self):
     # 定时rpc断线重连
     while True:
         await asyncio.sleep(3)
         # logger.info("start new schedule task~")
         # print("schedule:", RpcConnectionManager().type_dict, RpcConnectionManager().conns)
         for node_type, name_lst in RpcConnectionManager().type_dict.items(
         ):
             for name in name_lst:
                 if name not in RpcConnectionManager().conns.keys()\
                         or ConnectionStatus.ESTABLISHED != RpcConnectionManager().conns[name]["status"]:
                     host = RpcConnectionManager().conns[name]["host"]
                     port = RpcConnectionManager().conns[name]["port"]
                     try:
                         logger.debug("try to reconnect:{}".format(
                             [name, host, port]))
                         await self.loop.create_connection(RpcPushProtocol,
                                                           host=host,
                                                           port=port)
                         logger.info("success connect to {}:{}".format(
                             host, port))
                     except ConnectionRefusedError as e:
                         logger.error(
                             "schedule try connect to {}:{} failed!")
Exemple #23
0
    def param_check(self, **kwargs):  # 参数验证
        act_params = kwargs.get("act_params")
        if 1 != len(act_params):
            # 同时只允许有一个玩家发生吃牌操作
            logger.debug(u"act_chi_error:%s", str(act_params))
            return

        seat_id = list(act_params.keys())[0]
        params = act_params[seat_id]

        card_val = self.game_data.last_chu_card_val
        used_cards = params.get("used_card", [])
        # 接受三张牌,用户吃的牌, 出去被吃的牌做处理
        if card_val not in used_cards:
            logger.error("chi card val not in used_cards params error: %s",
                         str([seat_id, params]))
            return
        used_cards.remove(card_val)
        if not card_val or 2 != len(used_cards):
            logger.error("chi params error: %s", str([seat_id, params]))
            return

        hand_card_vals = self.players[seat_id].hand_card.hand_card_vals
        if used_cards[0] not in hand_card_vals or used_cards[
                1] not in hand_card_vals:
            logger.error("chi params error: %s", str([seat_id, params]))
            return

        cards = [card_val, used_cards[0], used_cards[1]]
        cards.sort()
        if not self.card_analyse.shun(cards):
            logger.error("chi params error: %s", str([seat_id, params]))
            return

        self.used_cards = used_cards
        self.chi_group = cards
        self.seat_id = seat_id
        return 1
Exemple #24
0
 def connection_lost(self, error):
     if error:
         logger.error('ERROR: {}'.format(error))
     else:
         logger.debug('closing')
     super().connection_lost(error)