Example #1
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) // make sure there are 5 params
            {
                switch (parameters[4])
                {
                    case "flat":
                    case "pixel":
                    case "island":
                    case "mountains":
                    case "ocean":
                    case "forest":
                    case "desert":
                        break;

                    default:
                        Player.SendMessage(p, "Valid types: island, mountains, forest, ocean, flat, pixel, desert"); 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 30million blocks"); return; }
                    }
                    else
                    {
                        if (x * y * z > 225000000) { Player.SendMessage(p, "You cannot make a map with over 225million blocks"); return; }
                    }
                }
                catch
                {
                    Player.SendMessage(p, "An error occured");
                }

                // create a new level...
                try
                {
                    Level lvl = new Level(name, x, y, z, parameters[4]);
                    lvl.Save(true); //... and save it.
                }
                finally
                {
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
                Player.GlobalMessage("Level " + name + " created"); // The player needs some form of confirmation.
            }
            else
                Help(p);
        }
Example #2
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;
        }