Exemple #1
0
        private void LogMessage(ulong clientId, ServiceDesc desc, bool client2Server)
        {
#if LOG_MESSAGE
            try
            {
                Logger logger;
                if (!mFromClientId2Logger.TryGetValue(clientId, out logger))
                {
                    logger = LogManager.GetLogger("Gate." + desc.ClientId);
                    mFromClientId2Logger.AddOrUpdate(clientId, logger, (arg1, logger1) => logger1);
                }

                string funcName;
                if (!mFromFunctionId2Name.TryGetValue((int)desc.FuncId, out funcName))
                {
                    funcName = "Other";
                }

                logger.Info("Dir:{5} Service:{0} Func:{1} PacketId:{2} Size:{3} Type:{6} Content:{4}",
                            (ServiceType)desc.ServiceType, funcName,
                            desc.PacketId, desc.Data.Length, Convert.ToBase64String(ProtocolExtension.Serialize(desc)),
                            client2Server ? "In" : "Out", (MessageType)desc.Type);
            }
            catch
            {
            }
#endif
        }
Exemple #2
0
        internal PeerConnection(
            Metainfo meta,
            PeerId peerId,
            IReadOnlyList <byte> reservedBytes,
            ProtocolExtension supportedExtensions,
            IPeerMessageHandler messageHandler,
            ITransportStream transportStream)
        {
            this.messageHandler  = messageHandler;
            this.transportStream = transportStream;
            customValues         = new Dictionary <IModule, Dictionary <string, object> >();
            PeerId                = peerId;
            ReservedBytes         = reservedBytes;
            SupportedExtensions   = supportedExtensions;
            InfoHash              = meta.InfoHash;
            reader                = new BigEndianBinaryReader(transportStream.Stream);
            writer                = new BigEndianBinaryWriter(transportStream.Stream);
            Available             = new Bitfield(meta.Pieces.Count);
            RequestedByRemotePeer = new HashSet <BlockRequest>();
            Requested             = new HashSet <BlockRequest>();

            IsRemotePeerInterested   = false;
            IsInterestedInRemotePeer = false;
            IsChokedByRemotePeer     = true;
            IsChokingRemotePeer      = true;
        }
Exemple #3
0
        //func = 3605
        public void RequestSceneInfo(ServerClient client, ServiceDesc desc)
        {
            var msg      = ProtocolExtension.Deserialize <__RPC_Scene_RequestSceneInfo_ARG_int32_serverId_int32_sceneTypeId__>(desc.Data);
            var serverId = msg.ServerId;
            var sceneId  = msg.SceneTypeId;
            var key      = CalcServerSceneId(serverId, sceneId);

            var retMsg = new __RPC_Scene_RequestSceneInfo_RET_MsgScenesInfo__();

            retMsg.ReturnValue = new MsgScenesInfo();

            ConcurrentDictionary <ulong, SceneInfo> infos;

            if (mFromServerIdAndSceneId2Guid.TryGetValue(key, out infos))
            {
                if (null != infos && !infos.IsEmpty)
                {
                    foreach (var info in infos)
                    {
                        var sceneInfo = new MsgSceneInfo();
                        sceneInfo.Guid        = info.Value.SceneGuid;
                        sceneInfo.PlayerCount = info.Value.CharacterIds.Count;
                        retMsg.ReturnValue.Info.Add(sceneInfo);
                    }
                }
            }
            desc.Data = ProtocolExtension.Serialize(retMsg);
            client.SendMessage(desc);
        }
Exemple #4
0
        //通知进入场景
        public void NotifyEnterScene(CharacterSceneInfo info, int changeType, SceneParam sp)
        {
            PlayerLog.WriteLog(888, "NotifyEnterScene characterId={0},SceneId={1},newScene={2}", info.CharacterId,
                               info.SceneInfo.SceneId, info.SceneInfo.SceneGuid);
            mLogger.Info("Enter Game {0} - NotifyEnterScene - 1 - {1}", info.CharacterId,
                         TimeManager.Timer.ElapsedMilliseconds);
            mLogger.Info("NotifyEnterScene {0}, {1}.", info.CharacterId, info.SceneInfo.Server.RemoteEndPoint);

            var content =
                new __RPC_Scene_SSEnterScene_ARG_uint64_characterId_uint64_guid_uint64_applyGuid_int32_changeType_SceneParam_sceneParam__
                    ();

            content.CharacterId = info.CharacterId;
            content.Guid        = info.SceneInfo.SceneGuid;
            content.ChangeType  = changeType;
            content.SceneParam  = sp;
            var message = new ServiceDesc();

            message.FuncId      = 3055;
            message.ServiceType = (int)ServiceType.Scene;
            message.PacketId    = mBroker.GetUniquePacketId();
            message.Data        = ProtocolExtension.Serialize(content);
            message.Type        = (int)MessageType.SS;
            message.CharacterId = info.CharacterId;


            info.SceneInfo.Server.SendMessage(message);
        }
Exemple #5
0
        //通知进入场景
        public void NotifyLoginEnterScene(ServerClient client,
                                          CharacterSceneInfo info,
                                          ulong sceneGuid,
                                          ServiceDesc desc)
        {
            Logger.Info("Enter Game {0} - NotifyEnterScene - 1 - {1}", info.CharacterId,
                        TimeManager.Timer.ElapsedMilliseconds);
            Logger.Info("NotifyEnterScene {0}, {1}.", info.CharacterId, info.SceneInfo.Server.RemoteEndPoint);

            var content = new __RPC_Scene_PrepareDataForEnterGame_RET_uint64__();

            content.ReturnValue = sceneGuid;

            var message = new ServiceDesc();

            message.FuncId      = 3051;
            message.ServiceType = (int)ServiceType.Login;
            message.PacketId    = desc.PacketId;
            message.Data        = ProtocolExtension.Serialize(content);
            message.Type        = desc.Type;
            message.CharacterId = desc.CharacterId;
            message.ClientId    = desc.ClientId;

            client.SendMessage(message);
        }
Exemple #6
0
        //func = 3072
        public void IsSceneExist(ServerClient client, ServiceDesc desc)
        {
            var msg       = ProtocolExtension.Deserialize <__RPC_Scene_IsSceneExist_ARG_uint64_sceneGuid__>(desc.Data);
            var sceneGuid = msg.SceneGuid;
            var exist     = mFromSceneGuid2Server.ContainsKey(sceneGuid);

            desc.Data = ProtocolExtension.Serialize(exist);
            client.SendMessage(desc);
        }
Exemple #7
0
 internal PeerConnectionPreparationContext(
     PeerId peerId,
     byte[] reservedBytes,
     ProtocolExtension supportExtensions)
 {
     PeerId              = peerId;
     ReservedBytes       = reservedBytes;
     SupportedExtensions = supportExtensions;
 }
Exemple #8
0
        //desc.FuncId == 3002   此场景已经不存在
        public void NoHaveScene(ServerClient client, ServiceDesc desc)
        {
            var msg =
                ProtocolExtension.Deserialize <__RPC_Scene_NotifySceneNotExist_ARG_uint64_sceneId_uint64_characterId__>(
                    desc.Data);
            var characterId = msg.CharacterId;

            mLogger.Info("Enter Game {0} - NotifySceneNotExist - 1 - {1}", characterId,
                         TimeManager.Timer.ElapsedMilliseconds);

            var info = mBroker.GetCharacter(characterId);

            if (info == null)
            {
                return;
            }
            var serverId = info.SceneInfo.ServerId;
            var sceneId  = info.SceneInfo.SceneId;

            mLogger.Info("Enter Game {0} - NotifySceneNotExist - 2 - {1}", characterId,
                         TimeManager.Timer.ElapsedMilliseconds);
            RemoveScene(msg.SceneId);
            mLogger.Info("Enter Game {0} - NotifySceneNotExist - 3 - {1}", characterId,
                         TimeManager.Timer.ElapsedMilliseconds);

            var newScene = SelectServerForScene(serverId, sceneId, msg.CharacterId);

            if (newScene == null)
            {
                mLogger.Info("Enter Game {0} - NotifySceneNotExist - 4 - {1}", characterId,
                             TimeManager.Timer.ElapsedMilliseconds);
                newScene = CreateNewSceneInfo(serverId, sceneId, 0);
                newScene.PushCharacter(msg.CharacterId);
                //DebugCounter[1]++;
                var param = new SceneParam();
                param.ObjId = desc.CharacterId;

                CreateNewScene(newScene, param);
            }

            if (newScene.Status == SceneStatus.ReadyToEnter)
            {
                mBroker.ChangeScene(msg.CharacterId, newScene);
                mLogger.Info("Enter Game {0} - NotifySceneNotExist - 5 - {1}", characterId,
                             TimeManager.Timer.ElapsedMilliseconds);
            }
            else
            {
                newScene.WaitingActions.Add(() =>
                {
                    mLogger.Info("Enter Game {0} - NotifySceneNotExist - 6 - {1}", characterId,
                                 TimeManager.Timer.ElapsedMilliseconds);
                    mBroker.ChangeScene(msg.CharacterId, newScene);
                });
            }
        }
Exemple #9
0
            private List <string> GetProtocolExtensions(ProtocolExtension extensions)
            {
                var results = new List <string>();

                foreach (ProtocolExtension e in Enum.GetValues(typeof(ProtocolExtension)))
                {
                    if ((extensions & e) != 0)
                    {
                        results.Add(e.ToString());
                    }
                }
                return(results);
            }
Exemple #10
0
        //让某个服务器卸载玩家数据
        private void UnloadData(ulong characterId, SceneInfo oldSceneInfo, Action <ServiceDesc> callback)
        {
            PlayerLog.WriteLog(888, "UnloadData characterId={0},ServerId={1},SceneId={2},SceneGuid={3}", characterId,
                               oldSceneInfo.ServerId, oldSceneInfo.SceneId, oldSceneInfo.SceneGuid);
            ConnectLostLogger.Info("character {0} SceneBroker UnloadData 1", characterId);
            var content = new __RPC_Scene_UnloadData_ARG_uint64_characterId__();

            content.CharacterId = characterId;


            var message = new ServiceDesc();

            message.FuncId      = 3020;
            message.ServiceType = (int)ServiceType.Scene;
            message.PacketId    = GetUniquePacketId();
            message.Data        = ProtocolExtension.Serialize(content);
            message.Type        = (int)MessageType.BS;
            message.CharacterId = characterId;

            Logger.Info("Notify Scene server UnloadData {0}", characterId);

            var act = new Action <bool, ServiceDesc>((b, item) =>
            {
                PlayerLog.WriteLog(888, "UnloadData characterId={0},result={1},error={2}", characterId, b, item.Error);
                if (b)
                {
                    if (item.Error == 0)
                    {
                        ConnectLostLogger.Info("character {0} SceneBroker UnloadData 3", characterId);
                        Logger.Info("Scene server UnloadData replied {0}", characterId);
                        callback(item);
                    }
                    else
                    {
                        ConnectLostLogger.Info("character {0} SceneBroker UnloadData 4", characterId);
                        Logger.Error("UnloadData failed {0}....", item.Error);
                    }
                }
                else
                {
                    ConnectLostLogger.Info("character {0} SceneBroker UnloadData 5", characterId);
                    Logger.Error("UnloadData timeout....");
                }
            });

            RegisterCallback(message.PacketId, act);


            ConnectLostLogger.Info("character {0} SceneBroker UnloadData 2", characterId);
            oldSceneInfo.Server.SendMessage(message);
        }
Exemple #11
0
        //desc.FuncId == 3039
        public void CheckCharacterOnline(ServerClient client, ServiceDesc desc)
        {
            var request =
                ProtocolExtension.Deserialize <__RPC_Scene_SBCheckCharacterOnline_ARG_Uint64Array_toList__>(desc.Data);
            var reply = new __RPC_Scene_SBCheckCharacterOnline_RET_Int32Array__();

            reply.ReturnValue = new Int32Array();
            foreach (var id in request.ToList.Items)
            {
                reply.ReturnValue.Items.Add(mCharacterInfoManager.ContainsKey(id) ? 1 : 0);
            }
            desc.Data = ProtocolExtension.Serialize(reply);
            client.SendMessage(desc);
        }
Exemple #12
0
        private void NotifyConnect(CharacterSceneInfo info, Action <ServiceDesc> callback)
        {
            ConnectLostLogger.Info("client {0} - {1} SceneBroker NotifyConnect 1", info.ClientId, info.CharacterId);
            Logger.Info("NotifyConnect {0}, {1}.", info.CharacterId, info.SceneInfo.Server.RemoteEndPoint);
            var desc = new ServiceDesc();

            desc.Type        = (int)MessageType.SS;
            desc.FuncId      = 3501;
            desc.CharacterId = info.CharacterId;
            desc.ClientId    = info.ClientId;
            desc.PacketId    = GetUniquePacketId();

            var content = new __RPC_Scene_SSNotifyCharacterOnConnet_ARG_uint64_clientId_uint64_characterId__();

            content.CharacterId = info.CharacterId;
            content.ClientId    = info.ClientId;
            desc.Data           = ProtocolExtension.Serialize(content);
            var act = new Action <bool, ServiceDesc>((b, item) =>
            {
                if (b)
                {
                    if (item.Error == 0)
                    {
                        ConnectLostLogger.Info("client {0} - {1} SceneBroker NotifyConnect 3", info.ClientId,
                                               info.CharacterId);
                        Logger.Info("Scene server Connected replied {0}", info.CharacterId);

                        callback(item);
                    }
                    else
                    {
                        ConnectLostLogger.Error("client {0} - {1} SceneBroker NotifyConnect 4", info.ClientId,
                                                info.CharacterId);
                        Logger.Error("NotifyConnect failed {0}....", item.Error);
                    }
                }
                else
                {
                    ConnectLostLogger.Error("client {0} - {1} SceneBroker NotifyConnect 5", info.ClientId,
                                            info.CharacterId);
                    Logger.Error("NotifyConnect timeout....");
                }
            });

            ConnectLostLogger.Info("client {0} - {1} SceneBroker NotifyConnect 2", info.ClientId, info.CharacterId);
            RegisterCallback(desc.PacketId, act);
            info.SceneInfo.Server.SendMessage(desc);
        }
Exemple #13
0
        //desc.FuncId == 3001   销毁场景
        public void DestroyScene(ServerClient client, ServiceDesc desc)
        {
            var       msg = ProtocolExtension.Deserialize <__RPC_Scene_SBDestroyScene_ARG_uint64_guid__>(desc.Data);
            var       ret = new __RPC_Scene_SBDestroyScene_RET_uint64__();
            SceneInfo info;

            if (mFromSceneGuid2Server.TryGetValue(msg.Guid, out info))
            {
                if (info.CharacterIds.Count == 0)
                {
                    SceneServerManager.RemoveScene(info.Server, 1);
                    ConcurrentDictionary <ulong, SceneInfo> scenes;
                    if (mFromServerIdAndSceneId2Guid.TryGetValue(CalcServerSceneId(info.ServerId, info.SceneId),
                                                                 out scenes))
                    {
                        SceneInfo info2;
                        scenes.TryRemove(msg.Guid, out info2);
                        //scenes.RemoveAll(item => item.SceneGuid == msg.Guid);
                        mFromSceneGuid2Server.TryRemove(msg.Guid, out info);
                        ret.ReturnValue = 1;
                    }
                    else
                    {
                        // 这种情况不应该发生
                        mLogger.Error(
                            "mFromSceneGuid2Server and mFromServerIdAndSceneId2Guid not consistent, {0},{1},{2}",
                            info.ServerId, info.SceneId, info.SceneGuid);
                        mFromSceneGuid2Server.TryRemove(msg.Guid, out info);
                        ret.ReturnValue = 1;
                    }
                }
                else
                {
                    ret.ReturnValue = 0;
                }
            }
            else
            {
                ret.ReturnValue = 0;
            }

            desc.Data = ProtocolExtension.Serialize(ret);
            client.SendMessage(desc);
        }
Exemple #14
0
        public static void PublishAccountData(this ProtocolExtension proto, Account acc)
        {
            var tas = proto.tas;

            if (acc != null && tas.ExistingUsers.ContainsKey(acc.Name))
            {
                var data = new Dictionary <string, string>
                {
                    { ProtocolExtension.Keys.Level.ToString(), acc.Level.ToString() },
                    { ProtocolExtension.Keys.EffectiveElo.ToString(), ((int)acc.EffectiveElo).ToString() },
                    { ProtocolExtension.Keys.Faction.ToString(), acc.Faction != null ? acc.Faction.Shortcut : "" },
                    { ProtocolExtension.Keys.Clan.ToString(), acc.Clan != null ? acc.Clan.Shortcut : "" },
                    { ProtocolExtension.Keys.Avatar.ToString(), acc.Avatar },
                    { ProtocolExtension.Keys.SpringieLevel.ToString(), acc.GetEffectiveSpringieLevel().ToString() },
                };
                if (acc.SteamID != null)
                {
                    data.Add(ProtocolExtension.Keys.SteamID.ToString(), acc.SteamID.ToString());
                }
                if (!string.IsNullOrEmpty(acc.SteamName) && acc.SteamName != acc.Name)
                {
                    data.Add(ProtocolExtension.Keys.DisplayName.ToString(), acc.SteamName);
                }

                if (acc.IsZeroKAdmin)
                {
                    data.Add(ProtocolExtension.Keys.ZkAdmin.ToString(), "1");
                }

                if (acc.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanMute))
                {
                    data.Add(ProtocolExtension.Keys.BanMute.ToString(), "1");
                }

                tas.Extensions.Publish(acc.Name, data);

                // if (acc.PunishmentsByAccountID.Any(x => x.BanExpires > DateTime.UtcNow && x.BanLobby)) tas.AdminKickFromLobby(acc.Name, "Banned");
                var penalty = acc.PunishmentsByAccountID.FirstOrDefault(x => x.BanExpires > DateTime.UtcNow && x.BanLobby);
                if (penalty != null)
                {
                    tas.AdminKickFromLobby(acc.Name, string.Format("Banned until {0}, reason: {1}", penalty.BanExpires, penalty.Reason));
                }
            }
        }
Exemple #15
0
        //func = 3499
        public void SeekSceneIndexByCharacterId(ServerClient client, ServiceDesc desc)
        {
            var msg =
                ProtocolExtension
                .Deserialize
                <__RPC_Scene_SBReconnectNotifyScene_ARG_uint64_oldclientId_uint64_newclientId_uint64_characterId__>(
                    desc.Data);

            var characterId = msg.CharacterId;
            var clientId    = msg.NewclientId;
            var oldClientId = msg.OldclientId;

            CommonBroker.CharacterInfo characterCommon;

            if (mBroker.mCharacterInfoManager.TryGetValue(characterId, out characterCommon))
            {
                var character = characterCommon as CharacterSceneInfo;
                if (character == null)
                {
                    return;
                }
                var index = mBroker.GetServerIndex(character.Server);
                if (index == -1)
                {
                    return;
                }

                var gateDesc = new ServiceDesc();
                gateDesc.Type        = (int)MessageType.ReConnetServerToGate;
                gateDesc.CharacterId = characterId;
                gateDesc.ServiceType = (int)ServiceType.Scene;
                gateDesc.ClientId    = clientId;

                gateDesc.Routing.Add(oldClientId);
                gateDesc.Routing.Add((ulong)index);

                character.Gate.Gate.SendMessage(gateDesc);
            }
        }
Exemple #16
0
        //funId = 3071
        public void MergeSceneByTeam(ServerClient client, ServiceDesc desc)
        {
            var msg = ProtocolExtension.Deserialize <__RPC_Scene_MergeSceneByTeam_ARG_IdList_ids__>(desc.Data);

            // 先按场景Id分组
            //var dict = msg.Ids.Ids.Select(i => mBroker.mFromCharacterId2Server[i]).ToLookup(k => k.SceneInfo.SceneId, v => v);

            var dict = new Dictionary <int, List <CharacterSceneInfo> >();

            foreach (var id in msg.Ids.Ids)
            {
                var c = mBroker.GetCharacter(id);
                if (c == null)
                {
                    continue;
                }
                List <CharacterSceneInfo> list;
                if (!dict.TryGetValue(c.SceneInfo.SceneId, out list))
                {
                    list = new List <CharacterSceneInfo>();
                    dict[c.SceneInfo.SceneId] = list;
                }
                list.Add(c);
            }


            foreach (var k in dict)
            {
                // 只合并非副本场景
                if (!IsNormalScene(Table.GetScene(k.Key)))
                {
                    continue;
                }

                var v = dict[k.Key];

                // 找到人最少的Server
                SceneInfo minCharacterSceneInfo = null;
                foreach (var info in v)
                {
                    if (minCharacterSceneInfo == null)
                    {
                        minCharacterSceneInfo = info.SceneInfo;
                        continue;
                    }

                    if (info.SceneInfo.CharacterIds.Count < minCharacterSceneInfo.CharacterIds.Count)
                    {
                        minCharacterSceneInfo = info.SceneInfo;
                    }
                }

                if (minCharacterSceneInfo == null)
                {
                    continue;
                }

                // 把其他人都移过去
                foreach (var info in v)
                {
                    // 如果可以跨服或者服务器Id相同,才可以合并
                    if (info.SceneInfo != minCharacterSceneInfo && (info.SceneInfo.SceneRecord.CanCrossServer == 1 || info.SceneInfo.ServerId == minCharacterSceneInfo.ServerId))
                    {
                        mBroker.ChangeScene(info.CharacterId, minCharacterSceneInfo);
                    }
                }
            }
        }
Exemple #17
0
 public override void OnSocketListenerMessageReceiveSB(ServerClient client, ServiceDesc desc)
 {
     // 换场景
     if (desc.FuncId == 3000)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             mWaitingEvents.Add(() => { ChangeScene(client, desc); });
         }
     }
     // 销毁场景
     else if (desc.FuncId == 3001)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             mWaitingEvents.Add(() => { mSceneManager.DestroyScene(client, desc); });
         }
     }
     //查询scene是否存在
     else if (desc.FuncId == 3002)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             mWaitingEvents.Add(() => { mSceneManager.NoHaveScene(client, desc); });
         }
     }
     // 检查是否在线
     else if (desc.FuncId == 3039)
     {
         CheckCharacterOnline(client, desc);
     } //广播表格重载
     else if (desc.FuncId == 3050)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             var info = ProtocolExtension.Deserialize <__RPC_Scene_SBReloadTable_ARG_string_tableName__>(desc.Data);
             mWaitingEvents.Add(() => { Table.ReloadTable(info.TableName); });
         }
     }
     else if (desc.FuncId == 3061)
     {
         OnNotifyConnected(desc);
     }
     else if (desc.FuncId == 3062)
     {
         OnNotifyLost(desc);
     }
     else if (desc.FuncId == 3063)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             mWaitingEvents.Add(() => { OnSceneFinished(desc); });
         }
     }
     else if (desc.FuncId == 3069)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             mWaitingEvents.Add(() => { ChangeSceneByTeam(client, desc); });
         }
     }
     else if (desc.FuncId == 3071)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             mWaitingEvents.Add(() => { mSceneManager.MergeSceneByTeam(client, desc); });
         }
     }
     else if (desc.FuncId == 3072)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             mWaitingEvents.Add(() => { mSceneManager.IsSceneExist(client, desc); });
         }
     }
     else if (desc.FuncId == 3499)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             mWaitingEvents.Add(() => { mSceneManager.SeekSceneIndexByCharacterId(client, desc); });
         }
     }
     else if (desc.FuncId == 3605)
     {
         if (!mWaitingEvents.IsAddingCompleted)
         {
             mWaitingEvents.Add(() => { mSceneManager.RequestSceneInfo(client, desc); });
         }
     }
     else
     {
         base.OnSocketListenerMessageReceiveSB(client, desc);
     }
 }
Exemple #18
0
        //创造新场景
        public void CreateNewScene(SceneInfo sceneInfo, SceneParam param = null)
        {
            var content =
                new __RPC_Scene_BSCreateScene_ARG_int32_serverId_int32_sceneId_uint64_guid_SceneParam_sceneParam__();

            content.ServerId   = sceneInfo.ServerId;
            content.SceneId    = sceneInfo.SceneId;
            content.Guid       = sceneInfo.SceneGuid;
            content.SceneParam = param ?? new SceneParam();

            var message = new ServiceDesc();

            message.FuncId      = 3010;
            message.ServiceType = (int)ServiceType.Scene;
            message.PacketId    = mBroker.GetUniquePacketId();
            message.Data        = ProtocolExtension.Serialize(content);
            message.Type        = (int)MessageType.BS;

            mLogger.Info("Notify Scene server CreateNewScene {0}, {1}, {2}", sceneInfo.ServerId, sceneInfo.SceneId,
                         sceneInfo.SceneGuid);

            ConcurrentDictionary <ulong, SceneInfo> infos;
            var serverSceneId = CalcServerSceneId(sceneInfo.ServerId, sceneInfo.SceneId);

            if (mFromServerIdAndSceneId2Guid.TryGetValue(serverSceneId, out infos))
            {
                infos.TryAdd(sceneInfo.SceneGuid, sceneInfo);
            }
            else
            {
                var temp = new ConcurrentDictionary <ulong, SceneInfo>();
                temp.TryAdd(sceneInfo.SceneGuid, sceneInfo);
                mFromServerIdAndSceneId2Guid.TryAdd(serverSceneId, temp);
            }

            mBroker.DebugCounter[17]++;
            mFromSceneGuid2Server.TryAdd(sceneInfo.SceneGuid, sceneInfo);

            SceneServerManager.CreateScene(sceneInfo.Server, 1);
            var act = new Action <bool, ServiceDesc>((b, item) =>
            {
                if (b)
                {
                    if (item.Error == 0)
                    {
                        mLogger.Info("Scene server CreateNewScene replied {0}, {1}, {2}", sceneInfo.ServerId,
                                     sceneInfo.SceneId, sceneInfo.SceneGuid);

                        sceneInfo.Status = SceneStatus.ReadyToEnter;

                        foreach (var action in sceneInfo.WaitingActions)
                        {
                            try
                            {
                                action();
                            }
                            catch (Exception ex)
                            {
                                mLogger.Error(ex, "Create new scene callback error.");
                            }
                        }

                        sceneInfo.WaitingActions.Clear();
                    }
                    else
                    {
                        mLogger.Error("CreateNewScene failed {0}....", item.Error);
                    }
                }
                else
                {
                    mLogger.Error("CreateNewScene timeout....");
                }
            });

            mBroker.RegisterCallback(message.PacketId, act);

            sceneInfo.Server.SendMessage(message);
        }
Exemple #19
0
        //desc.FuncId == 3000
        //单人切换场景
        public void ChangeScene(ServerClient client, ServiceDesc desc)
        {
            var characterId = desc.CharacterId;

            PlayerLog.WriteLog(888, "ChangeScene characterId={0}", characterId);
            Logger.Info("Character {0} chanage scene.", characterId);

            var info = GetCharacter(characterId);

            if (info == null)
            {
                // after prepare data, info must exist.
                Logger.Error("Can not find character info, {0}.", characterId);
                desc.Data = ProtocolExtension.Serialize(new __RPC_Scene_SBChangeScene_RET_uint64__
                {
                    ReturnValue = 0
                });
                client.SendMessage(desc);
                return;
            }

            Action changeScene = () =>
            {
                DebugCounter[0]++;
                Logger.Info("Enter Game {0} - ChangeScene - 1 - {1}", characterId, TimeManager.Timer.ElapsedMilliseconds);
                using (var ms = new MemoryStream(desc.Data, false))
                {
                    var msg =
                        Serializer
                        .Deserialize
                        <
                            __RPC_Scene_SBChangeScene_ARG_uint64_characterId_int32_serverId_int32_sceneId_uint64_guid_int32_changeType_SceneParam_sceneParam__
                        >(ms);
                    var param      = msg.SceneParam;
                    var changeType = msg.ChangeType;
                    var sceneInfo  = mSceneManager.SelectOldScene(msg.Guid, msg.ServerId, msg.SceneId, msg.CharacterId);

                    if (sceneInfo == null && msg.SceneId == -1)
                    {
                        PlayerLog.WriteLog(888, "ChangeScene characterId={0},ServerId={1},SceneId={2},SceneGuid={3}",
                                           msg.CharacterId, msg.ServerId, msg.SceneId, msg.Guid);
                        desc.Data = ProtocolExtension.Serialize(new __RPC_Scene_SBChangeScene_RET_uint64__
                        {
                            ReturnValue = 0
                        });
                        client.SendMessage(desc);
                        return;
                    }

                    if (sceneInfo == null)
                    {
                        Logger.Info("Enter Game {0} - ChangeScene - 2 - {1}", characterId,
                                    TimeManager.Timer.ElapsedMilliseconds);
                        sceneInfo = mSceneManager.CreateNewSceneInfo(msg.ServerId, msg.SceneId, msg.Guid);
                        sceneInfo.PushCharacter(msg.CharacterId);
                        var oldSceneInfo = info.SceneInfo;
                        oldSceneInfo.CharacterIds.Remove(msg.CharacterId);
                        info.SceneInfo = sceneInfo;
                        Logger.Info("change scene 1: {0}, {1}, {2}", characterId,
                                    oldSceneInfo.Server.RemoteEndPoint, sceneInfo.Server.RemoteEndPoint);

                        PlayerLog.WriteLog(888, "ChangeScene characterId={0},ServerId={1},SceneId={2},SceneGuid={3}",
                                           msg.CharacterId, msg.ServerId, msg.SceneId, msg.Guid);
                        DebugCounter[1]++;
                        param.ObjId = desc.CharacterId;
                        sceneInfo.WaitingActions.Add(() =>
                        {
                            DebugCounter[2]++;
                            Logger.Info("Enter Game {0} - ChangeScene - 3 - {1}", characterId,
                                        TimeManager.Timer.ElapsedMilliseconds);
                            ChangeSceneOver(info, oldSceneInfo, sceneInfo, b =>
                            {
                                PlayerLog.WriteLog(888, "ChangeSceneOver characterId={0},oldScene={1},newScene={2}",
                                                   desc.CharacterId, oldSceneInfo.SceneGuid, sceneInfo.SceneGuid);
                                DebugCounter[3]++;
                                desc.Data =
                                    ProtocolExtension.Serialize(new __RPC_Scene_SBChangeScene_RET_uint64__
                                {
                                    ReturnValue = sceneInfo.SceneGuid
                                });
                                client.SendMessage(desc);
                                mSceneManager.NotifyEnterScene(info, changeType, param);

                                info.State = CharacterInfoState.Connected;
                                if (info.WaitingChangeSceneAction != null)
                                {
                                    var call = info.WaitingChangeSceneAction;
                                    info.WaitingChangeSceneAction = null;
                                    call();
                                }
                            });
                        });
                        mSceneManager.CreateNewScene(sceneInfo, param);
                    }
                    else
                    {
                        var oldSceneInfo = info.SceneInfo;
                        if (oldSceneInfo != sceneInfo)
                        {
                            oldSceneInfo.CharacterIds.Remove(msg.CharacterId);
                            info.SceneInfo = sceneInfo;
                        }
                        Logger.Info("change scene 2: {0}, {1}, {2}", characterId,
                                    oldSceneInfo.Server.RemoteEndPoint, sceneInfo.Server.RemoteEndPoint);

                        DebugCounter[4]++;
                        var act = new Action(() =>
                        {
                            Logger.Info("Enter Game {0} - ChangeScene - 4 - {1}", characterId,
                                        TimeManager.Timer.ElapsedMilliseconds);
                            ChangeSceneOver(info, oldSceneInfo, sceneInfo, b =>
                            {
                                DebugCounter[5]++;
                                desc.Data =
                                    ProtocolExtension.Serialize(new __RPC_Scene_SBChangeScene_RET_uint64__
                                {
                                    ReturnValue = sceneInfo.SceneGuid
                                });
                                client.SendMessage(desc);
                                mSceneManager.NotifyEnterScene(info, changeType, param);

                                info.State = CharacterInfoState.Connected;
                                if (info.WaitingChangeSceneAction != null)
                                {
                                    var call = info.WaitingChangeSceneAction;
                                    info.WaitingChangeSceneAction = null;
                                    call();
                                }
                            });
                        });

                        if (sceneInfo.Status == SceneStatus.ReadyToEnter)
                        {
                            DebugCounter[6]++;
                            act();
                        }
                        else
                        {
                            DebugCounter[7]++;
                            sceneInfo.WaitingActions.Add(act);
                        }
                    }
                }
            };

            if (info.State == CharacterInfoState.Transfer)
            {
                info.WaitingChangeSceneAction = changeScene;
            }
            else
            {
                info.State = CharacterInfoState.Transfer;
                changeScene();
            }
        }
Exemple #20
0
        //desc.FuncId == 3069  一堆人同时进一个场景
        private void ChangeSceneByTeam(ServerClient client, ServiceDesc desc)
        {
            var msg =
                ProtocolExtension.Deserialize <__RPC_Scene_SBChangeSceneByTeam_ARG_ChangeSceneInfo_changeSceneData__>(
                    desc.Data);

            var sceneInfo = mSceneManager.SelectOldScene(msg.ChangeSceneData.SceneGuid, msg.ChangeSceneData.ServerId,
                                                         msg.ChangeSceneData.SceneId, 0, msg.ChangeSceneData.CheckFull);

            PlayerLog.WriteLog(888, "ChangeSceneByTeam characterId={0},ServerId={1},SceneId={2},SceneGuid={3}",
                               msg.ChangeSceneData.Guids.GetDataString(), msg.ChangeSceneData.ServerId, msg.ChangeSceneData.SceneId,
                               msg.ChangeSceneData.SceneGuid);
            // 如果场景不存在,不用造新的
            if (sceneInfo == null && msg.ChangeSceneData.SceneId == -1)
            {
                PlayerLog.WriteLog(888, "ChangeSceneByTeam not find and not new,guids={0}",
                                   msg.ChangeSceneData.Guids.GetDataString());
                desc.Data = ProtocolExtension.Serialize(new __RPC_Scene_SBChangeSceneByTeam_RET_uint64__
                {
                    ReturnValue = 0
                });
                client.SendMessage(desc);
                return;
            }

            var param = msg.ChangeSceneData.Pos;

            if (param == null)
            {
                param = new SceneParam();
            }

            param.ObjId = desc.CharacterId;

            if (sceneInfo == null)
            {
                sceneInfo = mSceneManager.CreateNewSceneInfo(msg.ChangeSceneData.ServerId, msg.ChangeSceneData.SceneId,
                                                             msg.ChangeSceneData.SceneGuid);
                mSceneManager.CreateNewScene(sceneInfo, param);
                //sceneInfo.PushCharacter(desc.CharacterId);
            }

            desc.Data =
                ProtocolExtension.Serialize(new __RPC_Scene_SBChangeSceneByTeam_RET_uint64__
            {
                ReturnValue = sceneInfo.SceneGuid
            });
            client.SendMessage(desc);

            var changeSceneInfos = new List <ChangeSceneInfo>();

            foreach (var characterId in msg.ChangeSceneData.Guids)
            {
                sceneInfo.CharacterIds.Add(characterId);
                var info = GetCharacter(characterId);
                if (info == null)
                {
                    continue;
                }
                var oldSceneInfo = info.SceneInfo;
                if (oldSceneInfo != sceneInfo)
                {
                    oldSceneInfo.CharacterIds.Remove(characterId);
                    info.SceneInfo = sceneInfo;
                }

                changeSceneInfos.Add(new ChangeSceneInfo
                {
                    Info         = info,
                    OldSceneInfo = oldSceneInfo,
                    NewSceneInfo = sceneInfo
                });
            }

            var type = msg.ChangeSceneData.Type;

            var act = new Action(() =>
            {
                PlayerLog.WriteLog(888, "ChangeSceneByTeam not find! new scene over guids={0}",
                                   msg.ChangeSceneData.Guids.GetDataString());
                foreach (var changeSceneInfo in changeSceneInfos)
                {
                    Logger.Info("Enter Game {0} {1} {2} - ChangeSceneByTeam - 2 - {3}", changeSceneInfo.Info.CharacterId,
                                changeSceneInfo.OldSceneInfo.SceneGuid, changeSceneInfo.NewSceneInfo.SceneGuid,
                                TimeManager.Timer.ElapsedMilliseconds);
                    ChangeSceneOver(changeSceneInfo.Info, changeSceneInfo.OldSceneInfo, changeSceneInfo.NewSceneInfo,
                                    b => { mSceneManager.NotifyEnterScene(changeSceneInfo.Info, type, param); });
                }
            });

            if (sceneInfo.Status == SceneStatus.ReadyToEnter)
            {
                act();
            }
            else
            {
                sceneInfo.WaitingActions.Add(act);
            }
        }
Exemple #21
0
        // 服务器收到消息

        public override void ServerOnMessageReceived(ServiceDesc desc)
        {
            try
            {
                var type = (MessageType)desc.Type;
                Logger.Debug("ServerOnMessageReceived ,type={0},FuncId={1}", type, desc.FuncId);
                switch (type)
                {
                case MessageType.CS:
                    Logger.Error("SceneBroker ServerOnMessageReceived MessageType.CS is Error! FuncId={0}",
                                 desc.FuncId);
                    break;

                case MessageType.SC:
                    Logger.Error("SceneBroker ServerOnMessageReceived MessageType.SC is Error! FuncId={0}",
                                 desc.FuncId);
                    break;

                case MessageType.Connect:
                    Logger.Error("SceneBroker ServerOnMessageReceived MessageType.Connect is Error! FuncId={0}",
                                 desc.FuncId);
                    break;

                case MessageType.Lost:
                    Logger.Error("SceneBroker ServerOnMessageReceived MessageType.Lost is Error! FuncId={0}",
                                 desc.FuncId);
                    break;

                case MessageType.Sync:
                    Logger.Error("SceneBroker ServerOnMessageReceived MessageType.Sync is Error! FuncId={0}",
                                 desc.FuncId);
                    break;

                case MessageType.Ping:
                    break;

                case MessageType.SB:
                    Logger.Error("SceneBroker ServerOnMessageReceived MessageType.SB is Error! FuncId={0}",
                                 desc.FuncId);
                    break;

                case MessageType.BS:
                    OnSocketListenerMessageReceiveBS(desc);
                    return;

                case MessageType.SCAll:
                    Logger.Error("SceneBroker ServerOnMessageReceived MessageType.SCAll is Error!");
                    break;

                case MessageType.SCServer:
                    OnSocketClientMessageReceivedSCServer(desc);
                    return;

                case MessageType.SCList:
                    OnSocketClientMessageReceivedSCList(desc);
                    return;

                case MessageType.SS:
                case MessageType.SAS:
                case MessageType.PrepareData:
                    var routing = GetRouting(desc);
                    if (routing == ulong.MaxValue)
                    {
                        if (desc.FuncId == 3501)
                        {
                            OnNotifyConnected(desc);
                            return;
                        }
                        return;
                    }
                    if (desc.FuncId == 3051)
                    {
                        var chara = GetCharacter(desc.CharacterId);
                        //Logger.Fatal("PrepareDataForEnterGame  sceneGuid = {0}", chara.SceneInfo.SceneGuid);
                        if (chara != null)
                        {
                            var content = new __RPC_Scene_PrepareDataForEnterGame_RET_uint64__();
                            content.ReturnValue = chara.SceneInfo.SceneGuid;
                            desc.Data           = ProtocolExtension.Serialize(content);
                        }
                    }
                    mFrontEndServer.Clients[routing].SendMessage(desc);
                    return;

                case MessageType.SASReply:
                    Logger.Error("SceneBroker ServerOnMessageReceived MessageType.SASReply is Error! FuncId={0}",
                                 desc.FuncId);
                    break;

                default:
                    Logger.Error("SceneBroker ServerOnMessageReceived MessageType.SB is Error! FuncId={0}",
                                 desc.FuncId);
                    return;
                }
                var character = GetCharacterInfo(desc.CharacterId);
                if (character == null)
                {
                    Logger.Error(
                        "SceneBroker ServerOnMessageReceived character = null desc.CharacterId :{0} ,funcId={1},ServiceType={2},clientId={3},type={4}",
                        desc.CharacterId, desc.FuncId, desc.ServiceType, desc.ClientId, desc.Type);
                    return;
                }
                if (character.Gate == null)
                {
                    Logger.Error("Can not reply message for character 9 = null desc.CharacterI0d :{0} ",
                                 desc.CharacterId);
                    return;
                }
                // desc.ClientId = character.ClientId;
                character.Gate.Gate.SendMessage(desc);
            }
            catch (Exception ex)
            {
                Logger.Warn(ex, "Some error inside ClientMessageReceived ");
            }
        }
Exemple #22
0
        public virtual void OnSocketListenerMessageReceiveSB(ServerClient client, ServiceDesc desc)
        {
            if (desc.FuncId % 1000 == 30)
            {
//SBGetAllOnlineCharacterInServer
                var info =
                    ProtocolExtension.Deserialize <__RPC_Logic_SBGetAllOnlineCharacterInServer_ARG_int32_serverId__>(
                        desc.Data);
                ConcurrentDictionary <ulong, int> bag;
                if (mFromServerId2CharacterId.TryGetValue((uint)info.ServerId, out bag))
                {
                    var ret =
                        new __RPC_Logic_SBGetAllOnlineCharacterInServer_RET_Uint64Array__();
                    ret.ReturnValue.Items.AddRange(bag.Keys);

                    desc.Data = ProtocolExtension.Serialize(ret);
                    client.SendMessage(desc);
                }
            }
            else if (desc.FuncId % 1000 == 40)
            {
                // QueryBrokerStatus
                //var ret = new __RPC_Logic_QueryBrokerStatus_RET_CommonBrokerStatus__();
                //var status = ret.ReturnValue = new CommonBrokerStatus();
                //status.CommonStatus = new ServerCommonStatus();
                //status.CommonStatus.ByteReceivedPerSecond = (uint) mFrontEndServer.ByteReceivedPerSecond;
                //status.CommonStatus.ByteSendPerSecond = (uint) mFrontEndServer.ByteSendPerSecond;
                //status.CommonStatus.MessageReceivedPerSecond = (uint) mFrontEndServer.MessageReceivedPerSecond;
                //status.CommonStatus.MessageSendPerSecond = (uint) mFrontEndServer.MessageSendPerSecond;
                //status.CommonStatus.ConnectionCount = (uint) mFrontEndServer.ConnectionCount;

                //status.ConnectionInfo.AddRange(mBackEnds.Select(item =>
                //{
                //    var conn = new ConnectionStatus();
                //    conn.ByteReceivedPerSecond = (uint) item.ByteReceivedPerSecond;
                //    conn.ByteSendPerSecond = (uint) item.ByteSendPerSecond;
                //    conn.MessageReceivedPerSecond = (uint) item.MessageReceivedPerSecond;
                //    conn.MessageSendPerSecond = (uint) item.MessageSendPerSecond;
                //    conn.Target = (uint) ((UserData) item.UserData).Id;
                //    conn.Latency = (float) item.Latency.TotalMilliseconds;

                //    return conn;
                //}));

                //desc.Data = ProtocolExtension.Serialize(ret);
                //client.SendMessage(desc);
            }
            else if (desc.FuncId % 1000 == 500)
            {
//收到login断线清理
                OnSocketListenerMessageReceiveCleanEx(desc);
            }
            else if (desc.FuncId % 1000 == 502)
            {
                var ret = new __RPC_Scene_SBGetServerCharacterCount_RET_Dict_int_int_Data__();
                ret.ReturnValue = new Dict_int_int_Data();
                foreach (var s in mFromServerId2CharacterId)
                {
                    ret.ReturnValue.Data.Add((int)s.Key, s.Value.Count);
                }
                desc.Data = ProtocolExtension.Serialize(ret);
                client.SendMessage(desc);
            }
            else if (desc.FuncId % 1000 == 503)
            {
//                 var info = ProtocolExtension.Deserialize<__RPC_Scene_SBModifyCharacterClientId_ARG_uint64_oldClientId_uint64_newClientId_uint64_characterId__>(desc.Data);
//                 var character = GetCharacterInfo(info.CharacterId);
//                 if (character == null)
//                 {
//                     client.SendMessage(desc);
//                     return;
//                 }
//                 if (character.ClientId != info.OldClientId)
//                 {
//                     Logger.Error("funID%1000=503,brokerClientId={0},oldClientId={1},newClientId={2}", character.ClientId, info.OldClientId, info.NewClientId);
//                     client.SendMessage(desc);
//                     return;
//                 }
//
//                 //执行
//                 ulong brokerId;
//                 mFromClientId2CharacterId.TryRemove(character.ClientId, out brokerId);
//                 mFromClientId2CharacterId.TryAdd(character.ClientId, info.CharacterId);
//                 character.ClientId = info.NewClientId;
//                 var ret = new __RPC_Scene_SBModifyCharacterClientId_RET_int32__();
//                 ret.ReturnValue = 1;
//                 desc.Data = ProtocolExtension.Serialize(ret);
//                 client.SendMessage(desc);
            }
            else
            {
                Logger.Error(
                    "OnSocketListenerMessageReceiveSB faild!! ClientId={0},CharacterId={1},FuncId={2},ServiceType={3}",
                    desc.ClientId, desc.CharacterId, desc.FuncId, desc.ServiceType);
            }
        }
Exemple #23
0
        /// <summary>
        ///     This function will be called in multithread, so THREAD SAFE is very important.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="desc"></param>
        private void ClientMessageReceived(ServerClient client, ServiceDesc desc)
        {
            try
            {
                Logger.Debug("Received a message from Client {0}, {1}.", client.ClientId, ((IPEndPoint)client.RemoteEndPoint).Address.MapToIPv4());

                if (desc.ServiceType == (int)ServiceType.Directory)

                {
                    switch (desc.FuncId)
                    {
                    case 8000:
                    {
                        var info =
                            ProtocolExtension
                            .Deserialize
                            <
                                __RPC_Directory_CheckVersion_ARG_string_lang_string_platform_string_channel_string_version__
                            >(desc.Data);

                        var lang     = info.Lang.ToLowerInvariant();
                        var platform = info.Platform.ToLowerInvariant();
                        var channel  = info.Channel.ToLowerInvariant();
                        var big      = info.Version;

                        var sb = new StringBuilder();
                        sb.Append(lang);
                        sb.Append(".");
                        sb.Append(platform);
                        sb.Append(".");
                        sb.Append(channel);
                        sb.Append(".");
                        sb.Append(big);

                        try
                        {
                            mLock.EnterReadLock();

                            Content c;
                            if (mContents.TryGetValue(sb.ToString(), out c))
                            {
                                var ret = new __RPC_Directory_CheckVersion_RET_VersionInfo__();
                                ret.ReturnValue = new VersionInfo();
                                ret.ReturnValue.SmallVersion   = c.SmallVersion;
                                ret.ReturnValue.AnnoucementURL = c.AnnoucementURL;
                                ret.ReturnValue.ResourceURL    = c.ResourceURL;
                                ret.ReturnValue.HasNewVersion  = c.HasNewVersion ? 1 : 0;
                                ret.ReturnValue.NewVersionURL  = c.NewVersionURL;
                                ret.ReturnValue.ReviewState    = c.ReviewState;

                                var length = c.GateAddress.Length;
                                if (length > 0)
                                {
                                    if (length == 1)
                                    {
                                        ret.ReturnValue.GateAddress = c.GateAddress[0];
                                    }
                                    else
                                    {
                                        ret.ReturnValue.GateAddress = c.GateAddress[random.Next(length)];
                                    }
                                }

                                desc.Data = ProtocolExtension.Serialize(ret);

                                client.SendMessage(desc);
                            }
                            else
                            {
                                desc.Data  = null;
                                desc.Error = 1;
                                client.SendMessage(desc);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex, "8000 error.");
                        }
                        finally
                        {
                            mLock.ExitReadLock();
                        }
                    }
                    break;

                    case 8001:
                    {
                        var info =
                            ProtocolExtension
                            .Deserialize
                            <
                                __RPC_Directory_CheckVersion_ARG_string_lang_string_platform_string_channel_string_version__
                            >(desc.Data);

                        var lang     = info.Lang.ToLowerInvariant();
                        var platform = info.Platform.ToLowerInvariant();
                        var channel  = info.Channel.ToLowerInvariant();
                        var big      = info.Version;

                        var sb = new StringBuilder();
                        sb.Append(lang);
                        sb.Append(".");
                        sb.Append(platform);
                        sb.Append(".");
                        sb.Append(channel);
                        sb.Append(".");
                        sb.Append(big);

                        try
                        {
                            mLock.EnterReadLock();

                            Content c;
                            if (mContents.TryGetValue(sb.ToString(), out c))
                            {
                                var ret = new __RPC_Directory_CheckVersion_RET_VersionInfo__();
                                ret.ReturnValue = new VersionInfo();
                                ret.ReturnValue.SmallVersion   = c.SmallVersion;
                                ret.ReturnValue.AnnoucementURL = c.AnnoucementURL;
                                ret.ReturnValue.ResourceURL    = c.ResourceURL;
                                ret.ReturnValue.HasNewVersion  = c.HasNewVersion ? 1 : 0;
                                ret.ReturnValue.NewVersionURL  = c.NewVersionURL;
                                ret.ReturnValue.ReviewState    = c.ReviewState;

                                ret.ReturnValue.GateAddress = c.GateAddressString;

                                desc.Data = ProtocolExtension.Serialize(ret);

                                client.SendMessage(desc);
                            }
                            else
                            {
                                desc.Data  = null;
                                desc.Error = 1;
                                client.SendMessage(desc);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex, "8001 error.");
                        }
                        finally
                        {
                            mLock.ExitReadLock();
                        }
                    }
                    break;

                    case 8002:
                    {
                        var info =
                            ProtocolExtension
                            .Deserialize
                            <
                                __RPC_Directory_CheckVersion3_ARG_string_lang_string_platform_string_channel_string_version__
                            >(desc.Data);

                        var lang     = info.Lang.ToLowerInvariant();
                        var platform = info.Platform.ToLowerInvariant();
                        var channel  = info.Channel.ToLowerInvariant();
                        var big      = info.Version;

                        var sb = new StringBuilder();
                        sb.Append(lang);
                        sb.Append(".");
                        sb.Append(platform);
                        sb.Append(".");
                        sb.Append(channel);
                        sb.Append(".");
                        sb.Append(big);

                        try
                        {
                            mLock.EnterReadLock();

                            Content c;
                            if (mContents.TryGetValue(sb.ToString(), out c))
                            {
                                var ret = new __RPC_Directory_CheckVersion3_RET_VersionInfo__();
                                ret.ReturnValue = new VersionInfo();
                                ret.ReturnValue.SmallVersion   = c.SmallVersion;
                                ret.ReturnValue.AnnoucementURL = c.AnnoucementURL;
                                ret.ReturnValue.ResourceURL    = c.ResourceURL;
                                ret.ReturnValue.HasNewVersion  = c.HasNewVersion ? 1 : 0;
                                ret.ReturnValue.NewVersionURL  = c.NewVersionURL;
                                ret.ReturnValue.ReviewState    = c.ReviewState;

                                if (c.IpWhiteList.Contains(((IPEndPoint)client.RemoteEndPoint).Address.MapToIPv4().ToString()))
                                {
                                    ret.ReturnValue.GateAddress = c.RetargetGateAddress;
                                }
                                else
                                {
                                    ret.ReturnValue.GateAddress = c.GateAddressString;
                                }
                                ret.ReturnValue.ForceShowAnn = c.ForceShowAnn;
                                ret.ReturnValue.Isbn         = c.Isbn;
                                desc.Data = ProtocolExtension.Serialize(ret);

                                client.SendMessage(desc);
                            }
                            else
                            {
                                desc.Data  = null;
                                desc.Error = 1;
                                client.SendMessage(desc);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex, "8001 error.");
                        }
                        finally
                        {
                            mLock.ExitReadLock();
                        }
                    }
                    break;

                    default:
                        Logger.Error("Unknown funcion id:{0}", desc.FuncId);
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Error(e, "ClientMessageReceived");
            }
        }
 string GetExtension(ProtocolExtension.Keys key) {
     string txt;
     Extensions.TryGetValue(key.ToString(), out txt);
     return txt;
 }