Bricklayer.Server.IO.SaveMap C# (CSharp) Метод

SaveMap() публичный статический Метод

public static SaveMap ( Bricklayer map ) : void
map Bricklayer
Результат void
        public static void SaveMap(Bricklayer.Server.World.Map map)
        {
            using (BinaryWriter binaryWriter = new BinaryWriter( //Create a new binary writer to write to the file
                new BufferedStream(
                File.Open(Path.Combine(mapFolder, map.Name + mapSuffix), FileMode.Create))))
            {
                //Write general data
                binaryWriter.Write(map.Name);
                binaryWriter.Write(map.Description);
                binaryWriter.Write((short)map.Width);
                binaryWriter.Write((short)map.Height);
                binaryWriter.Write(map.Rating);

                for (int y = 0; y < map.Height; y++)
                {
                    for (int x = 0; x < map.Width; x++)
                    {
                        BlockType fg = map.Tiles[x, y, 1].Block;
                        BlockType bg = map.Tiles[x, y, 0].Block;
                        SaveFlags sf = SaveFlags.None;

                        //Calculate Run-Length Encoding
                        int i = 0;
                        while (i + 1 + x < map.Width && fg.ID == map.Tiles[x + i + 1, y, 1].Block.ID && bg.ID == map.Tiles[x + i + 1, y, 0].Block.ID)
                            i++; //If next block is the same, record the amount of same blocks in i

                        //Calculate flags
                        if (i > 0)
                            sf |= SaveFlags.RLE;
                        if (fg.ID != BlockType.Empty.ID)
                            sf |= SaveFlags.Foreground;
                        if (bg.ID != BlockType.Empty.ID)
                            sf |= SaveFlags.Background;
                        binaryWriter.Write((byte)sf);

                        //Save data
                        if (i > 0)
                            binaryWriter.Write((short)i);
                        if (fg.ID != BlockType.Empty.ID)
                            binaryWriter.Write(fg.ID);
                        if (bg.ID != BlockType.Empty.ID)
                            binaryWriter.Write(bg.ID);

                        x += i;
                    }
                }
            }
        }

Usage Example

Пример #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;
            }
            }
        }