Ejemplo n.º 1
0
        public override byte[] GetBytes(Stream instream)
        {
            if (_cache != null)
            {
                instream.Write(_cache);
                return(_cache);
            }

            using (var stream = new MemoryStream())
            {
                stream.WriteByte(8);                 // version

                int numberOfStores = 1;
                stream.WriteByte((byte)numberOfStores);                  // storage size

                List <uint> palette = new List <uint>(10);
                byte[]      indexes = new byte[_blocks.Length];
                for (int i = 0; i < numberOfStores; i++)
                {
                    palette.Clear();

                    stream.WriteByte((8 << 1) | 1);                     // version

                    int  index    = 0;
                    uint prevHash = uint.MaxValue;
                    for (int b = 0; b < _blocks.Length; b++)
                    {
                        byte bid  = (byte)_blocks[b];
                        byte data = _metadata[b];
                        uint hash = BlockFactory.GetRuntimeId(bid, data);
                        if (hash != prevHash)
                        {
                            index = palette.IndexOf(hash);
                            if (index == -1)
                            {
                                palette.Add(hash);
                            }
                            index = palette.IndexOf(hash);
                        }

                        indexes[b] = (byte)index;
                        prevHash   = hash;
                    }

                    stream.Write(indexes, 0, indexes.Length);

                    VarInt.WriteSInt32(stream, palette.Count);                     // count
                    foreach (var val in palette)
                    {
                        VarInt.WriteSInt32(stream, (int)val);
                    }
                }

                var bytes = stream.ToArray();
                instream.Write(bytes);
                _cache = bytes;
            }

            return(_cache);
        }
Ejemplo n.º 2
0
        public static Item GetItem(short id, short metadata = 0, int count = 1)
        {
            Item item = null;

            if (CustomItemFactory != null)
            {
                item = CustomItemFactory.GetItem(id, metadata, count);
            }

            if (item != null)
            {
                return(item);
            }

            if (id == 0)
            {
                item = new ItemAir();
            }
            else if (id == 256)
            {
                item = new ItemIronShovel();
            }
            else if (id == 257)
            {
                item = new ItemIronPickaxe();
            }
            else if (id == 258)
            {
                item = new ItemIronAxe();
            }
            else if (id == 259)
            {
                item = new ItemFlintAndSteel();
            }
            else if (id == 260)
            {
                item = new ItemApple();
            }
            else if (id == 261)
            {
                item = new ItemBow();
            }
            else if (id == 262)
            {
                item = new ItemArrow();
            }
            else if (id == 263)
            {
                item = new ItemCoal();
            }
            else if (id == 264)
            {
                item = new ItemDiamond();
            }
            else if (id == 265)
            {
                item = new ItemIronIngot();
            }
            else if (id == 266)
            {
                item = new ItemGoldIngot();
            }
            else if (id == 267)
            {
                item = new ItemIronSword();
            }
            else if (id == 268)
            {
                item = new ItemWoodenSword();
            }
            else if (id == 269)
            {
                item = new ItemWoodenShovel();
            }
            else if (id == 270)
            {
                item = new ItemWoodenPickaxe();
            }
            else if (id == 271)
            {
                item = new ItemWoodenAxe();
            }
            else if (id == 272)
            {
                item = new ItemStoneSword();
            }
            else if (id == 273)
            {
                item = new ItemStoneShovel();
            }
            else if (id == 274)
            {
                item = new ItemStonePickaxe();
            }
            else if (id == 275)
            {
                item = new ItemStoneAxe();
            }
            else if (id == 276)
            {
                item = new ItemDiamondSword();
            }
            else if (id == 277)
            {
                item = new ItemDiamondShovel();
            }
            else if (id == 278)
            {
                item = new ItemDiamondPickaxe();
            }
            else if (id == 279)
            {
                item = new ItemDiamondAxe();
            }
            else if (id == 280)
            {
                item = new ItemStick();
            }
            else if (id == 283)
            {
                item = new ItemGoldenSword();
            }
            else if (id == 284)
            {
                item = new ItemGoldenShovel();
            }
            else if (id == 285)
            {
                item = new ItemGoldenPickaxe();
            }
            else if (id == 286)
            {
                item = new ItemGoldenAxe();
            }
            else if (id == 290)
            {
                item = new ItemWoodenHoe();
            }
            else if (id == 291)
            {
                item = new ItemStoneHoe();
            }
            else if (id == 292)
            {
                item = new ItemIronHoe();
            }
            else if (id == 293)
            {
                item = new ItemDiamondHoe();
            }
            else if (id == 294)
            {
                item = new ItemGoldenHoe();
            }
            else if (id == 295)
            {
                item = new ItemWheatSeeds();
            }
            else if (id == 296)
            {
                item = new ItemWheat();
            }
            else if (id == 297)
            {
                item = new ItemBread();
            }
            else if (id == 298)
            {
                item = new ItemLeatherHelmet();
            }
            else if (id == 299)
            {
                item = new ItemLeatherChestplate();
            }
            else if (id == 300)
            {
                item = new ItemLeatherLeggings();
            }
            else if (id == 301)
            {
                item = new ItemLeatherBoots();
            }
            else if (id == 302)
            {
                item = new ItemChainmailHelmet();
            }
            else if (id == 303)
            {
                item = new ItemChainmailChestplate();
            }
            else if (id == 304)
            {
                item = new ItemChainmailLeggings();
            }
            else if (id == 305)
            {
                item = new ItemChainmailBoots();
            }
            else if (id == 309)
            {
                item = new ItemIronBoots();
            }
            else if (id == 308)
            {
                item = new ItemIronLeggings();
            }
            else if (id == 307)
            {
                item = new ItemIronChestplate();
            }
            else if (id == 306)
            {
                item = new ItemIronHelmet();
            }
            else if (id == 310)
            {
                item = new ItemDiamondHelmet();
            }
            else if (id == 311)
            {
                item = new ItemDiamondChestplate();
            }
            else if (id == 312)
            {
                item = new ItemDiamondLeggings();
            }
            else if (id == 313)
            {
                item = new ItemDiamondBoots();
            }
            else if (id == 314)
            {
                item = new ItemGoldHelmet();
            }
            else if (id == 315)
            {
                item = new ItemGoldChestplate();
            }
            else if (id == 316)
            {
                item = new ItemGoldLeggings();
            }
            else if (id == 317)
            {
                item = new ItemGoldBoots();
            }
            else if (id == 319)
            {
                item = new ItemRawPorkchop();
            }
            else if (id == 320)
            {
                item = new ItemCookedPorkshop();
            }
            else if (id == 321)
            {
                item = new ItemPainting();
            }
            else if (id == 322)
            {
                item = new ItemGoldenApple();
            }
            else if (id == 323)
            {
                item = new ItemSign();
            }
            else if (id == 324)
            {
                item = new ItemWoodenDoor();
            }
            else if (id == 325)
            {
                item = new ItemBucket(metadata);
            }
            else if (id == 329)
            {
                item = new ItemSaddle();
            }
            else if (id == 331)
            {
                item = new ItemRedstone();
            }
            else if (id == 332)
            {
                item = new ItemSnowball();
            }
            else if (id == 333)
            {
                item = new ItemBoat(metadata);
            }
            else if (id == 340)
            {
                item = new ItemBook();
            }
            else if (id == 344)
            {
                item = new ItemEgg();
            }
            else if (id == 345)
            {
                item = new ItemCompass();
            }
            else if (id == 351)
            {
                item = new ItemDye();
            }
            else if (id == 352)
            {
                item = new ItemBone();
            }
            else if (id == 352)
            {
                item = new ItemSugar();
            }
            else if (id == 355)
            {
                item = new ItemBed();
            }
            else if (id == 357)
            {
                item = new ItemCookie();
            }
            else if (id == 358)
            {
                item = new ItemMap();
            }
            else if (id == 359)
            {
                item = new ItemShears();
            }
            else if (id == 360)
            {
                item = new ItemMelonSlice();
            }
            else if (id == 363)
            {
                item = new ItemBeef();
            }
            else if (id == 364)
            {
                item = new ItemCookedBeef();
            }
            else if (id == 365)
            {
                item = new ItemRawChicken();
            }
            else if (id == 366)
            {
                item = new ItemCookedChicken();
            }
            else if (id == 369)
            {
                item = new ItemBlazeRod();
            }
            else if (id == 371)
            {
                item = new ItemGoldNugget();
            }
            else if (id == 373)
            {
                item = new ItemPotion(metadata);
            }
            else if (id == 377)
            {
                item = new ItemBlazePowder();
            }
            else if (id == 380)
            {
                item = new ItemCauldron();
            }
            else if (id == 383)
            {
                item = new ItemMonsterEgg(metadata);
            }
            else if (id == 389)
            {
                item = new ItemFrame();
            }
            else if (id == 391)
            {
                item = new ItemCarrot();
            }
            else if (id == 392)
            {
                item = new ItemPotato();
            }
            else if (id == 393)
            {
                item = new ItemBakedPotato();
            }
            else if (id == 395)
            {
                item = new ItemEmptyMap();
            }
            else if (id == 395)
            {
                item = new ItemGoldenCarrot();
            }
            else if (id == 397)
            {
                item = new ItemMobHead(metadata);
            }
            else if (id == 400)
            {
                item = new ItemPumpkinPie();
            }
            else if (id == 401)
            {
                item = new ItemFireworks();
            }
            else if (id == 403)
            {
                item = new ItemEnchantedBook();
            }
            else if (id == 416)
            {
                item = new ItemHorseArmorLeather();
            }
            else if (id == 417)
            {
                item = new ItemHorseArmorIron();
            }
            else if (id == 418)
            {
                item = new ItemHorseArmorGold();
            }
            else if (id == 419)
            {
                item = new ItemHorseArmorDiamond();
            }
            else if (id == 423)
            {
                item = new ItemMuttonRaw();
            }
            else if (id == 424)
            {
                item = new ItemMuttonCooked();
            }
            else if (id == 427)
            {
                item = new ItemSpruceDoor();
            }
            else if (id == 428)
            {
                item = new ItemBirchDoor();
            }
            else if (id == 429)
            {
                item = new ItemJungleDoor();
            }
            else if (id == 430)
            {
                item = new ItemAcaciaDoor();
            }
            else if (id == 431)
            {
                item = new ItemDarkOakDoor();
            }
            else if (id == 444)
            {
                item = new ItemElytra();
            }
            else if (id == 446)
            {
                item = new ItemBanner();
            }
            else if (id == 452)
            {
                item = new ItemIronNugget();
            }
            else if (id == 454 && metadata == 0)
            {
                item = new ItemSlate();
            }
            else if (id == 454 && metadata == 1)
            {
                item = new ItemPoster();
            }
            else if (id == 454 && metadata == 2)
            {
                item = new ItemBoard();
            }
            else if (id == 458)
            {
                item = new ItemBeetrootSeeds();
            }
            else if (id == 498)
            {
                item = new ItemCamera(metadata);
            }
            else if (id <= 255)
            {
                int blockId = id;
                if (blockId < 0)
                {
                    blockId = (short)(Math.Abs(id) + 255);                               // hehe
                }
                Block block     = BlockFactory.GetBlockById(blockId);
                var   runtimeId = BlockFactory.GetRuntimeId(blockId, (byte)metadata);
                if (runtimeId < BlockFactory.BlockPalette.Count)
                {
                    var blockState = BlockFactory.BlockPalette[(int)runtimeId];
                    block.SetState(blockState);
                }

                if (CustomBlockItemFactory == null)
                {
                    item = new ItemBlock(block, metadata);
                }
                else
                {
                    item = CustomBlockItemFactory.GetBlockItem(block, metadata, count);
                }
            }
            else
            {
                item = new Item(id, metadata, count);
            }

            // This might now be a good idea if the constructor changes these
            // properties for custom items.
            item.Metadata = metadata;
            item.Count    = (byte)count;

            return(item);
        }
Ejemplo n.º 3
0
        private void ParseSection(SubChunk section, ReadOnlySpan <byte> data)
        {
            var reader = new SpanReader();

            var version = reader.ReadByte(data);

            if (version != 8)
            {
                throw new Exception("Wrong chunk version");
            }

            var storageSize = reader.ReadByte(data);

            for (int storage = 0; storage < storageSize; storage++)
            {
                byte paletteAndFlag = reader.ReadByte(data);
                bool isRuntime      = (paletteAndFlag & 1) != 0;
                if (isRuntime)
                {
                    throw new Exception("Can't use runtime for persistent storage.");
                }
                int bitsPerBlock  = paletteAndFlag >> 1;
                int blocksPerWord = (int)Math.Floor(32d / bitsPerBlock);
                int wordCount     = (int)Math.Ceiling(4096d / blocksPerWord);

                int blockIndex = reader.Position;
                reader.Position += wordCount * 4;

                int paletteSize = reader.ReadInt32(data);

                var palette = new Dictionary <int, (short, byte)>();
                for (int j = 0; j < paletteSize; j++)
                {
                    var file = new NbtFile {
                        BigEndian = false, UseVarInt = false
                    };
                    var buffer = data.Slice(reader.Position).ToArray();

                    int numberOfBytesRead = (int)file.LoadFromStream(new MemoryStream(buffer), NbtCompression.None);
                    reader.Position += numberOfBytesRead;
                    var    tag       = file.RootTag;
                    string blockName = tag["name"].StringValue;
                    Block  block     = BlockFactory.GetBlockByName(blockName);
                    short  blockId   = 0;
                    if (block != null)
                    {
                        blockId = (short)block.Id;
                    }
                    else
                    {
                        Log.Warn($"Missing block={blockName}");
                    }
                    short blockMeta = tag["val"].ShortValue;
                    palette.Add(j, (blockId, (byte)blockMeta));
                }

                int nextStore = reader.Position;
                reader.Position = blockIndex;

                int position = 0;
                for (int wordIdx = 0; wordIdx < wordCount; wordIdx++)
                {
                    uint word = reader.ReadUInt32(data);
                    for (int block = 0; block < blocksPerWord; block++)
                    {
                        if (position >= 4096)
                        {
                            continue;                                           // padding bytes
                        }
                        int state = (int)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1));
                        int x     = (position >> 8) & 0xF;
                        int y     = position & 0xF;
                        int z     = (position >> 4) & 0xF;
                        if (state > palette.Count)
                        {
                            Log.Error($"Got wrong state={state} from word. bitsPerBlock={bitsPerBlock}, blocksPerWord={blocksPerWord}, Word={word}");
                        }
                        short bid      = palette[state].Item1;
                        byte  metadata = palette[state].Item2;

                        int runtimeId = (int)BlockFactory.GetRuntimeId(bid, metadata);
                        if (storage == 0)
                        {
                            section.SetBlockByRuntimeId(x, y, z, runtimeId);
                        }
                        else
                        {
                            section.SetLoggedBlockByRuntimeId(x, y, z, runtimeId);
                        }
                        position++;
                    }
                }
                reader.Position = nextStore;
            }
        }
Ejemplo n.º 4
0
        public void EncodePalettedChunk()
        {
            //PaletteChunk chunk = new PaletteChunk();
            //chunk.GetBytes()

            uint waste = BlockFactory.GetRuntimeId(0, 0);

            int[] legacyToRuntimeId = BlockFactory.LegacyToRuntimeId;

            short[] blocks = new short[4096];
            Random  random = new Random();

            for (int i = 0; i < blocks.Length; i++)
            {
                blocks[i] = (short)random.Next(8);
            }
            //blocks[0] = 0b000;
            //blocks[1] = 0b111;
            //blocks[2] = 0b111;
            //blocks[3] = 0b111;
            //blocks[4] = 0b111;
            //blocks[5] = 0b111;
            //blocks[6] = 0b111;
            //blocks[7] = 0b001;
            //blocks[8] = 0b010;
            //blocks[9] = 0b011;
            //blocks[10] = 0b100;
            //blocks[11] = 0b101;
            byte[] metas = new byte[4096];

            int count = 10_000;
            var sw    = Stopwatch.StartNew();

            for (int c = 0; c < count; c++)
            {
                for (int sc = 0; sc < 8; sc++)
                {
                    var  palette  = new Dictionary <uint, byte>();
                    uint prevHash = uint.MaxValue;
                    for (int i = 0; i < 4096; i++)
                    {
                        uint hash = (uint)blocks[i] << 4 | metas[i];
                        if (hash == prevHash)
                        {
                            continue;
                        }

                        prevHash      = hash;
                        palette[hash] = 0;
                    }

                    // log2(number of entries) => bits needed to store them
                    //Assert.AreEqual(0, Math.Ceiling(Math.Log(1, 2)));
                    //Assert.AreEqual(1, Math.Ceiling(Math.Log(2, 2)));
                    //Assert.AreEqual(2, Math.Ceiling(Math.Log(3, 2)));
                    //Assert.AreEqual(2, Math.Ceiling(Math.Log(4, 2)));
                    //Assert.AreEqual(3, Math.Ceiling(Math.Log(5, 2)));
                    //Assert.AreEqual(3, Math.Ceiling(Math.Log(palette.Count, 2)));
                    //Assert.AreEqual(3, Math.Ceiling(Math.Log(8, 2)));
                    //Assert.AreEqual(4, Math.Ceiling(Math.Log(9, 2)));
                    //Assert.AreEqual(4, Math.Ceiling(Math.Log(16, 2)));
                    //Assert.AreEqual(5, Math.Ceiling(Math.Log(17, 2)));
                    //Assert.AreEqual(5, Math.Ceiling(Math.Log(32, 2)));
                    //Assert.AreEqual(6, Math.Ceiling(Math.Log(33, 2)));
                    //Assert.AreEqual(6, Math.Ceiling(Math.Log(64, 2)));
                    //Assert.AreEqual(7, Math.Ceiling(Math.Log(65, 2)));
                    //Assert.AreEqual(7, Math.Ceiling(Math.Log(128, 2)));
                    //Assert.AreEqual(8, Math.Ceiling(Math.Log(129, 2)));
                    //Assert.AreEqual(8, Math.Ceiling(Math.Log(256, 2)));
                    //Assert.AreEqual(16, Math.Ceiling(Math.Log(ushort.MaxValue, 2)));

                    int bitsPerBlock = (int)Math.Ceiling(Math.Log(palette.Count, 2));

                    switch (bitsPerBlock)
                    {
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                        //Paletted1 = 1,   // 32 blocks per word
                        //Paletted2 = 2,   // 16 blocks per word
                        //Paletted3 = 3,   // 10 blocks and 2 bits of padding per word
                        //Paletted4 = 4,   // 8 blocks per word
                        //Paletted5 = 5,   // 6 blocks and 2 bits of padding per word
                        //Paletted6 = 6,   // 5 blocks and 2 bits of padding per word
                        break;

                    case 7:
                    case 8:
                        //Paletted8 = 8,  // 4 blocks per word
                        bitsPerBlock = 8;
                        break;

                    case int i when i > 8:
                        //Paletted16 = 16, // 2 blocks per word
                        bitsPerBlock = 16;
                        break;

                    default:
                        break;
                    }

                    int blocksPerWord = (int)Math.Floor(32f / bitsPerBlock);                      // Floor to remove padding bits
                    int wordsPerChunk = (int)Math.Ceiling(4096f / blocksPerWord);

                    Assert.AreEqual(10, blocksPerWord);

                    byte t = 0;
                    foreach (var b in palette.ToArray())
                    {
                        palette[b.Key] = t++;
                    }

                    uint[] indexes = new uint[wordsPerChunk];

                    int position = 0;
                    for (int w = 0; w < wordsPerChunk; w++)
                    {
                        uint word = 0;
                        for (int block = 0; block < blocksPerWord; block++)
                        {
                            if (position >= 4096)
                            {
                                continue;
                            }

                            uint state = palette[(uint)blocks[position] << 4 | metas[position]];
                            word |= state << (bitsPerBlock * block);

                            //string bin = Convert.ToString(word, 2);
                            //bin = new string('0', 32 - bin.Length) + bin;
                            //Console.WriteLine($"{bin}");

                            position++;
                        }
                        indexes[w] = word;
                    }
                }
            }
            Console.WriteLine($"time={sw.ElapsedMilliseconds}");
        }