Пример #1
0
        /// <summary>
        /// Handles a <see cref="AcquireServerResponse"/>.
        /// </summary>
        private void HandleOperationResponseAcquireServerResponse(IRpcProtocol protocol, OperationResponse operationResponse)
        {
            var response = new AcquireServerResponse(protocol, operationResponse);

            if (!response.IsValid || operationResponse.ReturnCode != (short)ResultCode.Ok)
            {
#if MMO_DEBUG
                _logger.DebugFormat("Re-acquiring chat server connection info. ResponseValid?={0}. ReturnCode={1}.", response.IsValid, operationResponse.ReturnCode);
#endif
                this.AcquireChatServerConnection(ServerSettings.SERVER_RECONNECT_INTERVAL);
                return;
            }

            Interlocked.CompareExchange(ref listenerState, (int)ListenerState.Connecting, (int)ListenerState.Disconnected);

            var newListenerState = ListenerState;
            if (newListenerState != ListenerState.Connecting)
            {
                _logger.ErrorFormat("[HandleOperationResponseAcquireServerResponse]: Invalid listener state (State={0})", newListenerState);
                return;
            }

            var ipAddress = IPAddress.Parse(response.Address);
            var port      = response.TcpPort;
            WorldApplication.Instance.ConnectToExternalServer(new IPEndPoint(ipAddress, port), "Chat", this);
        }
Пример #2
0
        protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
        {
            this.application.MasterLobby.OnServerDisconnected(this);
#if MMO_DEBUG
            Logger.DebugFormat("Server (Id={0}:{1}) Disconnected.", this.ServerId, this.ServerType);
#endif
        }
Пример #3
0
        protected override void Setup()
        {
            // this will let us send raw bytes
            Protocol.AllowRawCustomValues = true;
            // init the settings
            this.Settings    = ServerConfig.Initialize(this.BinaryPath);
            this.MasterLobby = new Lobby();
            // register custom types
            TypeSerializer.RegisterType(CustomTypeCode.Guid);
            // setup logging
            this.SetupLogging();
            // log any unhandled exception
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            if (Logger.IsDebugEnabled)
            {
                Logger.DebugFormat("(:> ********** <:) MasterServer Started > {0} (:> ********** <:)", DateTime.Now);
            }
        }
Пример #4
0
        /// <summary>
        ///   Publishes a <see cref = "ItemPositionMessage" /> in the <see cref = "PositionUpdateChannel" />
        ///   and in the current <see cref = "Region" /> if it changes
        ///   and then updates the <see cref = "CurrentWorldRegion" />.
        /// </summary>
        public void UpdateInterestManagement()
        {
            Region newRegion = this.World.GetRegion(this.Position);

            // inform attached and auto subscribed (delayed) interest areas
            ItemPositionMessage message = this.GetPositionUpdateMessage(this.Position, newRegion);

            this.positionUpdateChannel.Publish(message);

            if (this.SetCurrentWorldRegion(newRegion))
            {
                // inform unsubscribed interest areas in new region
                ItemSnapshot snapshot = this.GetItemSnapshot();
                newRegion.Publish(snapshot);

#if MissingSubscribeDebug
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("{0} sent snap shot to region {1}", this.id, newRegion.Coordinate);
                }
#endif
            }
        }
Пример #5
0
        /// <summary>
        ///   Increments <see cref = "MessageCounters.CounterReceive" /> and subscribes the <see cref = "InterestArea" /> to the <see cref = "Source" /> item if it not already subscribed or attached.
        ///   Called by the <see cref = "InterestArea" /> when received.
        /// </summary>
        /// <param name = "interestArea">
        ///   The calling interest area.
        /// </param>
        public override void OnInterestAreaReceive(InterestArea interestArea)
        {
            MessageCounters.CounterReceive.Increment();

            interestArea.ReceiveItemSnapshot(this);
#if MissingSubscribeDebug
            if (log.IsDebugEnabled)
            {
                log.DebugFormat("{1} received snap shot from item {0} - region {2}",
                                this.source.Id,
                                interestArea.GetHashCode(),
                                this.WorldRegion.Coordinate);
            }
#endif
        }
Пример #6
0
        /// <summary>
        ///   Called by the <see cref = "Item" /> when received.
        ///   Increments <see cref = "MessageCounters.CounterReceive" /> and publishes an <see cref = "ItemPositionMessage" /> in the <paramref name = "item" />'s <see cref = "Item.CurrentWorldRegion" />.
        /// </summary>
        /// <param name = "item">
        ///   The calling item.
        /// </param>
        public override void OnItemReceive(Item item)
        {
            MessageCounters.CounterReceive.Increment();

            ItemSnapshot itemSnapshot = item.GetItemSnapshot();

            this.source.ReceiveItemSnapshot(itemSnapshot);

#if MissingSubscribeDebug
            if (log.IsDebugEnabled)
            {
                log.DebugFormat(
                    "{0} sent snap shot to interest area {1} - region {2}",
                    item.Id,
                    this.source.GetHashCode(),
                    itemSnapshot.WorldRegion.Coordinate);
            }
#endif
        }
Пример #7
0
        public MasterClientPeer(InitRequest initRequest, MasterApplication application)
            : base(initRequest.Protocol, initRequest.PhotonPeer)
        {
            this.application = application;
            this.clientId    = Utils.NewGuidInt32();

            this.LoginData            = null;
            this.WorldServer          = null;
            this.CurrentState         = ClientPeerState.Connect;
            this.IsSafelyDisconnected = false;

            this.Application.MasterLobby.OnClientConnected(this);
#if MMO_DEBUG
            if (_logger.IsDebugEnabled)
            {
                _logger.DebugFormat("Client (Id={0}) Connected", clientId);
            }
#endif
        }
Пример #8
0
        private GameOperationResponse HandleOperationSendChat(GameOperationRequest operationRequest)
        {
            var operation = new SendChat(server.Protocol, operationRequest);

            if (!operation.IsValid)
            {
                return new GameErrorResponse(operationRequest.OperationCode)
                       {
                           ReturnCode = (short)ResultCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage()
                       }
            }
            ;

            switch ((MessageType)operation.MessageType)
            {
            case MessageType.Group:
            {
                lock (joinedChannels)
                {
                    var channel = this.joinedChannels.Find(chnl => chnl.Type == ChannelType.Group);
                    if (channel == null)
                    {
                        return new SendChatResponse(operation.OperationCode)
                               {
                                   ReturnCode = (short)ResultCode.ChannelNotAvailable, MessageType = operation.MessageType
                               }
                    }
                    ;

                    // TODO: Normalize content and prevent spam
                    var message = operation.Message;
                    if (string.IsNullOrEmpty(message))
                    {
                        return(operation.GetErrorResponse((short)ResultCode.MessageIsEmpty));
                    }

                    channel.Publish(message, this);
                }
            }
            break;

            case MessageType.Guild:
            {
                lock (joinedChannels)
                {
                    var channel = this.joinedChannels.Find(chnl => chnl.Type == ChannelType.Guild);
                    if (channel == null)
                    {
                        return new SendChatResponse(operation.OperationCode)
                               {
                                   ReturnCode = (short)ResultCode.ChannelNotAvailable, MessageType = operation.MessageType
                               }
                    }
                    ;

                    // TODO: Normalize content and prevent spam
                    var message = operation.Message;
                    if (string.IsNullOrEmpty(message))
                    {
                        return(operation.GetErrorResponse((short)ResultCode.MessageIsEmpty));
                    }

                    channel.Publish(message, this);
                }
            }
            break;

            case MessageType.Local:
            {
                lock (joinedChannels)
                {
                    var channel = this.joinedChannels.Find(chnl => chnl.Type == ChannelType.Local);
                    if (channel == null)
                    {
                        return new SendChatResponse(operation.OperationCode)
                               {
                                   ReturnCode = (short)ResultCode.ChannelNotAvailable, MessageType = operation.MessageType
                               }
                    }
                    ;

                    // TODO: Normalize content and prevent spam
                    var message = operation.Message;
                    if (string.IsNullOrEmpty(message))
                    {
                        return(operation.GetErrorResponse((short)ResultCode.MessageIsEmpty));
                    }

                    channel.Publish(message, this);
                }
            }
            break;

            case MessageType.Trade:
            {
                lock (joinedChannels)
                {
                    var channel = this.joinedChannels.Find(chnl => chnl.Type == ChannelType.Trade);
                    if (channel == null)
                    {
                        return new SendChatResponse(operation.OperationCode)
                               {
                                   ReturnCode = (short)ResultCode.ChannelNotAvailable, MessageType = operation.MessageType
                               }
                    }
                    ;

                    // TODO: Normalize content and prevent spam
                    var message = operation.Message;
                    if (string.IsNullOrEmpty(message))
                    {
                        return(operation.GetErrorResponse((short)ResultCode.MessageIsEmpty));
                    }

                    channel.Publish(message, this);
                }
            }
            break;

            case MessageType.Tell:
            {
                var receiverName = operation.Receiver;
                if (string.IsNullOrEmpty(receiverName))
                {
                    return(operation.GetErrorResponse((short)ResultCode.PlayerNotFound));
                }

                ChatSession receiver;
                if (!chat.SessionCache.TryGetSessionBySessionName(receiverName, out receiver))
                {
                    return(operation.GetErrorResponse((short)ResultCode.PlayerNotFound));
                }

                // TODO: Normalize content and prevent spam
                var message = operation.Message;
                if (string.IsNullOrEmpty(message))
                {
                    return(operation.GetErrorResponse((short)ResultCode.MessageIsEmpty));
                }

                receiver.ReceiveTell(this, message);
            }
            break;

            default:
            {
#if MMO_DEBUG
                _logger.DebugFormat("[HandleOperationSendChat]: Session (Name={0}) sent an unhandled Message (Type={1})", name,
                                    (MessageType)operation.MessageType);
#endif
            }
            break;
            }

            return(null);
        }

        /// <summary>
        /// Call this to handle client operation requests
        /// </summary>
        void OnOperationRequest(GameOperationRequest operationRequest, MessageParameters messageParameters)
        {
            GameOperationResponse response;

            switch ((GameOperationCode)operationRequest.OperationCode)
            {
            case GameOperationCode.SendChat:
                response = this.HandleOperationSendChat(operationRequest);
                break;

            default:
                response = new GameErrorResponse(operationRequest.OperationCode)
                {
                    ReturnCode = (short)ResultCode.OperationNotAvailable
                };
                break;
            }

            if (response != null)
            {
                this.SendOperationResponse(response, messageParameters);
            }
        }

        #endregion

        #region Helper Methods

        void DoAddSession()
        {
            // adding session to the chat
            while (!chat.AddSession(this))
            {
                ChatSession exisitingSession;
                if (chat.SessionCache.TryGetSessionBySessionId(sessionId, out exisitingSession))
                {
                    // this shouldn't happen because the master won't let the same player login twice it will disconnect the exisitng player
                    // we are handling it to satisfy Murphy's Law
#if MMO_DEBUG
                    _logger.DebugFormat("[DoAddSession]: ChatSession (Name={0}) cannot be added because an existing ChatSession (Name={1}) is found",
                                        this.Name, exisitingSession.Name);
#endif
                    exisitingSession.Disconnect();
                    this.Disconnect();
                    this.Destroy(DestroySessionReason.KickedByExistingSession);
                    return;
                }
            }
        }

        #endregion
    }