/// <summary> /// 发送 /// </summary> private void SendTrapMsg() { if (m_need_send && m_session_conn_idx > 0) { //加入队列 CheckItem item = new CheckItem(); item.check_delay_time = MathUtils.RandRange(SHC_MIN_TIME, SHC_MAX_TIME); item.sh_check_sn = MathUtils.RandRange(0, int.MaxValue); item.check_send_time = Time.time; m_send_checks.Add(item); //发给客户端 gs2c.SpeedCheck msg = PacketPools.Get(gs2c.msg.SPEED_CHECK) as gs2c.SpeedCheck; msg.delay_time = item.check_delay_time; msg.check_sn = item.sh_check_sn; ClientSession session = ClientSessionManager.Instance.GetSession(m_session_conn_idx); if (session != null) { session.Send(msg); } m_need_send = false; ++m_total_times; } }
/// <summary> /// ping gate /// </summary> public static void SendPingGS(uint packet_idx) { c2gs.PingNet msg = PacketPools.Get(c2gs.msg.PING_NET) as c2gs.PingNet; msg.packet_id = packet_idx; msg.tick = Time.time; ClientNetManager.Instance.Send(msg); }
/// <summary> /// 处理登出逻辑 /// </summary> private void HandleLogoutAccount(long account_idx) { Player player = UnitManager.Instance.GetPlayerByAccount(account_idx) as Player; if (player == null) {//如果在加载完角色信息前退出,则不会有unit return; } //告诉fs ss2fs.LogoutClient fs_msg = PacketPools.Get(ss2fs.msg.LOGOUT_CLIENT) as ss2fs.LogoutClient; fs_msg.char_idx = player.char_idx; ServerNetManager.Instance.Send2FS(player.fs_uid, fs_msg); //告诉ws ss2ws.LogoutClient ws_msg = PacketPools.Get(ss2ws.msg.LOGOUT_CLIENT) as ss2ws.LogoutClient; ws_msg.char_idx = player.char_idx; ServerNetManager.Instance.Send2WS(ws_msg); //告诉gl ss2gl.LogoutClient gl_msg = PacketPools.Get(ss2gl.msg.LOGOUT_CLIENT) as ss2gl.LogoutClient; gl_msg.char_idx = player.char_idx; ServerNetManager.Instance.Send2GL(gl_msg); //从场景移除 BaseScene scene = SceneManager.Instance.GetScene(player.scene_obj_idx); if (scene != null) { scene.RemoveUnit(player); } //从管理器移除 UnitManager.Instance.RemoveUnit(player); }
/// <summary> /// ping网络 /// </summary> private void OnPingNet(PacketBase packet) { c2ss.PingNet msg = packet as c2ss.PingNet; if (Utils.HasFlag(msg.flags, (uint)eServerType.GLOBAL)) {//ping gl ss2gl.PingNet rep_msg = PacketPools.Get(ss2gl.msg.PING_NET) as ss2gl.PingNet; rep_msg.client_uid = msg.client_uid; rep_msg.packet_id = msg.packet_id; rep_msg.tick = msg.tick; rep_msg.flags = msg.flags; ServerNetManager.Instance.Send2GL(rep_msg); } else { long offset_time = Time.time - msg.tick; Log.Debug("收到第:" + msg.packet_id + " 时间:" + Time.time + " 延迟:" + offset_time); ss2c.PingNet rep_msg = PacketPools.Get(ss2c.msg.PING_NET) as ss2c.PingNet; rep_msg.packet_id = msg.packet_id; rep_msg.tick = msg.tick; rep_msg.flags = msg.flags; ServerNetManager.Instance.SendProxy(msg.client_uid, rep_msg); } }
/// <summary> /// 发包 /// </summary> /// <param name="conn_idx"></param> /// <param name="packet"></param> public void Send(PacketBase packet) { if (m_cur_conn_idx > 0) { //包索引 uint packet_idx = 0; if (packet is PackBaseC2S) { packet_idx = PacketEncrypt.GetPacketIndex(); (packet as PackBaseC2S).packet_idx = PacketEncrypt.EncrpytPacketIndex(packet_idx, GlobalID.ENCRYPT_KEY); } //数据写入stream m_send_by.Clear(); m_send_by.WriteUShort(0); //先写入长度占位 packet.Write(m_send_by); int data_len = m_send_by.Available - NetID.PacketHeadSize; //总长度 m_send_by.ModifyUShort((ushort)data_len, 0); //数据有效性 if (packet is PackBaseC2S) { //包长2 + 协议头2 + 包索引id4 + 有效性校验2 = 10 ushort data_verify = PacketEncrypt.CalcPacketDataVerify(m_send_by.Buffer, 10, m_send_by.Available - 10, packet_idx, GlobalID.ENCRYPT_KEY); m_send_by.ModifyUShort((ushort)data_verify, 8); } NetConnectManager.Instance.Send(m_cur_conn_idx, m_send_by); } PacketPools.Recover(packet); }
/// <summary> /// 赠送 /// </summary> public static void SendRelationGive(long char_idx, PropID item_id) { c2ss.RelationGive msg = PacketPools.Get(c2ss.msg.RELATION_GIVE) as c2ss.RelationGive; msg.target_char_idx = char_idx; msg.item_id = item_id; ClientNetManager.Instance.Send(msg); }
/// <summary> /// 断开与战斗服的连接 /// </summary> public void DisConnectFightServer() { Player player = UnitManager.Instance.GetPlayerByIdx(m_char_idx); if (player == null) { return; } if (player.fs_uid > 0 && m_connect_state == eFSConnectState.Connected) { //告诉fs ss2fs.LogoutClient fs_msg = PacketPools.Get(ss2fs.msg.LOGOUT_CLIENT) as ss2fs.LogoutClient; fs_msg.char_idx = m_char_idx; ServerNetManager.Instance.Send2FS(player.fs_uid, fs_msg); //告诉gs分配给玩家的fs ss2gs.NotifyServer gs_msg = PacketPools.Get(ss2gs.msg.NOTIFY_SERVER) as ss2gs.NotifyServer; gs_msg.account_idx = player.account_idx; gs_msg.s_type = eServerType.FIGHT; gs_msg.fs_uid = 0; ServerNetManager.Instance.Send(player.client_uid.srv_uid, gs_msg); m_connect_state = eFSConnectState.UnConnect; } }
/// <summary> /// 添加关系:发给对方验证 /// </summary> public void AddRelationGL(long event_idx, PlayerIDName player_id, eRelationFlag flag, string message) { Player player = UnitManager.Instance.GetUnitByIdx(m_char_idx) as Player; if (player == null) { return; } //超过上限 if (IsRelationFull(flag)) { return; } //判断是否已经存在关系 RelationInfo relation_info; if (m_relations.TryGetValue(player_id.char_idx, out relation_info) && relation_info.flags == flag) { return; } //发给client处理是否同意 if (flag != eRelationFlag.Block) { ss2c.RelationAdd rep_msg = PacketPools.Get(ss2c.msg.RELATION_ADD) as ss2c.RelationAdd; rep_msg.event_idx = event_idx; rep_msg.player_id = player_id; rep_msg.message = message; rep_msg.flag = flag; ServerNetManager.Instance.SendProxy(player.client_uid, rep_msg); } }
/// <summary> /// 发包 /// </summary> /// <param name="conn_idx"></param> /// <param name="packet"></param> public void Send(long conn_idx, PacketBase packet) { if (m_sockets.Contains(conn_idx)) { //包索引 uint packet_idx = 0; if (packet is PackBaseC2S) { packet_idx = PacketEncrypt.GetPacketIndex(); (packet as PackBaseC2S).packet_idx = PacketEncrypt.EncrpytPacketIndex(packet_idx, GlobalID.ENCRYPT_KEY); } m_send_by.Clear(); m_send_by.WriteUShort(0);//先写入长度占位 packet.Write(m_send_by); int data_len = m_send_by.Available - NetID.PacketHeadSize; m_send_by.ModifyUShort((ushort)data_len, 0); //数据有效性 if (packet is PackBaseC2S) { //包长2 + 协议头2 + 包索引id4 + 有效性校验2 = 10 ushort data_verify = PacketEncrypt.CalcPacketDataVerify(m_send_by.Buffer, 10, m_send_by.Available - 10, packet_idx, GlobalID.ENCRYPT_KEY); m_send_by.ModifyUShort((ushort)data_verify, 8); } int size = NetConnectManager.Instance.Send(conn_idx, m_send_by); m_send_msg_count++; m_send_msg_size += size; } PacketPools.Recover(packet); }
/// <summary> /// 好友赠送 /// </summary> public void FriendGiveClient(long target_char_idx, PropID item_id) { //先查找是否有好友 RelationInfo relation_info; if (!m_relations.TryGetValue(target_char_idx, out relation_info) || relation_info.flags != eRelationFlag.Friend) { return; } //是否今日已经赠送 //TODO //赠送是否合法 if (!item.IsValidProp(item_id)) { return; } //发送到gl ss2gl.RelationGive msg = PacketPools.Get(ss2gl.msg.RELATION_GIVE) as ss2gl.RelationGive; msg.char_idx = m_char_idx; msg.target_char_idx = target_char_idx; msg.item_id = item_id; ServerNetManager.Instance.Send2GL(msg); }
/// <summary> /// 登陆 /// </summary> private void OnClientLogin(ClientSession session, PacketBase packet) { c2gs.ClientLogin msg = packet as c2gs.ClientLogin; if (string.IsNullOrEmpty(msg.name) || string.IsNullOrEmpty(msg.psw)) { Log.Debug("数据错误 name:" + msg.name); return; } //只有创建或登录错误,才能进一步验证 if (session.session_status != eSessionStatus.CREATED && session.session_status != eSessionStatus.LOGIN_FAILED) { Log.Debug("错误的seesion状态:" + session.session_status); return; } //标记状态,正在验证中,防止重复验证 session.session_status = eSessionStatus.LOGIN_DOING; //发给ws请求验证 gs2ws.ClientLogin ws_msg = PacketPools.Get(gs2ws.msg.CLIENT_LOGIN) as gs2ws.ClientLogin; ws_msg.client_uid = session.client_uid; ws_msg.name = msg.name; ws_msg.psw = msg.psw; ServerNetManager.Instance.Send2WS(ws_msg); }
/// <summary> /// 前端请求邮件列表 /// </summary> public void HandleReqList() { Player player = UnitManager.Instance.GetUnitByIdx(m_char_idx) as Player; if (player == null) { return; } if (m_new_mails.Count > 0) { ss2c.MailList msg = PacketPools.Get(ss2c.msg.MAIL_LIST) as ss2c.MailList; foreach (var mail_idx in m_new_mails) { MailInfo mail_info; if (m_all_mails.TryGetValue(mail_idx, out mail_info)) { MailTitleInfo info = new MailTitleInfo(); info.CopyFromInfo(mail_info); msg.mail_list.Add(info); } } ServerNetManager.Instance.SendProxy(player.client_uid, msg); m_new_mails.Clear(); } }
/// <summary> /// 前端请求邮件列表 /// </summary> public void HandleReqList() { Player player = UnitManager.Instance.GetUnitByIdx(m_char_idx) as Player; if (player == null) { return; } while (m_new_mails.Count > 0) {//数量太多,分次数发送 ss2c.MailList msg = PacketPools.Get(ss2c.msg.MAIL_LIST) as ss2c.MailList; int count = 0; for (int i = m_new_mails.Count - 1; i >= 0 && count++ < 10; --i) { long mail_idx = m_new_mails[i]; MailInfo mail_info; if (m_all_mails.TryGetValue(mail_idx, out mail_info)) { MailTitleInfo info = new MailTitleInfo(); info.CopyFromInfo(mail_info); msg.mail_list.Add(info); } m_new_mails.RemoveAt(i); } ServerNetManager.Instance.SendProxy(player.client_uid, msg); } m_new_mails.Clear(); }
/// <summary> /// 下发关系列表 /// </summary> public void RelationListClient() { Player player = UnitManager.Instance.GetUnitByIdx(m_char_idx) as Player; if (player == null) { return; } List <RelationInfo> list = new List <RelationInfo>(); foreach (var obj in m_relations) { list.Add(obj.Value); if (list.Count == 10) {//每次下发10个 ss2c.RelationList msg = PacketPools.Get(ss2c.msg.RELATION_LIST) as ss2c.RelationList; msg.list.AddRange(list); ServerNetManager.Instance.SendProxy(player.client_uid, msg, false); list.Clear(); } } if (list.Count > 0) { ss2c.RelationList msg = PacketPools.Get(ss2c.msg.RELATION_LIST) as ss2c.RelationList; msg.list.AddRange(list); ServerNetManager.Instance.SendProxy(player.client_uid, msg, false); } }
/// <summary> /// 处理由gate转发的client消息 /// </summary> /// <param name="packet"></param> private void HandleProxyClientMsg(PacketBase packet) { ProxyC2SMsg proxy_msg = packet as ProxyC2SMsg; //转发的消息id ushort header = proxy_msg.data.ReadUShort(); if (header < ProtocolID.MSG_BASE_C2SS || header >= ProtocolID.MSG_BASE_C2SS + ProtocolID.MSG_APPLAYER_PER_INTERVAL) { Log.Debug("收到错误的消息ID:" + header); return; } PacketBase msg = PacketPools.Get(header); msg.Read(proxy_msg.data); //处理 ushort msg_id = (ushort)(header - ProtocolID.MSG_BASE_C2SS); MsgProcFunction fun = m_client_msg_proc[msg_id]; if (fun == null) { Log.Debug("未注册消息处理函数ID:" + header); } else { fun(msg); } PacketPools.Recover(msg); }
/// <summary> /// 主动关服 /// </summary> public void Stop(int wait_time) { int leave_time = wait_time <= 0 ? GlobalID.TOTAL_WAIT_SHUTDOWN : wait_time; Log.Info("剩余关服时间:" + leave_time); //告诉客户端关服倒计时 ws2c.ShutdownServer msg = PacketPools.Get(ws2c.msg.SHUTDOWN_SERVER) as ws2c.ShutdownServer; msg.leave_time = (ushort)leave_time; ServerNetManager.Instance.BroadcastProxyMsg(msg); //XX秒后自动关服,每秒触发一次 TimerManager.Instance.AddLoop(1000, leave_time, (timer_id, param) => { --leave_time; if (leave_time <= 0) { OnStopServer(); } else { Log.Info("剩余关服时间:" + leave_time); } }); }
/// <summary> /// 网络事件处理 /// </summary> public void OnNetworkServer(long conn_idx, ushort header, ByteArray data) { PacketBase packet = PacketPools.Get(header); packet.Read(data); MsgProcFunction fun; if (m_msg_proc.TryGetValue(packet.header, out fun)) { try { fun(packet); } catch (Exception e) { Log.Exception(e); } } else { Log.Warning("未注册消息处理函数id:" + header); } PacketPools.Recover(packet); }
/// <summary> /// 登录 /// </summary> /// <param name="name">账号</param> /// <param name="psw">密码</param> public static void SendLogin(string name, string psw) { c2gs.ClientLogin msg = PacketPools.Get(c2gs.msg.CLIENT_LOGIN) as c2gs.ClientLogin; msg.name = name; msg.psw = psw; ClientNetManager.Instance.Send(msg); }
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~事件~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ private void OnAcceptConnect(long conn_idx) { m_sockets.Add(conn_idx); c2gs.EncryptInfo msg = PacketPools.Get(c2gs.msg.ENCRYPT) as c2gs.EncryptInfo; msg.version = 1; this.Send(conn_idx, msg); EventController.TriggerEvent(ClientEventID.NET_CONNECTED_OPEN, conn_idx); }
/// <summary> /// 角色列表 /// </summary> private void OnEnumCharacterList(ClientSession session, PacketBase packet) { gs2ss.EnumCharacter msg = PacketPools.Get(gs2ss.msg.ENUM_CHAR) as gs2ss.EnumCharacter; msg.client_uid = session.client_uid; msg.account_idx = session.account_idx; msg.game_db_id = session.db_id.game_id; ForServerNetManager.Instance.Send(session.ss_uid, msg); }
/// <summary> /// 请求好友操作 /// </summary> public static void SendRelationApplyCommand(long event_idx, long char_idx, eRelationApplyCmd cmd) { c2ss.RelationApplyCmd msg = PacketPools.Get(c2ss.msg.RELATION_APPLY_CMD) as c2ss.RelationApplyCmd; msg.event_idx = event_idx; msg.target_char_idx = char_idx; msg.cmd = cmd; ClientNetManager.Instance.Send(msg); }
public static void SendPingGL(uint packet_idx) { c2ss.PingNet msg = PacketPools.Get(c2ss.msg.PING_NET) as c2ss.PingNet; msg.packet_id = packet_idx; msg.tick = Time.time; msg.flags |= (uint)eServerType.GLOBAL; ClientNetManager.Instance.Send(msg); }
/// <summary> /// 发给ss检测 /// </summary> private void SendCheckOnline() { ws2ss.ClientOnline msg = PacketPools.Get(ws2ss.msg.CLIENT_ONLINE) as ws2ss.ClientOnline; msg.char_idx = this.char_idx; ServerNetManager.Instance.Send(m_srv_uid.ss_uid, msg); m_is_send_check_online = true; }
/// <summary> /// 请求添加好友 /// </summary> public static void SendRelationAdd(RelationAddTarget target, eRelationFlag flag, string message) { c2ss.RelationAdd msg = PacketPools.Get(c2ss.msg.RELATION_ADD) as c2ss.RelationAdd; msg.target_id = target; msg.message = message; msg.flag = flag; ClientNetManager.Instance.Send(msg); }
/// <summary> /// 压力测试 /// </summary> /// <param name="packet"></param> private void OnRobotTest(PacketBase packet) { ss2gs.RobotTest msg = packet as ss2gs.RobotTest; gs2c.RobotTest rep_msg = PacketPools.Get(gs2c.msg.ROBOT_TEST) as gs2c.RobotTest; rep_msg.length = msg.length; ForClientNetManager.Instance.Send(msg.client_uid.conn_idx, rep_msg); }
/// <summary> /// 创建角色 /// </summary> private void OnCreateCharacter(PacketBase packet) { ss2gs.CreateCharacter msg = packet as ss2gs.CreateCharacter; gs2c.CreateCharacter rep_msg = PacketPools.Get(gs2c.msg.CREATE_CHARACTER) as gs2c.CreateCharacter; rep_msg.result = msg.result; rep_msg.char_idx = msg.char_idx; ForClientNetManager.Instance.Send(msg.client_uid.conn_idx, rep_msg); }
/// <summary> /// 服务器时间 /// </summary> private void OnServerTime(PacketBase packet) { c2ws.ServerTime msg = packet as c2ws.ServerTime; //告诉客户端当前服务器时间 ws2c.ServerTime rep_msg = PacketPools.Get(ws2c.msg.SERVER_TIME) as ws2c.ServerTime; rep_msg.server_time = GameTimeManager.Instance.server_time; ServerNetManager.Instance.SendProxy(msg.client_uid, rep_msg); }
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~事件~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ private void OnAcceptConnect(long conn_idx) { m_cur_conn_idx = conn_idx; c2gs.EncryptInfo msg = PacketPools.Get(c2gs.msg.ENCRYPT) as c2gs.EncryptInfo; msg.version = GlobalID.GetVersion(); this.Send(msg); EventController.TriggerEvent(ClientEventID.NET_CONNECTED_OPEN, m_cur_conn_idx); }
/// <summary> /// 压力测试 /// </summary> private void OnRobotTest(PacketBase packet) { gs2ss.RobotTest msg = packet as gs2ss.RobotTest; ss2gs.RobotTest rep_msg = PacketPools.Get(ss2gs.msg.ROBOT_TEST) as ss2gs.RobotTest; rep_msg.client_uid = msg.client_uid; rep_msg.length = msg.length; this.Send(rep_msg); }
public int Send(long conn_idx, PacketBase packet) { m_send_by.Clear(); m_send_by.WriteUShort(0);//先写入长度占位 packet.Write(m_send_by); int len = NetConnectManager.Instance.Send(conn_idx, m_send_by); PacketPools.Recover(packet); return(len); }