Пример #1
0
        /// <summary>
        /// Handles all actions for recieving data messages (Such as movement, block placing, etc)
        /// </summary>
        /// <param name="inc">The incoming message</param>
        private void ProcessDataMessage(NetIncomingMessage inc)
        {
            Player sender = Server.PlayerFromRUI(inc.SenderConnection.RemoteUniqueIdentifier, true);
            Map map = null;
            if (sender != null)
                map = (Map)sender.Map;
            MessageTypes type = (MessageTypes)Enum.Parse(typeof(MessageTypes), inc.ReadByte().ToString());
            switch (type)
            {
                //When a player request to recieve a message
                case MessageTypes.Request:
                    {
                        MessageTypes request = new RequestMessage(inc).RequestType;

                        //Request to recieve lobby data
                        if (request == MessageTypes.Lobby)
                        {
                            List<LobbySaveData> rooms = new List<LobbySaveData>();
                            foreach (Map m in Maps)
                            {
                                rooms.Add(LobbySaveData.FromMap(m));
                            }
                            LobbyMessage msg = new LobbyMessage(Server.Config.Name, Server.Config.Decription, Server.Config.Intro, NetworkManager.NetServer.ConnectionsCount, rooms);
                            NetManager.Send(msg, inc.SenderConnection);
                        }
                        break;
                    }
                //When a player exits to the lobby
                case MessageTypes.PlayerLeave:
                    {
                        PlayerLeaveMessage user = new PlayerLeaveMessage(inc);
                        user.ID = sender.ID;
                        Log.WriteLine(LogType.Room, "{0} has left: {1}", sender.Username, sender.Map.Name);
                        //Remove player
                        map.Players.Remove(sender);
                        RebuildIndexes(map);
                        //Send to players
                        NetManager.Broadcast(sender.Map, new PlayerLeaveMessage(sender.ID));
                        IO.SaveMap((Bricklayer.Server.World.Map)sender.Map);
                        sender = null;
                        break;
                    }
                //When a player moves
                case MessageTypes.PlayerStatus:
                    {
                        PlayerStateMessage state = new PlayerStateMessage(inc);
                        state.ID = sender.ID;
                        //Clamp position in bounds
                        state.Position = new Point((int)MathHelper.Clamp(state.Position.X, Tile.Width, (map.Width * Tile.Width) - (Tile.Width * 2)), (int)MathHelper.Clamp(state.Position.Y, Tile.Height, (map.Height * Tile.Height) - (Tile.Height * 2)));
                        sender.SimulationState.Position = state.Position.ToVector2();
                        sender.SimulationState.Velocity = state.Velocity.ToVector2();
                        sender.SimulationState.Movement = state.Movement.ToVector2();
                        sender.IsJumping = state.IsJumping;

                        NetManager.BroadcastExcept(state, sender);
                        break;
                    }
                //When a player places a block
                case MessageTypes.Block:
                    {
                        BlockMessage state = new BlockMessage(inc);
                        BlockType block = BlockType.FromID(state.BlockID);
                        //Verify Block (Make sure it is in bounds and it has changed, no use sending otherwise)
                        //TODO: Punish players spamming invalid data (Because official client should never send it)
                        if (map.InBounds(state.X, state.Y, state.Z) && map.Tiles[state.X, state.Y, state.Z].Block.ID != block.ID)
                        {
                            map.Tiles[state.X, state.Y, state.Z].Block = block;
                            NetManager.Broadcast(sender.Map, state);
                        }
                        break;
                    }
                //When a player sends a chat message
                case MessageTypes.Chat:
                    {
                        ChatMessage chat = new ChatMessage(inc);
                        chat.ID = sender.ID;

                        //Verify length
                        if (chat.Message.Length > ChatMessage.MaxLength)
                            chat.Message = chat.Message.Truncate(ChatMessage.MaxLength);
                        NetManager.BroadcastExcept(chat, sender);

                        //Log message
                        Log.WriteLine(LogType.Chat, ConsoleColor.Gray, "<{0}> {1}", sender.Username, chat.Message);
                        break;
                    }
                //When a player changes smiley
                case MessageTypes.PlayerSmiley:
                    {
                        PlayerSmileyMessage smiley = new PlayerSmileyMessage(inc);
                        smiley.ID = sender.ID;
                        if (sender.Smiley != smiley.Smiley)
                        {
                            sender.Smiley = smiley.Smiley;
                            NetManager.BroadcastExcept(smiley, sender);
                        }
                        break;
                    }
                //When a player changes mode (Ex: godmode to normal
                case MessageTypes.PlayerMode:
                    {
                        PlayerModeMessage mode = new PlayerModeMessage(inc);
                        mode.ID = sender.ID;
                        if (sender.Mode != mode.Mode)
                        {
                            sender.Mode = mode.Mode;
                            NetManager.BroadcastExcept(mode, sender);
                        }
                        break;
                    }

                //When a player requests to join a room
                case MessageTypes.JoinRoom:
                    {
                        if (sender == null) //If the sender isn't null, then they are already in a room
                        {
                            JoinRoomMessage msg = new JoinRoomMessage(inc);
                            int newMap = Maps.IndexOf(Server.MapFromID(msg.ID));
                            LoginMessage login = Server.Logins[inc.SenderConnection.RemoteUniqueIdentifier]; //Fetch stored login from dictionary
                            Maps[newMap].Players.Add(new Player(Maps[newMap], Maps[newMap].Spawn, login.Username, inc.SenderConnection.RemoteUniqueIdentifier, Server.FindEmptyID(Maps[newMap])) { Tint = login.Color });
                            sender = Server.PlayerFromRUI(inc.SenderConnection.RemoteUniqueIdentifier, true);
                            NetManager.Send(new InitMessage(sender.Map), sender);
                            //Send message to player notifing he is connected and ready
                            NetManager.Send(new PlayerJoinMessage(sender.Username, sender.ID, true, sender.Tint), sender);

                            //Log message
                            Log.WriteLine(LogType.Room, "{0} joined: {1}", login.Username, Maps[newMap].Name);
                            //Send message to everyone notifying of new user
                            NetManager.BroadcastExcept(new PlayerJoinMessage(sender.Username, sender.ID, false, sender.Tint), sender);
                            //Let new player know of all existing players and their states (Mode, Position, Smiley)
                            foreach (Player player in sender.Map.Players)
                            {
                                if (player.ID != sender.ID)
                                {
                                    NetManager.Send(new PlayerJoinMessage(player.Username, player.ID, false, player.Tint), sender);
                                    NetManager.Send(new PlayerStateMessage(player), sender);
                                    if (player.Mode != PlayerMode.Normal)
                                        NetManager.Send(new PlayerModeMessage(player), sender);
                                    if (player.Smiley != SmileyType.Default)
                                        NetManager.Send(new PlayerSmileyMessage(player, player.Smiley), sender);
                                }
                            }
                        }
                        break;
                    }
                //When a player requests to make a room
                case MessageTypes.CreateRoom: //If the sender isn't null, then they are already in a room
                    {
                        if (sender == null)
                        {
                            CreateRoomMessage msg = new CreateRoomMessage(inc);
                            Map newMap = Server.CreateMap(msg.Name, msg.Description);
                            LoginMessage login = Server.Logins[inc.SenderConnection.RemoteUniqueIdentifier]; //Fetch stored login from dictionary
                            newMap.Players.Add(new Player(newMap, newMap.Spawn, login.Username, inc.SenderConnection.RemoteUniqueIdentifier, Server.FindEmptyID(newMap)) { Tint = login.Color });
                            sender = Server.PlayerFromRUI(inc.SenderConnection.RemoteUniqueIdentifier, true);
                            //Send message to player notifing he is connected and ready
                            NetManager.Send(new InitMessage(sender.Map), sender);
                            NetManager.Send(new PlayerJoinMessage(sender.Username, sender.ID, true, sender.Tint), sender);
                            //Log message
                            Log.WriteLine(LogType.Room, "{0} created room: {1}", login.Username, newMap.Name);
                        }
                        break;
                    }
            }
        }