Esempio n. 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 = 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;
                        Program.WriteLine(sender.Username + " has left room: " + sender.Map.Name + " (Exited to lobby)", ConsoleColor.Magenta);
                        //Remove player
                        map.Players.Remove(sender);
                        RebuildIndexes(map);
                        //Send to players
                        NetManager.Broadcast(sender.Map, new PlayerLeaveMessage(sender.ID));
                        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);
                        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
                            Program.WriteLine(string.Format("{0} joined room: {1}", login.Username, Maps[newMap].Name), ConsoleColor.Magenta);
                            //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);
                                }
                            }
                            Program.WriteLine(string.Format("\tMap ID/Player Index: {0}/{1}", sender.ID, sender.Index));
                        }
                        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
                            Program.WriteLine(string.Format("{0} created room: {1}", login.Username, newMap.Name), ConsoleColor.Magenta);
                            Program.WriteLine(string.Format("\tMap ID/Player Index: {0}/{1}", sender.ID, sender.Index));
                        }
                        break;
                    }
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Handles a data message (The bulk of all messages recieved, containing player movements, block places, etc)
 /// </summary>
 private void HandleDataMessage(NetIncomingMessage im)
 {
     MessageTypes messageType = (MessageTypes)im.ReadByte(); //Find the type of data message sent
     switch (messageType)
     {
         case MessageTypes.Lobby: //Lobby list packet
             {
                 if (Game.CurrentGameState == GameState.Lobby)
                 {
                     LobbyScreen screen = MainWindow.ScreenManager.Current as LobbyScreen;
                     LobbyMessage msg = new LobbyMessage(im);
                     screen.Name = msg.ServerName;
                     screen.Description = msg.Description;
                     screen.Intro = msg.Intro;
                     screen.Online = msg.Online;
                     screen.Rooms = msg.Rooms;
                     screen.Lobby.LoadRooms();
                 }
                 break;
             }
         case MessageTypes.PlayerJoin: //Player join message
             {
                 PlayerJoinMessage user = new PlayerJoinMessage(im);
                 //Add player to map
                 Map.Players.Add(new Player(Map, Map.Spawn, user.Username, 1, user.ID) { Tint = user.Color });
                 //Add user to userlist
                 (MainWindow.ScreenManager.Current as GameScreen).PlayerList.Items.Add(user.Username);
                 if (user.ID != Game.MyID && recievedInit) //Broadcast join message to chat
                 {
                     (MainWindow.ScreenManager.Current as GameScreen).SystemChat(user.Username + " [color:LightGray]has[/color] [color:LightGreen]joined.[/color]");
                 }
                 if (user.Me)
                 {
                     //Let game know of it's own player
                     Game.MyID = user.ID;
                     Game.MyIndex = (byte)Map.Players.IndexOf(Map.Players.First(x => x.ID == Game.MyID));
                     Game.Me.Tint = Game.MyColor;
                 }
                 break;
             }
         case MessageTypes.PlayerLeave: //Player leave message
             {
                 PlayerLeaveMessage user = new PlayerLeaveMessage(im);
                 //Remove player
                 if (user.ID != Game.MyID)
                 {
                     Player player = Map.PlayerFromID(user.ID);
                     Map.Players.Remove(Map.PlayerFromID(user.ID));
                     (MainWindow.ScreenManager.Current as GameScreen).PlayerList.Items.Remove(player.Username);
                     (MainWindow.ScreenManager.Current as GameScreen).SystemChat(player.Username + " [color:LightGray]has[/color] [color:IndianRed]left.[/color]");
                     //Rebuild indexes
                     for (int i = 0; i < Map.Players.Count; i++)
                     {
                         Map.Players[i].Index = i;
                         if (Map.Players[i].ID == Game.MyID)
                             Game.MyIndex = (byte)i;
                     }
                 }
                 break;
             }
         case MessageTypes.PlayerStatus: //Player move message
             {
                 if (Game.CurrentGameState == GameState.Game)
                 {
                     PlayerStateMessage user = new PlayerStateMessage(im);
                     Player player = Map.PlayerFromID(user.ID);
                     player.SimulationState.Position = user.Position.ToVector2();
                     player.SimulationState.Velocity = user.Velocity.ToVector2();
                     player.SimulationState.Movement = user.Movement.ToVector2();
                     if (!recievedInit) //If we have not recieved init (meaning we are not in game yet), set the initial positions directly so interpolation doesn't mess with them
                         player.DisplayState.Position = player.SimulationState.Position;
                     player.VirtualJump = user.IsJumping;
                 }
                 break;
             }
         case MessageTypes.Block: //Block place message
             {
                 if (Game.CurrentGameState == GameState.Game)
                 {
                     BlockMessage msg = new BlockMessage(im);
                     BlockType block = BlockType.FromID(msg.BlockID);
                     if (Map.CanPlaceBlock(msg.X, msg.Y, msg.Z, block))
                         Map.Tiles[msg.X, msg.Y, msg.Z].Block = block;
                 }
                 break;
             }
         case MessageTypes.PlayerSmiley: //Smiley change message
             {
                 if (Game.CurrentGameState == GameState.Game)
                 {
                     PlayerSmileyMessage msg = new PlayerSmileyMessage(im);
                     Player p = Map.PlayerFromID(msg.ID);
                     p.Smiley = msg.Smiley;
                 }
                 break;
             }
         case MessageTypes.PlayerMode: //Player mode change message
             {
                 if (Game.CurrentGameState == GameState.Game)
                 {
                     PlayerModeMessage mode = new PlayerModeMessage(im);
                     Map.PlayerFromID(mode.ID).Mode = (PlayerMode)mode.Mode;
                 }
                 break;
             }
         case MessageTypes.Chat: //Chat message
             {
                 if (Game.CurrentGameState == GameState.Game)
                 {
                     ChatMessage chat = new ChatMessage(im);
                     (MainWindow.ScreenManager.Current as GameScreen).AddChat(Map.PlayerFromID(chat.ID).Username, chat.Message);
                 }
                 break;
             }
         case MessageTypes.Init: //Initialization message with world data
             {
                 Game.Map = new Bricklayer.Client.World.Map(game, 1, 1);
                 InitMessage msg = new InitMessage(im, Map);
                 Game.CurrentGameState = GameState.Game;
                 (MainWindow.ScreenManager.Current as GameScreen).Show();
                 (MainWindow.ScreenManager.Current as GameScreen).SystemChat("Connected to [color:LightGray]" + Game.Host + ":" + Game.Port + "[/color]");
                 recievedInit = true;
                 break;
             }
     }
 }