Пример #1
0
        /// <summary>
        /// Handles the those commands send by the client through a TCP socket.
        /// </summary>
        protected void HandleCommandsThreadMethod()
        {
            Message        messageToProcess        = null;
            ManagedMessage managedMessageReference = null;

            if (!this.ableToRun)
            {
                KSPMGlobals.Globals.Log.WriteTo(Error.ErrorType.ServerUnableToRun.ToString());
            }
            try
            {
                KSPMGlobals.Globals.Log.WriteTo("-Starting to handle commands[ " + this.alive + " ]");
                while (this.alive)
                {
                    this.commandsQueue.DequeueCommandMessage(out messageToProcess);
                    if (messageToProcess != null)
                    {
                        managedMessageReference = (ManagedMessage)messageToProcess;
                        switch (messageToProcess.Command)
                        {
                        case Message.CommandType.Chat:
                            this.clientsHandler.TCPBroadcastTo(this.chatManager.GetChatGroupById(ChatMessage.InflateTargetGroupId(messageToProcess.bodyMessage)).MembersAsList, messageToProcess);

                            /*
                             * if (ChatMessage.InflateChatMessage(messageToProcess.bodyMessage, out chatMessage) == Error.ErrorType.Ok)
                             * {
                             *  //KSPMGlobals.Globals.Log.WriteTo(string.Format("[{0}][{1}_{2}]-Says:{3}", managedMessageReference.OwnerNetworkEntity.Id, chatMessage.Time.ToShortTimeString(), chatMessage.sendersUsername, chatMessage.Body));
                             *  this.clientsHandler.TCPBroadcastTo(this.chatManager.AttachMessage(chatMessage).MembersAsList, messageToProcess);
                             * }
                             */
                            break;

                        case Message.CommandType.KeepAlive:
                            KSPMGlobals.Globals.Log.WriteTo("KeepAlive command: " + messageToProcess.Command.ToString());
                            break;

                        case Message.CommandType.Unknown:
                        default:
                            KSPMGlobals.Globals.Log.WriteTo("Unknown command: " + messageToProcess.Command.ToString());
                            break;
                        }
                        ///Releasing and recycling the message.
                        this.incomingMessagesPool.Recycle(messageToProcess);
                    }
                    else
                    {
                        ///Yielding the process.
                        Thread.Sleep(0);
                    }
                }
            }
            catch (ThreadAbortException)
            {
                this.alive = false;
            }
        }
Пример #2
0
        /// <summary>
        /// Handles the TCP socket and the main Queue of messages, uses the a TCP socket to send messages.
        /// </summary>
        protected void HandleOutgoingPriorityMessagesThreadMethod()
        {
            Message        outgoingMessage  = null;
            ManagedMessage managedReference = null;

            if (!this.ableToRun)
            {
                KSPMGlobals.Globals.Log.WriteTo(Error.ErrorType.ServerUnableToRun.ToString());
            }
            try
            {
                KSPMGlobals.Globals.Log.WriteTo("-Starting to handle outgoing messages[ " + this.alive + " ]");
                while (this.alive)
                {
                    this.priorityOutgoingMessagesQueue.DequeueCommandMessage(out outgoingMessage);
                    if (outgoingMessage != null)
                    {
                        //KSPMGlobals.Globals.Log.WriteTo(string.Format("[{0}]===Error==={1}.", outgoingMessage.bodyMessage[ 4 ], outgoingMessage.Command));
                        managedReference = (ManagedMessage)outgoingMessage;
                        try
                        {
                            ///Checking if the NetworkEntity is still running.
                            if (managedReference.OwnerNetworkEntity.IsAlive())
                            {
                                KSPMGlobals.Globals.Log.WriteTo(outgoingMessage.Command.ToString());
                                managedReference.OwnerNetworkEntity.ownerNetworkCollection.socketReference.BeginSend(outgoingMessage.bodyMessage, 0, (int)outgoingMessage.MessageBytesSize, SocketFlags.None, new AsyncCallback(this.AsyncSenderCallback), managedReference.OwnerNetworkEntity);
                            }
                        }
                        catch (System.Exception ex)
                        {
                            KSPMGlobals.Globals.Log.WriteTo(string.Format("[{0}][\"{1}-{2}\"] Something went wrong with the remote client, performing a removing process on it.", managedReference.OwnerNetworkEntity.Id, "HandleOutgoingPriorityMessages", ex.Message));
                            this.DisconnectClient(managedReference.OwnerNetworkEntity);
                        }

                        ///Releasing the processed command.
                        outgoingMessage.Release();
                        outgoingMessage = null;
                    }
                    Thread.Sleep(1);
                }
            }
            catch (ThreadAbortException)
            {
                this.alive = false;
            }
        }
Пример #3
0
        /// <summary>
        /// Handles the commands passed by the UI or the console if is it one implemented.
        /// </summary>
        protected void HandleLocalCommandsThreadMethod()
        {
            Message          messageToProcess          = null;
            Message          responseMessage           = null;
            ManagedMessage   managedMessageReference   = null;
            ServerSideClient newClientAttempt          = null;
            ServerSideClient serverSideClientReference = null;
            GameUser         referredUser = null;

            if (!this.ableToRun)
            {
                KSPMGlobals.Globals.Log.WriteTo(Error.ErrorType.ServerUnableToRun.ToString());
            }
            try
            {
                KSPMGlobals.Globals.Log.WriteTo("-Starting to handle local commands[ " + this.alive + " ]");
                while (this.alive)
                {
                    this.localCommandsQueue.DequeueCommandMessage(out messageToProcess);
                    if (messageToProcess != null)
                    {
                        //KSPMGlobals.Globals.Log.WriteTo(messageToProcess.Command.ToString());
                        managedMessageReference = (ManagedMessage)messageToProcess;
                        switch (messageToProcess.Command)
                        {
                        case Message.CommandType.NewClient:
                            if (this.clientsHandler.ConnectedClients < this.lowLevelOperationSettings.maxConnectedClients)
                            {
                                if (this.defaultUserManagementSystem.Query(managedMessageReference.OwnerNetworkEntity))
                                {
                                    if (ServerSideClient.CreateFromNetworkEntity(managedMessageReference.OwnerNetworkEntity, out newClientAttempt) == Error.ErrorType.Ok)
                                    {
                                        newClientAttempt.RegisterUserConnectedEvent(this.UserConnected);
                                        if (newClientAttempt.StartClient())
                                        {
                                            this.clientsHandler.AddNewClient(newClientAttempt);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                //Creates the reject message and set the callback to the RejectMessageToClient. Performed in that way because it is needed to send the reject message before to proceed to disconnect the client.
                                Message.ServerFullMessage(managedMessageReference.OwnerNetworkEntity, out responseMessage);
                                PacketHandler.EncodeRawPacket(ref responseMessage.bodyMessage);
                                ((ManagedMessage)responseMessage).OwnerNetworkEntity.SetMessageSentCallback(this.RejectMessageToClient);
                                this.priorityOutgoingMessagesQueue.EnqueueCommandMessage(ref responseMessage);
                            }
                            break;

                        case Message.CommandType.StopServer:
                            this.ShutdownServer();
                            break;

                        case Message.CommandType.Authentication:
                            User.InflateUserFromBytes(messageToProcess.bodyMessage, ((BufferedMessage)messageToProcess).StartsAt, messageToProcess.MessageBytesSize, out referredUser);
                            serverSideClientReference          = (ServerSideClient)managedMessageReference.OwnerNetworkEntity;
                            serverSideClientReference.gameUser = referredUser;
                            if (this.usersAccountManager.Query(managedMessageReference.OwnerNetworkEntity))
                            {
                                /*
                                 * Message.AuthenticationSuccessMessage(messageOwner, out responseMessage);
                                 * this.outgoingMessagesQueue.EnqueueCommandMessage(ref responseMessage);
                                 */
                                serverSideClientReference.RemoveAwaitingState(ServerSideClient.ClientStatus.Authenticated);
                            }
                            else
                            {
                                ///Need to improve this code for a only one if.
                                ///And to check if is it needed to send a disconnect message before release the socket.
                                if ((serverSideClientReference.gameUser.AuthencticationAttempts++) < this.lowLevelOperationSettings.maxAuthenticationAttempts)
                                {
                                    ///There is still a chance to authenticate again.
                                    Message.AuthenticationFailMessage(managedMessageReference.OwnerNetworkEntity, out responseMessage);
                                    PacketHandler.EncodeRawPacket(ref responseMessage.bodyMessage);
                                }
                                else
                                {
                                    ///There is no chance to try it again.
                                    ((ManagedMessage)responseMessage).OwnerNetworkEntity.SetMessageSentCallback(this.RejectMessageToClient);
                                }
                                this.priorityOutgoingMessagesQueue.EnqueueCommandMessage(ref responseMessage);
                            }
                            break;

                        case Message.CommandType.Disconnect:
                            ///Disconnects either a NetworkEntity or a ServerSideClient.
                            this.DisconnectClient(managedMessageReference.OwnerNetworkEntity);
                            break;

                        case Message.CommandType.Unknown:
                        default:
                            KSPMGlobals.Globals.Log.WriteTo("Unknown command: " + messageToProcess.Command.ToString());
                            break;
                        }

                        ///Recyles and releases the message.
                        this.priorityMessagesPool.Recycle(messageToProcess);
                    }

                    Thread.Sleep(1);
                }
            }
            catch (ThreadAbortException)
            {
                this.alive = false;
            }
        }
Пример #4
0
        /// <summary>
        /// Handles the TCP socket and the main Queue of messages, uses the a TCP socket to send messages.
        /// </summary>
        protected void HandleOutgoingMessagesThreadMethod()
        {
            Message              outgoingMessage    = null;
            ManagedMessage       managedReference   = null;
            BroadcastMessage     broadcastReference = null;
            SocketAsyncEventArgs sendingData        = null;
            int entityCounter = 0;
            int blockSize;

            if (!this.ableToRun)
            {
                KSPMGlobals.Globals.Log.WriteTo(Error.ErrorType.ServerUnableToRun.ToString());
            }
            try
            {
                KSPMGlobals.Globals.Log.WriteTo("-Starting to handle outgoing messages[ " + this.alive + " ]");
                while (this.alive)
                {
#if PROFILING
                    this.profilerOutgoingMessages.Set();
#endif
                    this.outgoingMessagesQueue.DequeueCommandMessage(out outgoingMessage);
                    if (outgoingMessage != null)
                    {
                        //KSPMGlobals.Globals.Log.WriteTo(string.Format("[{0}]===Error==={1}.", outgoingMessage.bodyMessage[ 4 ], outgoingMessage.Command));
                        try
                        {
                            ///If it is broadcaste message a different sending procces is performed.
                            if (outgoingMessage.IsBroadcast)
                            {
                                broadcastReference = (BroadcastMessage)outgoingMessage;
                                for (entityCounter = 0; entityCounter < broadcastReference.Targets.Length; entityCounter++)
                                {
                                    if (broadcastReference.Targets[entityCounter] != null && broadcastReference.Targets[entityCounter].IsAlive())
                                    {
                                        blockSize = System.BitConverter.ToInt32(outgoingMessage.bodyMessage, 4);
                                        if (blockSize == outgoingMessage.MessageBytesSize)
                                        {
                                            sendingData = ((ServerSideClient)broadcastReference.Targets[entityCounter]).TCPOutSocketAsyncEventArgsPool.NextSlot;
                                            sendingData.AcceptSocket = broadcastReference.Targets[entityCounter].ownerNetworkCollection.socketReference;
                                            sendingData.UserToken    = broadcastReference.Targets[entityCounter];
                                            sendingData.SetBuffer(outgoingMessage.bodyMessage, 0, (int)outgoingMessage.MessageBytesSize);
                                            if (!broadcastReference.Targets[entityCounter].ownerNetworkCollection.socketReference.SendAsync(sendingData))
                                            {
                                                this.OnSendingOutgoingDataComplete(this, sendingData);
                                            }
                                        }
                                        else
                                        {
                                            KSPMGlobals.Globals.Log.WriteTo("PACKET CRC ERROR, Avoiding it.");
                                        }
                                    }
                                }
                            }
                            else
                            {
                                managedReference = (ManagedMessage)outgoingMessage;
                                blockSize        = System.BitConverter.ToInt32(outgoingMessage.bodyMessage, 4);
                                if (blockSize == outgoingMessage.MessageBytesSize)
                                {
                                    ///Checking if the NetworkEntity is still running and it has not been released.
                                    if (managedReference.OwnerNetworkEntity != null && managedReference.OwnerNetworkEntity.IsAlive())
                                    {
                                        sendingData = ((ServerSideClient)managedReference.OwnerNetworkEntity).TCPOutSocketAsyncEventArgsPool.NextSlot;
                                        sendingData.AcceptSocket = managedReference.OwnerNetworkEntity.ownerNetworkCollection.socketReference;
                                        sendingData.UserToken    = managedReference.OwnerNetworkEntity;
                                        sendingData.SetBuffer(outgoingMessage.bodyMessage, 0, (int)outgoingMessage.MessageBytesSize);
                                        if (!managedReference.OwnerNetworkEntity.ownerNetworkCollection.socketReference.SendAsync(sendingData))
                                        {
                                            this.OnSendingOutgoingDataComplete(this, sendingData);
                                        }
                                    }
                                }
                                else
                                {
                                    KSPMGlobals.Globals.Log.WriteTo("PACKET CRC ERROR, Avoiding it.");
                                }
                            }
                        }
                        catch (System.Exception ex)
                        {
                            KSPMGlobals.Globals.Log.WriteTo(string.Format("[{0}][\"{1}-{2}\"] Something went wrong with the remote client, performing a removing process on it.", (outgoingMessage.IsBroadcast ? ((BroadcastMessage)outgoingMessage).Targets[entityCounter].Id : ((ManagedMessage)outgoingMessage).OwnerNetworkEntity.Id), "HandleOutgoingMessages", ex.Message));
                            this.DisconnectClient((outgoingMessage.IsBroadcast ? ((BroadcastMessage)outgoingMessage).Targets[entityCounter] : ((ManagedMessage)outgoingMessage).OwnerNetworkEntity));
                        }
                        finally
                        {
                            ///Cleaning up.
                            outgoingMessage.Release();
                            outgoingMessage = null;
                        }
                    }
                    else
                    {
                        ///Yielding the process.
                        Thread.Sleep(0);
                    }
#if PROFILING
                    this.profilerOutgoingMessages.Mark();
#endif
                }
            }
            catch (ThreadAbortException)
            {
                this.alive = false;
            }
        }
Пример #5
0
        /// <summary>
        /// Creates a GeneralChat message, it means a chat to be broadcasted to every member on the group.
        /// </summary>
        /// <param name="sender">Network entity who is sending the message.</param>
        /// <param name="targetGroup">ChatGroup to whom is sent the message.</param>
        /// <param name="bodyMessage">String containing the message.</param>
        /// <param name="targetMessage">Out reference to the message to be sent.</param>
        /// <returns></returns>
        public static Error.ErrorType CreateChatMessage(NetworkEntity sender, ChatGroup targetGroup, string bodyMessage, out Message targetMessage)
        {
            int bytesToSend = Message.HeaderOfMessageCommand.Length;

            byte[]     rawBuffer = new byte[Server.ServerSettings.ServerBufferSize];
            GameClient senderClient;
            short      shortBuffer;

            targetMessage = null;
            byte[] messageHeaderContent = null;
            byte[] bytesBuffer          = null;
            if (sender == null)
            {
                return(Error.ErrorType.InvalidNetworkEntity);
            }

            if (targetGroup == null)
            {
                return(Error.ErrorType.ChatInvalidGroup);
            }

            senderClient = (GameClient)sender;

            ///Writing header
            System.Buffer.BlockCopy(Message.HeaderOfMessageCommand, 0, rawBuffer, 0, Message.HeaderOfMessageCommand.Length);
            bytesToSend += 4;

            ///Writing the command.
            rawBuffer[bytesToSend] = (byte)Message.CommandType.Chat;
            bytesToSend           += 1;

            ///Writing the hash's length
            shortBuffer = (short)senderClient.ClientOwner.Hash.Length;
            bytesBuffer = null;
            bytesBuffer = System.BitConverter.GetBytes(shortBuffer);
            System.Buffer.BlockCopy(bytesBuffer, 0, rawBuffer, bytesToSend, bytesBuffer.Length);
            bytesToSend += bytesBuffer.Length;

            ///Writing the user's hash code.
            System.Buffer.BlockCopy(senderClient.ClientOwner.Hash, 0, rawBuffer, bytesToSend, shortBuffer);
            bytesToSend += shortBuffer;

            ///Writing the user name length bytesToSend + 2 to make room to the name's length.
            KSPMGlobals.Globals.StringEncoder.GetBytes(((GameClient)sender).ClientOwner.Username, out bytesBuffer);
            shortBuffer = (short)bytesBuffer.Length;
            System.Buffer.BlockCopy(bytesBuffer, 0, rawBuffer, bytesToSend + 2, bytesBuffer.Length);

            bytesBuffer = System.BitConverter.GetBytes(shortBuffer);
            System.Buffer.BlockCopy(bytesBuffer, 0, rawBuffer, bytesToSend, bytesBuffer.Length);
            bytesToSend += bytesBuffer.Length + shortBuffer;

            ///Writing the groupId.
            bytesBuffer = System.BitConverter.GetBytes(targetGroup.Id);
            System.Buffer.BlockCopy(bytesBuffer, 0, rawBuffer, bytesToSend, bytesBuffer.Length);
            bytesToSend += bytesBuffer.Length;

            ///Writing the body message.
            KSPMGlobals.Globals.StringEncoder.GetBytes(bodyMessage, out bytesBuffer);
            shortBuffer = (short)bytesBuffer.Length;
            ///bytesToSend + 2 because we have to left room for the size of the messagebody.
            System.Buffer.BlockCopy(bytesBuffer, 0, rawBuffer, bytesToSend + 2, shortBuffer);

            ///Writing the body message's size
            bytesBuffer = System.BitConverter.GetBytes(shortBuffer);
            System.Buffer.BlockCopy(bytesBuffer, 0, rawBuffer, bytesToSend, bytesBuffer.Length);
            bytesToSend += shortBuffer + bytesBuffer.Length;

            ///Writing the EndOfMessage command.
            System.Buffer.BlockCopy(Message.EndOfMessageCommand, 0, rawBuffer, bytesToSend, Message.EndOfMessageCommand.Length);
            bytesToSend += Message.EndOfMessageCommand.Length;

            //Writing the message length.
            messageHeaderContent = System.BitConverter.GetBytes(bytesToSend);
            System.Buffer.BlockCopy(messageHeaderContent, 0, rawBuffer, Message.HeaderOfMessageCommand.Length, messageHeaderContent.Length);

            targetMessage = new ManagedMessage((Message.CommandType)rawBuffer[Message.HeaderOfMessageCommand.Length + 4], sender);
            targetMessage.SetBodyMessage(rawBuffer, (uint)bytesToSend);

            return(Error.ErrorType.Ok);
        }