def OnClientCommonMsg(self, connect_id, str_msg): msg = msgpack.unpackb(str_msg) logger.GetLog().debug('gateway on client common msg : connect id = %s, msg = %s' % (connect_id, msg)) cmd = msg.get(proto_def.field_name_cmd, None) if cmd is None: logger.GetLog().warn('gateway on client common msg unexpected cmd : %s' % cmd) else: if cmd == proto_def.cg_login_server: # 登录服务器 msg_obj = CGLoginServerRequest.new_from_data(msg) ModObjFac.CreateApp().get_msg_manager().handle_user_login_server(connect_id, msg_obj) elif cmd == proto_def.cg_get_online_num: ModObjFac.CreateApp().get_msg_manager().handle_get_online_num(connect_id) elif cmd == proto_def.cg_game_server_register: # 游戏服登录 msg_obj = CGGameServerRegisterRequest.new_from_data(msg) ModObjFac.CreateApp().get_msg_manager().handle_game_server_register(connect_id, msg_obj) else: logger.GetLog().warn('gateway on client common msg unexpected cmd : %s' % cmd)
def send_msg_to_server_node(self, client_type, msg_str, *args): # gateway的服务器节点: monitor server_node_id = self.get_node_type_by_client_type(client_type) if server_node_id == ModTopo.NODE_TYPE.MONITOR: game.SendMsgToServer(client_type, ModTopo.PROTO_TYPE.COMMON, msg_str) else: logger.GetLog().error( 'send msg to an unexpected server node : %s, %s, %s' % (client_type, msg_str, args))
def OnUpdateTeamListItemMemCount(self, server_group_id, team_id, mem_count): """ 同步队伍列表中队伍成员数量 """ logger.GetLog().debug( 'syn update team list item mem count: %s, %s, %s' % (server_group_id, team_id, mem_count)) self.get_team_manager().update_team_list_item_mem_count( server_group_id, team_id, mem_count)
def TestGameServerLogin(self): req = CGGameServerRegisterRequest() req.rk_zone = 'test_game_server' import hashlib md5 = hashlib.md5() md5.update(req.rk_zone + proto_def.game_notice_check_md5_ticket) req.sign = md5.hexdigest() req_dump = req.dump() logger.GetLog().debug('TestGameServerLogin req: %s' % req_dump) self.SendCommonMsg(req_dump)
def OnServerDisconnect(self, client_type): # 先删除字典记录的server信息 server_node_type = self.get_node_type_by_client_type(client_type) if server_node_type in self.connect_server_dict: self.connect_server_dict[server_node_type].pop(client_type, None) # 各种节点处理 if server_node_type == ModTopo.NODE_TYPE.MONITOR: # 如果是Monitor断开, 尝试重连 logger.GetLog().error('Monitor Node Disconnected, Try to Connect') self._start_connect_monitor()
def TestP2PChat(self, args=None): self.chatTimes += 1 req = CGSendChatMsgRequest() req.channel_type = chat_def.CHAT_CHANNEL_TYPE_P2P req.receiver_id = self.get_test_param('p2p_receiver') req.data = 'P2P Chat --- i am user : %s, times %d' % ( self.get_test_param('user_id'), self.chatTimes) req_dump = req.dump() logger.GetLog().debug('TestP2PChat req : %s' % req_dump) self.SendChatMsg(req_dump)
def TestPublicNotice(self, args=None): req = CGGameServerNotice() req.server_id = self.get_test_param('server_id') req.channel_type = chat_def.CHAT_CHANNEL_TYPE_NOTICE req.data = 'Public Notice --- From Test Client : %s' % self.config.get( 'AppId', None) # 计算验证key req_dump = req.dump() logger.GetLog().debug('TestPublicNotice req : %s' % req_dump) self.SendChatMsg(req_dump)
def _get_user_map_channel_id(self, server_user_id): if server_user_id in self.user_map_channel: server_group_id, channel_id = self.user_map_channel[server_user_id] if server_group_id in self.channel_map_node and channel_id in self.channel_map_node[ server_group_id]: return channel_id logger.GetLog().warn( 'user has map channel but data not in channel_map_node : %s, %s' % (server_group_id, channel_id)) return None
def handle_user_login_server(self, connect_id, msg_obj): logger.GetLog().info('user login server : %s, %s, %s, %s' % (connect_id, msg_obj.server_user_id, msg_obj.server_id, msg_obj.sign)) res_obj = CGLoginServerResponse() res_obj.return_code = excp.ExceptionSuccess.code gateway_app = ModObjFac.CreateApp() # 校验登录参数 if not self.check_login_sign(msg_obj.server_user_id, msg_obj.server_id, msg_obj.sign): # 校验失败 res_obj.return_code = excp.ExceptionCheckLoginFailed.code else: # 校验成功 server_group_id = get_server_group_id(msg_obj.server_id) # TODO: 先将现有连接主动断掉? # 移除旧连接 old_connect_id = gateway_app.get_conn_id_by_char_id( msg_obj.server_user_id) if old_connect_id != -1: gateway_app.del_connect(server_group_id, msg_obj.server_user_id, old_connect_id) # 增加连接信息 gateway_app.add_connect(server_group_id, msg_obj.server_user_id, connect_id) # 同步玩家在线状态到各个chat server,更新在线人数 gateway_app.get_gateway_2_chat_proxy_rpc( ).OnUserOnlineStatusUpdate( server_group_id, msg_obj.server_user_id, connect_id, True, gateway_app.get_client_connect_ip(connect_id)) # 推送玩家在线状态给team server gateway_app.get_gateway_2_team_proxy_rpc( ).OnUserOnlineStatusUpdate(server_group_id, msg_obj.server_user_id, True) # # 推送玩家在线状态给scene server # gateway_app.get_gateway_2_scene_proxy_rpc().OnUserOnlineStatusUpdate(server_group_id, msg_obj.server_user_id, True) res_msg = res_obj.dump() logger.GetLog().debug('user login server res : %s' % res_msg) # 返回信息给客户端 gateway_app.send_msg_to_client(connect_id, ModTopo.PROTO_TYPE.COMMON, msgpack.packb(res_msg))
def OnChatMsg(self, server_group_id, server_user_id, str_msg): msg = msgpack.unpackb(str_msg) logger.GetLog().debug( 'chat server receive msg: %s, %s, %s' % (server_group_id, server_user_id, len("%s" % msg))) cmd = msg.get(proto_def.field_name_cmd, None) if cmd is None: logger.GetLog().warn('format of this chat msg is unexpected : %s' % msg) else: if cmd == proto_def.cg_send_chat: # 发送聊天消息 self._handle_chat_msg(server_group_id, server_user_id, msg) elif cmd == proto_def.cg_get_offline_msg: # 获取离线数据 self._handle_get_offline_msg(server_group_id, server_user_id, msg) elif cmd == proto_def.cg_offline_msg_confirm: # 离线消息确认 self._handle_confirm_offline_msg(server_user_id, msg) else: logger.GetLog().warn( 'chat server receive unexpected cmd msg : %s' % msg)
def db_friend(): global _db_friend if not _db_friend: logger.GetLog().info('DB:friend:Connecting: {0}'.format( common_config.couchbase_host_game)) _db_friend = _db_connector( bucket=common_config.get_bucket_name('friend'), host=common_config.couchbase_host_game) return _db_friend
def handle_battle_msg(self, server_user_id, cmd, msg): if cmd == proto_def.bt_submit_fort_war_damage: # 战斗初始化完成 is_finish = self._handle_damage(server_user_id, msg) return is_finish elif cmd == proto_def.bt_quit_battle: self._handle_quit_battle(server_user_id) else: logger.GetLog().warn( 'this battle protocol is unexpected, cmd is : %s' % cmd) return False
def _send_msg_to_chat(self, msg_str, chat_node_id=None): if ModTopo.NODE_TYPE.CHAT in self.connect_client_dict: if chat_node_id: if chat_node_id in self.connect_client_dict[ ModTopo.NODE_TYPE.CHAT]: game.SendMsgToClient( ModTopo.SERVICE_TYPE.FOR_NODE, self.connect_client_dict[ModTopo.NODE_TYPE.CHAT] [chat_node_id], ModTopo.PROTO_TYPE.CHAT, msg_str) else: logger.GetLog().warn('chat node %s not connected' % chat_node_id) else: for chat_node_conn_id in self.connect_client_dict[ ModTopo.NODE_TYPE.CHAT].values(): game.SendMsgToClient(ModTopo.SERVICE_TYPE.FOR_NODE, chat_node_conn_id, ModTopo.PROTO_TYPE.CHAT, msg_str) else: logger.GetLog().warn('no chat node in connect_client_dict')
def send_msg_to_client_node(self, client_node_type, msg_str, *args): # chat proxy的客户端节点: chat (可能还有其他逻辑节点, 可以支持) if client_node_type == ModTopo.NODE_TYPE.CHAT: if args: self._send_msg_to_chat(msg_str, args[0]) else: self._send_msg_to_chat(msg_str) else: logger.GetLog().error( 'send msg to an unexpected client node : %s, %s, %s' % (client_node_type, msg_str, args))
def OnSceneMsg(self, server_group_id, server_user_id, str_msg, channel_id): msg = msgpack.unpackb(str_msg) logger.GetLog().debug('scene server receive msg: %s, %s, %s' % (server_group_id, server_user_id, msg)) cmd = msg.get(proto_def.field_name_cmd, None) if cmd is None: logger.GetLog().warn( 'format of this scene msg is unexpected : %s' % msg) elif cmd == proto_def.sc_enter_scene: self._handle_user_enter_scene(server_group_id, server_user_id, msg) elif cmd == proto_def.sc_player_move: self._handler_user_move(server_group_id, server_user_id, channel_id, msg) elif cmd == proto_def.sc_update_follow_leader: self._handler_user_update_follow_leader(server_group_id, server_user_id, channel_id, msg) else: logger.GetLog().warn( 'scene server receive unexpected cmd msg : %s' % msg)
def OnRegisterFortBattle(self, battle_unique_id, server_group_id, server_user_id, temp_init_data): logger.GetLog().debug('on find fort battle : %s, %s' % (battle_unique_id, server_user_id)) map_fight_node_id = self.get_fight_node_route_data(battle_unique_id) if not map_fight_node_id: # 没有战斗, 增加数据 fight_node_id_list = self.get_fight_node_id_list() map_fight_node_id = random.choice(fight_node_id_list) # 随机一条用来处理 self.add_fight_node_route_data(battle_unique_id, map_fight_node_id) self.add_user_battle_map_data(server_user_id, battle_unique_id) # 注册反馈 self.get_fight_proxy_2_fight_rpc(map_fight_node_id).OnRegisterFortBattleResponse(server_group_id, server_user_id, battle_unique_id, temp_init_data)
def db_invest(): global _db_invest if not _db_invest: logger.GetLog().info('DB:invest:Connecting: {0}'.format( common_config.couchbase_host_game)) _db_invest = _db_connector( bucket=common_config.get_bucket_name('invest'), host=common_config.couchbase_host_game) return _db_invest
def db_admin(): global _db_admin if not _db_admin: logger.GetLog().info('DB:admin:Connecting: {0}'.format( common_config.couchbase_host_util)) _db_admin = _db_connector( bucket=common_config.get_bucket_name('admin'), host=common_config.couchbase_host_util) return _db_admin
def _start_connect_server(self, server_node_type, server_node_id, server_node_addr, server_node_port): if server_node_type not in self.connect_server_dict or \ self.construct_client_type(server_node_type, server_node_id) not in self.connect_server_dict[server_node_type]: # 节点未连接, 发起连接 logger.GetLog().info('start connect server node : %s, %s, %s, %s' % (server_node_type, server_node_id, server_node_addr, server_node_port)) game.ConnectToServer( self.construct_client_type(server_node_type, server_node_id), server_node_addr, server_node_port)
def ConfirmGetOfflineMsg(self, server_user_id): logger.GetLog().debug('chat db handle confirm offline msg : %s' % server_user_id) server_id, user_id = get_server_and_user_id(server_user_id) instant_box.server_selected = server_id instant_box.time_current = time.time() data_context = DataContext() p2p_chat_do = P2PChattingMsgDo(data_context, user_id) p2p_chat_do.clear_msg_dict() data_context.save() data_context.unlock() # 主动unlock return server_user_id
def LoadClanDataToSendMsg(self, chat_msg_data, msg_time, server_group_id, server_sender_id): logger.GetLog().debug( 'load clan data to send msg : %s, %s, %s' % (server_group_id, server_sender_id, chat_msg_data)) instant_box.server_group = server_group_id instant_box.time_current = msg_time data_context = DataContext() instant_box.data_context = data_context sender_server_id, sender_id = get_server_and_user_id(server_sender_id) user_clan_view_do = UserClanDo.Reader()(data_context, sender_id, sender_server_id) if user_clan_view_do.doc.clan_id: member_id_list = ClanDo.Reader()( data_context, user_clan_view_do.doc.clan_id).doc.member_list.keys() # 将消息加入到消息列表 ClanChattingMsgDo(data_context, user_clan_view_do.doc.clan_id).add_msg( chat_msg_data, instant_box.time_current, server_sender_id) if server_sender_id: # 有发送者的公共聊天信息,存日志 user_do = UserDo.Reader()(data_context, sender_id, sender_server_id) aofei_account_id = user_do.doc.aofei_account_id if aofei_account_id: game_logger_inst.start_log(aofei_account_id, GameLogOperation.chat) game_logger_inst.push_log_param(GameLogFieldName.server, sender_server_id) game_logger_inst.push_log_param( GameLogFieldName.account_id, aofei_account_id) game_logger_inst.push_log_param(GameLogFieldName.role_id, sender_id) game_logger_inst.push_log_param(GameLogFieldName.role_name, user_do.name) game_logger_inst.push_log_param( GameLogFieldName.role_level, user_do.level) game_logger_inst.push_log_param( GameLogFieldName.content, json.dumps(chat_msg_data).decode('unicode-escape')) game_logger_inst.push_log_param( GameLogFieldName.channel, chat_def.CHAT_CHANNEL_TYPE_P2P) game_logger_inst.push_log_param(GameLogFieldName.chat_time, instant_box.time_current) game_logger_inst.end_log() data_context.save() data_context.unlock() # 主动unlock return excp.ExceptionSuccess.code, chat_msg_data, server_group_id, server_sender_id, member_id_list return excp.ExceptionClanNotFound.code, server_sender_id
def OnUserCreateTeam(self, server_user_id, team_id, scene_user_info): if server_user_id in self.user_map_channel: server_group_id, cur_channel_id = self.user_map_channel[ server_user_id] if server_group_id not in self.channel_bind_team: self.channel_bind_team[server_group_id] = {} if cur_channel_id in self.channel_bind_team[server_group_id]: # 当前场景已有队伍,需要切换场景 # 拿到旧场景对应的场景逻辑服id cur_scene_node_id = self._get_channel_map_node_id( server_group_id, cur_channel_id) # 找到一个新场景绑定给队伍 new_channel_id = self._find_target_scene( server_group_id, team_id) new_scene_node_id = self.channel_map_node[server_group_id][ new_channel_id] # 旧场景删除玩家数据 self._remove_scene_user(server_user_id) # 更新玩家场景映射数据 self.user_map_channel[server_user_id] = (server_group_id, new_channel_id) # 更新场景玩家数据 self._add_channel_user(server_group_id, new_channel_id, server_user_id) # 通知旧场景玩家离开场景 self.get_scene_proxy_2_scene_rpc( cur_scene_node_id).OnUserLeaveScene( server_group_id, server_user_id, cur_channel_id, LEAVE_SCENE_REASON_CREATE_TEAM) # 通知新场景该玩家进入 self.get_scene_proxy_2_scene_rpc( new_scene_node_id).OnUseEnterSelectChannelCallback( server_group_id, server_user_id, new_channel_id, scene_user_info, team_id, server_user_id, [server_user_id]) else: # 当前场景还未绑定, 直接绑定给队伍 self.channel_bind_team[server_group_id][ cur_channel_id] = team_id self.team_bind_channel[team_id] = (server_group_id, cur_channel_id) cur_scene_node_id = self._get_channel_map_node_id( server_group_id, cur_channel_id) self.get_scene_proxy_2_scene_rpc( cur_scene_node_id).OnSyncUserCreateTeamInScene( server_group_id, server_user_id, cur_channel_id, team_id) else: logger.GetLog().warn( 'user create team but user has no match channel : %s, %s' % (server_user_id, team_id))
def check_login_sign(self, server_user_id, server_id, sign): if server_user_id and server_id and sign and server_id == get_server_id( server_user_id): md5 = hashlib.md5() md5.update(server_user_id + server_id + proto_def.login_check_md5_ticket) admin_pwd = md5.hexdigest() logger.GetLog().debug( 'server_user_id: %s, server_id: %s, sign: %s, cal_sign: %s' % (server_user_id, server_id, sign, admin_pwd)) return admin_pwd == sign return False
def OnClientDisconnect(self, service_type, conn_id): logger.GetLog().debug('----------on client disconnect : %s, %s' % (service_type, conn_id)) # 从客户端连接字典中删除数据 if service_type in self.client_connect_id_dict: self.client_connect_id_dict[service_type].pop(conn_id, None) if service_type == ModTopo.SERVICE_TYPE.FOR_NODE and conn_id in self.connect_to_node_dict: client_node_type, client_node_id = self.connect_to_node_dict[ conn_id] if client_node_type in self.connect_client_dict: self.connect_client_dict[client_node_type].pop( client_node_id, None)
def TestUserLogin(self): req = CGLoginServerRequest() req.user_id = self.get_test_param('server_user_id') req.server_id = self.get_test_param('server_id') import hashlib md5 = hashlib.md5() md5.update(req.user_id + req.server_id + proto_def.login_check_md5_ticket) req.sign = md5.hexdigest() req_dump = req.dump() logger.GetLog().debug('TestUserLogin req: %s' % req_dump) self.SendCommonMsg(req_dump)
def _handle_user_enter_scene(self, server_group_id, server_user_id, msg): logger.GetLog().debug('scene handle user enter: %s, %s, %s' % (server_group_id, server_user_id, msg)) msg_obj = proto_def.SCEnterSceneRequest.new_from_data(msg) if msg_obj.scene == 'scLobby': # 进入场景, 到db构造自己的数据并发送给所有玩家 self.get_scene_2_db_rpc().HandleUserEnterScene( server_group_id, server_user_id) else: # 离开场景 self.get_scene_2_scene_proxy_rpc().OnUserLeaveSceneManual( server_group_id, server_user_id)
def _handle_chat_msg(self, server_group_id, server_sender_id, msg): logger.GetLog().debug('handle chat msg : %s, %s, %s' % (server_group_id, server_sender_id, msg)) msg_obj = CGSendChatMsgRequest.new_from_data(msg) # 更新服务器id msg_time = time.time() chat_msg_data = self._pack_push_chat_msg_data(msg_obj, msg_time, server_sender_id) return_code = None if msg_obj.channel_type in [ chat_def.CHAT_CHANNEL_TYPE_PUBLIC, chat_def.CHAT_CHANNEL_TYPE_NOTICE ]: # 公共聊天或系统推送 return_code = self._process_public_chat(chat_msg_data, msg_time, server_group_id, server_sender_id) elif msg_obj.channel_type == chat_def.CHAT_CHANNEL_TYPE_CLAN: # 公会聊天 self._process_clan_chat(chat_msg_data, msg_time, server_group_id, server_sender_id) elif msg_obj.channel_type == chat_def.CHAT_CHANNEL_TYPE_P2P: # 私聊 return_code = self._process_p2p_chat(chat_msg_data, msg_time, server_group_id, server_sender_id, msg_obj.server_receiver_id) elif msg_obj.channel_type == chat_def.CHAT_CHANNEL_TYPE_TEAM: # 队伍内部聊天 self._process_team_chat(chat_msg_data, msg_time, server_group_id, server_sender_id) else: logger.GetLog().warn( 'chat server handle unexcept channel type msg : %s' % msg) return_code = excp.ExceptionChatBase.code # 发送消息成功返回给发送者 if server_sender_id and return_code is not None: # return_code为None,表示异步处理 self.get_chat_2_chat_proxy_rpc().OnHandleSendChatMsgResponse( server_sender_id, return_code)
def reload_data_inst(inst_name): this_mod = sys.modules[__name__] if hasattr(this_mod, inst_name): data_context.reload( getattr(sys.modules[__name__], inst_name).get_doc_cache_key()) elif inst_name == 'all': data_context.reload() else: logger.GetLog().warn('reload data inst : %s not found' % inst_name) return if inst_name == 'master_constants_inst' or inst_name == 'all': init_battle_config_const_value()
def handle_get_online_num(self, connect_id): connect_info = ModObjFac.CreateApp().get_connect_info(connect_id) if connect_info and connect_info.server_group_id: res_obj = CGGetOnlineNumResponse() res_obj.online_num = self.get_server_online_num( connect_info.server_group_id) logger.GetLog().debug( 'server %s online num %s' % (connect_info.server_group_id, res_obj.online_num)) # 返回信息给客户端 ModObjFac.CreateApp().send_msg_to_client( connect_id, ModTopo.PROTO_TYPE.COMMON, msgpack.packb(res_obj.dump()))
def LoadOfflineMsgToSend(self, server_group_id, server_user_id, last_public_time, last_clan_time): logger.GetLog().debug('load offline msg : %s, %s, %s, %s' % (server_group_id, server_user_id, last_public_time, last_clan_time)) server_id, user_id = get_server_and_user_id(server_user_id) instant_box.server_group = server_group_id instant_box.server_selected = server_id instant_box.time_current = time.time() instant_box.data_context = DataContext() return server_user_id, self.get_public_msg_list( last_public_time), self.get_clan_msg_list( user_id, last_clan_time), self.get_p2p_msg_list(user_id)