Exemple #1
0
        public static Level Load(Stream lvlStream, string fileName)
        {
            byte[] temp = new byte[8];
            Level lvl = new Level(fileName, 0, 0, 0, "empty");
            byte[] data;
            int length;
            try {
                lvlStream.Seek( -4, SeekOrigin.End );
                lvlStream.Read( temp, 0, sizeof( int ) );
                lvlStream.Seek( 0, SeekOrigin.Begin );
                length = BitConverter.ToInt32( temp, 0 );
                data = new byte[length];
                using( GZipStream reader = new GZipStream( lvlStream, CompressionMode.Decompress, true ) ) {
                    reader.Read( data, 0, length );
                }

                for( int i = 0; i < length - 1; i++ ) {
                    if( data[i] == 0xAC && data[i + 1] == 0xED ) {

                        // bypassing the header crap
                        int pointer = i + 6;
                        Array.Copy( data, pointer, temp, 0, sizeof( short ) );
                        pointer += IPAddress.HostToNetworkOrder( BitConverter.ToInt16( temp, 0 ) );
                        pointer += 13;

                        int headerEnd = 0;
                        // find the end of serialization listing
                        for( headerEnd = pointer; headerEnd < data.Length - 1; headerEnd++ ) {
                            if( data[headerEnd] == 0x78 && data[headerEnd + 1] == 0x70 ) {
                                headerEnd += 2;
                                break;
                            }
                        }

                        // start parsing serialization listing
                        int offset = 0;
                        while( pointer < headerEnd ) {
                            if( data[pointer] == 'Z' ) offset++;
                            else if( data[pointer] == 'I' || data[pointer] == 'F' ) offset += 4;
                            else if( data[pointer] == 'J' ) offset += 8;

                            pointer += 1;
                            Array.Copy( data, pointer, temp, 0, sizeof( short ) );
                            short skip = IPAddress.HostToNetworkOrder( BitConverter.ToInt16( temp, 0 ) );
                            pointer += 2;

                            // look for relevant variables
                            Array.Copy( data, headerEnd + offset - 4, temp, 0, sizeof( int ) );
                            if( MemCmp( data, pointer, "width" ) ) {
                                lvl.width = (ushort)IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) );
                            } else if( MemCmp( data, pointer, "depth" ) ) {
                                lvl.depth = (ushort)IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) );
                            } else if( MemCmp( data, pointer, "height" ) ) {
                                lvl.height = (ushort)IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) );
                            }

                            pointer += skip;
                        }

                        lvl.spawnx = (ushort)(lvl.width / 1.3);
                        lvl.spawny = (ushort)(lvl.depth / 1.3);
                        lvl.spawnz = (ushort)(lvl.height / 1.3);

                        // find the start of the block array
                        bool foundBlockArray = false;
                        offset = Array.IndexOf<byte>( data, 0x00, headerEnd );
                        while( offset != -1 && offset < data.Length - 2 ) {
                            if( data[offset] == 0x00 && data[offset + 1] == 0x78 && data[offset + 2] == 0x70 ) {
                                foundBlockArray = true;
                                pointer = offset + 7;
                            }
                            offset = Array.IndexOf<byte>( data, 0x00, offset + 1 );
                        }

                        // copy the block array... or fail
                        if( foundBlockArray ) {
                            lvl.CopyBlocks( data, pointer );
                            lvl.Save(true);
                        } else {
                            throw new Exception( "Could not locate block array." );
                        }
                        break;
                    }
                }

            } catch( Exception ex ) {
                Server.s.Log("Conversion failed");
                Server.ErrorLog(ex);
                return null;
            }

            return lvl;
        }
Exemple #2
0
        public override void Use(Player p, string message)
        {
            if (message == "") { Help(p); return; }

            string[] parameters = message.Split(' '); // Grab the parameters from the player's message
            if (parameters.Length >= 5 && parameters.Length <= 6) // make sure there are 5 params, or 6, if type is sphere.
            {
                switch (parameters[4])
                {
                    case "flat":
                    case "pixel":
                    case "island":
                    case "mountains":
                    case "ocean":
                    case "forest":
                    case "desert":
                    case "nether":
                    case "hell":
                    case "arctic":
                    case "dome":
                    case "sphere":
                        break;

                    default:
                        Player.SendMessage(p, "Valid types: island, mountains, forest, ocean, flat, pixel, desert, nether, arctic, sphere [block]"); return;
                }

                string name = parameters[0].ToLower();
                ushort x = 1, y = 1, z = 1;
                try
                {
                    x = Convert.ToUInt16(parameters[1]);
                    y = Convert.ToUInt16(parameters[2]);
                    z = Convert.ToUInt16(parameters[3]);
                }
                catch { Player.SendMessage(p, "Invalid dimensions."); return; }
                if (!isGood(x)) { Player.SendMessage(p, x + " is not a good dimension! Use a power of 2 next time."); }
                if (!isGood(y)) { Player.SendMessage(p, y + " is not a good dimension! Use a power of 2 next time."); }
                if (!isGood(z)) { Player.SendMessage(p, z + " is not a good dimension! Use a power of 2 next time."); }

                if (!Player.ValidName(name)) { Player.SendMessage(p, "Invalid name!"); return; }

                try
                {
                    if (p != null)
                    if (p.group.Permission < LevelPermission.Admin)
                    {
                        if (x * y * z > 30000000) { Player.SendMessage(p, "Cannot create a map with over 30 million blocks"); return; }
                    }
                    else
                    {
                        if (x * y * z > 225000000) { Player.SendMessage(p, "You cannot make a map with over 225 million blocks"); return; }
                    }
                }
                catch
                {
                    Player.SendMessage(p, "An error occured");
                }

                // create a new level...
                try
                {
                    if (parameters.Length == 5) { Level lvl = new Level(name, x, y, z, parameters[4]); lvl.Save(true); }
                    else
                    {
                        byte blockChosen = 20;
                        try { blockChosen = Block.Byte(parameters[5]); }
                        catch { Player.SendMessage(p, "Invalid Block Chosen"); return; }
                        Level lvl = new Level(name, x, y, z, parameters[4], blockChosen);
                        lvl.Save(true);
                    }
                }
                finally
                {
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
                Player.GlobalMessage("Level " + name + " created"); // The player needs some form of confirmation.
            }
            else
                Help(p);
        }