Пример #1
0
        /// <summary>
        /// The process network messages such as player's joining, moving, etc
        /// </summary>
        public void ProcessNetworkMessages()
        {
            //Used to store messages
            NetIncomingMessage inc;

            while (true) //Continously check for new messages and process them
            {
                //Block thread until next message
                NetworkManager.NetServer.MessageReceivedEvent.WaitOne();

                if ((inc = NetManager.ReadMessage()) != null)
                {
                    //Try and find who sent the message
                    Player sender = inc.SenderConnection == null ?
                        null : Server.PlayerFromRUI(inc.SenderConnection.RemoteUniqueIdentifier, true);

                    switch (inc.MessageType)
                    {
                        //ConnectionApproval messages are sent when a client would like to connect to the server
                        case NetIncomingMessageType.ConnectionApproval:
                            {
                                MessageTypes type = (MessageTypes)Enum.Parse(typeof(MessageTypes), inc.ReadByte().ToString()); //Find message type
                                switch (type)
                                {
                                    //If the player would like to login
                                    case MessageTypes.Login:
                                        {
                                            Log.WriteLine(LogType.Server, "Login request (RUI: {0} IP: {1})",
                                                inc.SenderConnection.RemoteUniqueIdentifier, inc.SenderEndPoint.Address); //Log message

                                            //If the player isn't already connected, allow them to join
                                            if (!Server.Logins.ContainsKey(inc.SenderConnection.RemoteUniqueIdentifier))
                                            {
                                                LoginMessage login = new LoginMessage(inc);
                                                if (GlobalSettings.NameRegex.IsMatch(login.Username)) //Double check username is valid
                                                {
                                                    Server.Logins.Add(inc.SenderConnection.RemoteUniqueIdentifier, login);
                                                    inc.SenderConnection.Approve();
                                                }
                                                else
                                                    inc.SenderConnection.Deny("Invalid Username:Kicked");
                                            }
                                            else
                                                inc.SenderConnection.Deny();
                                            break;
                                        }
                                }
                                break;
                            }
                        //Data messages are all messages manually sent from client
                        //These are the bulk of the messages, used for player movement, block placing, etc
                        case NetIncomingMessageType.Data:
                            {
                                ProcessDataMessage(inc);
                                break;
                            }
                        //StatusChanged messages occur when a client connects, disconnects, is approved, etc
                        //NOTE: Disconnecting and Disconnected are not instant unless client is shutdown with Disconnect()
                        case NetIncomingMessageType.StatusChanged:
                            {
                                //Find player name
                                string name = Server.Logins.ContainsKey(inc.SenderConnection.RemoteUniqueIdentifier) ?
                                    Server.Logins[inc.SenderConnection.RemoteUniqueIdentifier].Username + " (" + inc.SenderConnection.RemoteUniqueIdentifier + ")" :
                                    "Unknown (" + inc.SenderConnection.RemoteUniqueIdentifier + ")";

                                //The lines below can get spammy, used to show when statuses change
                                //Log.WriteLine(LogType.Status, "Status: {0} changed: {1}", name, inc.SenderConnection.Status.ToString());

                                //When a players connection is finalized
                                if (inc.SenderConnection.Status == NetConnectionStatus.Connected)
                                {
                                    //Log message
                                    LoginMessage login = Server.Logins[inc.SenderConnection.RemoteUniqueIdentifier];
                                    Log.WriteLine(LogType.Server, "User {0} authenticated (RUI: {1}, IP: {2})", login.Username, inc.SenderConnection.RemoteUniqueIdentifier, inc.SenderEndPoint.Address);
                                    break;
                                }
                                //When a client disconnects
                                if (inc.SenderConnection.Status == NetConnectionStatus.Disconnected || inc.SenderConnection.Status == NetConnectionStatus.Disconnecting)
                                {
                                    if (sender != null)
                                    {
                                        Log.WriteLine(LogType.Server, ConsoleColor.Red, "{0} disconnected. (Room: {1})", sender.Username, sender.Map.Name);
                                        if (sender.Map.Players.Contains(sender))
                                        {
                                            //Remove player
                                            sender.Map.Players.Remove(sender);
                                            RebuildIndexes(sender.Map);
                                            //Send to players
                                            NetManager.Broadcast(sender.Map, new PlayerLeaveMessage(sender.ID));
                                            sender = null;
                                        }
                                    }
                                    else
                                    {
                                        Log.WriteLine(LogType.Server, ConsoleColor.Red, "{0} disconnected.", Server.Logins[inc.SenderConnection.RemoteUniqueIdentifier].Username);
                                    }
                                    Server.Logins.Remove(inc.SenderConnection.RemoteUniqueIdentifier);
                                }
                                break;
                            }
                        default:
                            break;
                    }
                }
            }
        }