示例#1
0
 /// <summary>
 /// Creates a new section at the given Y location.
 /// </summary>
 /// <param name="y">The location of the section in relative coordinates.</param>
 public Section(byte y)
 {
     this.Y = y;
     Blocks = new byte[Width*Height*Depth];
     Metadata = new NibbleArray(Width*Height*Depth);
     BlockLight = new NibbleArray(Width*Height*Depth);
     SkyLight = new NibbleArray(Width*Height*Depth);
     nonAirCount = 0;
 }
示例#2
0
 /// <summary>
 /// Creates a new section at the given Y location.
 /// </summary>
 /// <param name="y">The location of the section in relative coordinates.</param>
 public Section(byte y)
 {
     this.Y = y;
     Blocks = new byte[Width*Height*Depth];
     Metadata = new NibbleArray(Width*Height*Depth);
     BlockLight = new NibbleArray(Width*Height*Depth);
     SkyLight = new NibbleArray(Width*Height*Depth);
     for (int i = 0; i < SkyLight.Data.Length; i++)
         SkyLight.Data[i] = BlockLight.Data[i] = 0xFF;
     nonAirCount = 0;
 }
示例#3
0
        public SubChunk(bool clearBuffers = true)
        {
            _blocks = ArrayPool <short> .Shared.Rent(4096);

            _loggedBlocks = ArrayPool <byte> .Shared.Rent(4096);

            _blocklight = new NibbleArray(ArrayPool <byte> .Shared.Rent(2048));
            _skylight   = new NibbleArray(ArrayPool <byte> .Shared.Rent(2048));

            if (clearBuffers)
            {
                ClearBuffers();
            }
        }
示例#4
0
        public ChunkSection()
        {
            SkyLight   = new NibbleArray(TotalBlocks);
            BlockLight = new NibbleArray(TotalBlocks);

            Types = new VariableValueArray(13, TotalBlocks);
            for (int i = 0; i < TotalBlocks; i++)
            {
                Types[i]    = 0;
                SkyLight[i] = 0xff;
            }

            AirBlocks = TotalBlocks;
        }
        public ChunkData()
        {
            m_Blocks      = new byte[BlockCountInChunk];
            m_BlockStates = new byte[BlockCountInChunk];
            m_SkyLights   = new NibbleArray(BlockCountInChunk);
            m_BlockLights = new NibbleArray(BlockCountInChunk);

            m_HeightMap = new byte[ChunkWidth * ChunkWidth];

            m_TickRefCounts    = new ushort[SectionCountInChunk];
            m_RenderableCounts = new uint[SectionCountInChunk];

            m_ReadWriteLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
        }
示例#6
0
        public Chunk(Coordinates2D coordinates) : this()
        {
            X = coordinates.X;
            Z = coordinates.Z;
            const int size = Width * Height * Depth;

            Blocks     = new byte[size];
            Metadata   = new NibbleArray(size);
            BlockLight = new NibbleArray(size);
            SkyLight   = new NibbleArray(size);
            for (int i = 0; i < size; i++)
            {
                SkyLight[i] = 0xFF;
            }
        }
示例#7
0
        public SubChunk(bool clearBuffers = true)
        {
            _runtimeIds = new List <int> {
                (int)BlockFactory.GetBlockByName("minecraft:air").GetRuntimeId()
            };

            _blocks = ArrayPool <short> .Shared.Rent(4096);

            _loggedBlocks = ArrayPool <byte> .Shared.Rent(4096);

            _blocklight = new NibbleArray(ArrayPool <byte> .Shared.Rent(2048));
            _skylight   = new NibbleArray(ArrayPool <byte> .Shared.Rent(2048));

            if (clearBuffers)
            {
                ClearBuffers();
            }
        }
示例#8
0
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    Blocks          = null;
                    Metadata        = null;
                    Blocklight.Data = null;
                    Blocklight      = null;
                    BiomeId         = null;
                    BiomeColor      = null;
                    Skylight.Data   = null;
                    Skylight        = null;
                }

                disposed = true;
            }
        }
示例#9
0
        public ChunkSection(ChunkColumn owner, int y, bool storeSkylight, int sections = 2)
        {
            Owner = owner;
            if (sections <= 0)
            {
                sections = 1;
            }

            this._yBase = y;
            //Data = new BlockStorage();
            _blockStorages = new BlockStorage[sections];
            for (int i = 0; i < sections; i++)
            {
                _blockStorages[i] = new BlockStorage();
            }

            this.BlockLight = new NibbleArray(new byte[2048]);
            MiNET.Worlds.ChunkColumn.Fill <byte>(BlockLight.Data, 0);

            //	if (storeSkylight)
            {
                this.SkyLight = new NibbleArray(new byte[2048]);
                MiNET.Worlds.ChunkColumn.Fill <byte>(SkyLight.Data, (byte)(storeSkylight ? 0xff : 0x00));
            }
//System.Collections.BitArray a = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]);

            TransparentBlocks          = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]);
            SolidBlocks                = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]);
            ScheduledUpdates           = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]);
            ScheduledSkylightUpdates   = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]);
            ScheduledBlocklightUpdates = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]);
            RenderedBlocks             = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]);

            for (int i = 0; i < TransparentBlocks.Length; i++)
            {
                TransparentBlocks[i] = true;
                SolidBlocks[i]       = false;
            }
        }
示例#10
0
        public ChunkSection(int y, bool storeSkylight)
        {
            this._yBase     = y;
            Data            = new BlockStorage();
            this.BlockLight = new NibbleArray(4096, 0);

            if (storeSkylight)
            {
                this.SkyLight = new NibbleArray(4096, 0xff);
            }

            TransparentBlocks        = new BitArray(new byte[(16 * 16 * 16) / 8]);
            SolidBlocks              = new BitArray(new byte[(16 * 16 * 16) / 8]);
            ScheduledUpdates         = new BitArray(new byte[(16 * 16 * 16) / 8]);
            ScheduledSkylightUpdates = new BitArray(new byte[(16 * 16 * 16) / 8]);
            RenderedBlocks           = new BitArray(new byte[(16 * 16 * 16) / 8]);

            for (int i = 0; i < TransparentBlocks.Length; i++)
            {
                TransparentBlocks[i] = true;
                SolidBlocks[i]       = false;
            }
        }
示例#11
0
 public void ResetSkyLight()
 {
     this.SkyLight = new NibbleArray(4096, 0);
 }
 /// <summary>
 /// Called by a Chunk to initialize the MSB array if getBlockMSBArray returns null. Returns the newly-created
 /// NibbleArray instance.
 /// </summary>
 public virtual NibbleArray CreateBlockMSBArray()
 {
     BlockMSBArray = new NibbleArray(BlockLSBArray.Length, 4);
     return(BlockMSBArray);
 }
示例#13
0
 public virtual void Load(TagCompound c)
 {
     _blockLight = (new NibbleArray(c.GetByteArray("BlockLight"), 4));
     _skyLight   = (new NibbleArray(c.GetByteArray("SkyLight"), 4));
 }
示例#14
0
        public void Correct_Backing_len()
        {
            var a = new NibbleArray(3);

            Assert.Equal(2, a.Backing.Length);
        }
示例#15
0
 public void ResetWater(ByteArray blocks, NibbleArray data)
 {
     for (int i = 0; i < blocks.Length; i++) {
         if ((blocks[i] == BlockType.STATIONARY_WATER || blocks[i] == BlockType.WATER) && data[i] != 0) {
             blocks[i] = BlockType.AIR;
             data[i] = 0;
         }
         else if (blocks[i] == BlockType.WATER) {
             blocks[i] = BlockType.STATIONARY_WATER;
         }
     }
 }
示例#16
0
        public static byte[] Compress(Bitmap image, ref NibbleArray beforeCompressed, PixelFormat format)
        {
            using var info = new MemoryStream();
            var bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly,
                                            format);

            var pixelsPer = System.Drawing.Image.GetPixelFormatSize(bitmapData.PixelFormat) >> 3;

            var height = bitmapData.Height;
            var width  = bitmapData.Width * pixelsPer;

            var pixels           = new NibbleArray(width * height);
            var changedPixelData = new NibbleArray(width * height);
            var offset           = bitmapData.Stride - width;

            var changedPos = 0;

            unsafe
            {
                var pos          = 0;
                var point        = (byte *)bitmapData.Scan0;
                var changed      = false;
                var startChanged = 0;
                for (var y = 0; y < height; y++)
                {
                    for (var x = 0; x < width; x++)
                    {
                        var before = changed;

                        var color = pixels[pos++] = *point++;

                        var check = pos - 1;
                        changed = pixels[check] != beforeCompressed[check];

                        if (changed)
                        {
                            changedPixelData[changedPos++] = color;
                        }
                        if (before == changed)
                        {
                            continue;
                        }
                        if (!before)
                        {
                            startChanged = check;
                        }
                        else
                        {
                            var count = check - startChanged - 1;
                            Write(info, ByteBuf.GetVarInt(startChanged));
                            Write(info, ByteBuf.GetVarInt(count));
                        }
                    }

                    point += offset;
                }

                if (changed)
                {
                    var count = pos - startChanged - 1;
                    Write(info, ByteBuf.GetVarInt(startChanged));
                    Write(info, ByteBuf.GetVarInt(count));
                }
            }

            beforeCompressed = pixels;
            image.UnlockBits(bitmapData);

            if (changedPos == 0)
            {
                return(null);
            }

            using var ms = new MemoryStream();
            var changedPixels = changedPixelData.GetData(changedPos);
            var length        = changedPixels.Length;

            // var compressed = ByteHelper.Compress(changedPixels);
            // if (length > compressed.Length)
            // {
            //     // Debug.WriteLine($"{changedPixels.Length} -> {compressed.Length}");
            //     length = compressed.Length;
            //     changedPixels = compressed;
            //     ms.WriteByte(1);
            // }
            // else
            ms.WriteByte(0);

            Write(ms, ByteBuf.GetVarInt(length));
            ms.Write(changedPixels, 0, length);

            Write(ms, info.ToArray());

            return(ms.ToArray());
        }
示例#17
0
        public void Throws_OutOfRange()
        {
            var a = new NibbleArray(3);

            Assert.Throws <IndexOutOfRangeException>(() => a[3] = 10);
        }
示例#18
0
 public AnvilSectionClassic(int y, bool makeSkyLight)
     : base(y, makeSkyLight)
 {
     _blocks = new byte[4096];
     _data   = new NibbleArray();
 }
 public ChunkSectionCompactStorage(DataArray data, NibbleArray blockLight, NibbleArray skyLight)
 {
     Data       = data;
     BlockLight = blockLight;
     SkyLight   = skyLight;
 }
示例#20
0
        private void HandleChunk(byte[] chunkData, int cx, int cz, Action <ChunkColumn> callback)
        {
            MeasureProfiler.StartCollectingData();
            var profiler = MiniProfiler.StartNew("BEToJavaColumn");

            try
            {
                using (MemoryStream stream = new MemoryStream(chunkData))
                {
                    NbtBinaryReader defStream = new NbtBinaryReader(stream, true);

                    int count = defStream.ReadByte();
                    if (count < 1)
                    {
                        Log.Warn("Nothing to read");
                        return;
                    }

                    ChunkColumn chunkColumn = new ChunkColumn();
                    chunkColumn.IsDirty = true;
                    chunkColumn.X       = cx;
                    chunkColumn.Z       = cz;

                    for (int s = 0; s < count; s++)
                    {
                        var section = chunkColumn.Sections[s] as ChunkSection;
                        if (section == null)
                        {
                            section = new ChunkSection(s, true);
                        }

                        int version = defStream.ReadByte();

                        if (version == 1 || version == 8)
                        {
                            int storageSize = defStream.ReadByte();

                            for (int storage = 0; storage < storageSize; storage++)
                            {
                                int  paletteAndFlag = defStream.ReadByte();
                                bool isRuntime      = (paletteAndFlag & 1) != 0;
                                int  bitsPerBlock   = paletteAndFlag >> 1;
                                int  blocksPerWord  = (int)Math.Floor(32f / bitsPerBlock);
                                int  wordCount      = (int)Math.Ceiling(4096.0f / blocksPerWord);

                                uint[] words = new uint[wordCount];
                                for (int w = 0; w < wordCount; w++)
                                {
                                    int word = defStream.ReadInt32();
                                    words[w] = SwapBytes((uint)word);
                                }

                                uint[] pallete = new uint[0];

                                if (isRuntime)
                                {
                                    int palleteSize = VarInt.ReadSInt32(stream);
                                    pallete = new uint[palleteSize];

                                    for (int pi = 0; pi < pallete.Length; pi++)
                                    {
                                        var ui = (uint)VarInt.ReadSInt32(stream);
                                        pallete[pi] = ui;
                                    }

                                    if (palleteSize == 0)
                                    {
                                        Log.Warn($"Pallete size is 0");
                                        continue;
                                    }
                                }

                                int position = 0;
                                for (int w = 0; w < wordCount; w++)
                                {
                                    uint word = words[w];
                                    for (int block = 0; block < blocksPerWord; block++)
                                    {
                                        if (position >= 4096)
                                        {
                                            break;                                                   // padding bytes
                                        }
                                        uint state =
                                            (uint)((word >> ((position % blocksPerWord) * bitsPerBlock)) &
                                                   ((1 << bitsPerBlock) - 1));
                                        int x = (position >> 8) & 0xF;
                                        int y = position & 0xF;
                                        int z = (position >> 4) & 0xF;

                                        if (storage == 0)
                                        {
                                            if (state >= pallete.Length)
                                            {
                                                continue;
                                            }

                                            IBlockState translated = _convertedStates.GetOrAdd(pallete[state],
                                                                                               u =>
                                            {
                                                if (_blockStateMap.TryGetValue(pallete[state], out var bs))
                                                {
                                                    var result =
                                                        BlockFactory.RuntimeIdTable.FirstOrDefault(xx =>
                                                                                                   xx.Name == bs.Name);

                                                    if (result != null && result.Id >= 0)
                                                    {
                                                        var reverseMap = MiNET.Worlds.AnvilWorldProvider.Convert.FirstOrDefault(map =>
                                                                                                                                map.Value.Item1 == result.Id);

                                                        var id = result.Id;
                                                        if (reverseMap.Value != null)
                                                        {
                                                            id = reverseMap.Key;
                                                        }

                                                        var res = BlockFactory.GetBlockStateID(
                                                            (int)id,
                                                            (byte)bs.Data);

                                                        if (AnvilWorldProvider.BlockStateMapper.TryGetValue(
                                                                res,
                                                                out var res2))
                                                        {
                                                            var t = BlockFactory.GetBlockState(res2);
                                                            t     = TranslateBlockState(t, id,
                                                                                        bs.Data);

                                                            return(t);
                                                        }
                                                        else
                                                        {
                                                            Log.Info(
                                                                $"Did not find anvil statemap: {result.Name}");
                                                            return(TranslateBlockState(
                                                                       BlockFactory.GetBlockState(result.Name),
                                                                       id, bs.Data));
                                                        }
                                                    }

                                                    return(TranslateBlockState(
                                                               BlockFactory.GetBlockState(bs.Name),
                                                               -1, bs.Data));
                                                }

                                                return(null);
                                            });

                                            if (translated != null)
                                            {
                                                section.Set(x, y, z, translated);
                                            }
                                        }
                                        else
                                        {
                                            //TODO.
                                        }

                                        position++;
                                    }

                                    if (position >= 4096)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            #region OldFormat

                            byte[] blockIds = new byte[4096];
                            defStream.Read(blockIds, 0, blockIds.Length);

                            NibbleArray data = new NibbleArray(4096);
                            defStream.Read(data.Data, 0, data.Data.Length);

                            for (int x = 0; x < 16; x++)
                            {
                                for (int z = 0; z < 16; z++)
                                {
                                    for (int y = 0; y < 16; y++)
                                    {
                                        int idx  = (x << 8) + (z << 4) + y;
                                        var id   = blockIds[idx];
                                        var meta = data[idx];

                                        IBlockState result = null;

                                        if (id > 0 && result == null)
                                        {
                                            var res = BlockFactory.GetBlockStateID(id, meta);

                                            if (AnvilWorldProvider.BlockStateMapper.TryGetValue(res,
                                                                                                out var res2))
                                            {
                                                var t = BlockFactory.GetBlockState(res2);
                                                t = TranslateBlockState(t, id,
                                                                        meta);

                                                result = t;
                                            }
                                            else
                                            {
                                                Log.Info($"Did not find anvil statemap: {result.Name}");
                                                result = TranslateBlockState(BlockFactory.GetBlockState(res),
                                                                             id, meta);
                                            }
                                        }

                                        if (result == null)
                                        {
                                            var results = BlockFactory.RuntimeIdTable.Where(xx =>
                                                                                            xx.Id == id && xx.Data == meta).ToArray();

                                            if (results.Length > 0)
                                            {
                                                result = TranslateBlockState(
                                                    BlockFactory.GetBlockState((uint)results[0].RuntimeId), id,
                                                    meta);
                                            }
                                        }

                                        if (result != null)
                                        {
                                            section.Set(x, y, z, result);
                                        }
                                    }
                                }
                            }

                            #endregion
                        }

                        if (UseAlexChunks)
                        {
                            //  Log.Info($"Alex chunk!");

                            var rawSky = new Utils.NibbleArray(4096);
                            defStream.Read(rawSky.Data, 0, rawSky.Data.Length);

                            var rawBlock = new Utils.NibbleArray(4096);
                            defStream.Read(rawBlock.Data, 0, rawBlock.Data.Length);

                            for (int x = 0; x < 16; x++)
                            {
                                for (int y = 0; y < 16; y++)
                                {
                                    for (int z = 0; z < 16; z++)
                                    {
                                        var peIndex = (x * 256) + (z * 16) + y;
                                        var sky     = rawSky[peIndex];
                                        var block   = rawBlock[peIndex];

                                        var idx = y << 8 | z << 4 | x;

                                        section.SkyLight[idx]   = sky;
                                        section.BlockLight[idx] = block;
                                    }
                                }
                            }
                        }

                        section.RemoveInvalidBlocks();
                        section.IsDirty = true;

                        //Make sure the section is saved.
                        chunkColumn.Sections[s] = section;
                    }


                    byte[] ba = new byte[512];
                    if (defStream.Read(ba, 0, 256 * 2) != 256 * 2)
                    {
                        Log.Error($"Out of data height");
                    }

                    Buffer.BlockCopy(ba, 0, chunkColumn.Height, 0, 512);

                    int[] biomeIds = new int[256];
                    for (int i = 0; i < biomeIds.Length; i++)
                    {
                        biomeIds[i] = defStream.ReadByte();
                    }

                    chunkColumn.BiomeId = biomeIds;

                    if (stream.Position >= stream.Length - 1)
                    {
                        callback?.Invoke(chunkColumn);
                        return;
                    }

                    int borderBlock = VarInt.ReadSInt32(stream);
                    if (borderBlock > 0)
                    {
                        byte[] buf = new byte[borderBlock];
                        int    len = defStream.Read(buf, 0, borderBlock);
                    }


                    if (stream.Position < stream.Length - 1)
                    {
                        while (stream.Position < stream.Length)
                        {
                            NbtFile file = new NbtFile()
                            {
                                BigEndian = false,
                                UseVarInt = true
                            };

                            file.LoadFromStream(stream, NbtCompression.None);
                        }
                    }

                    if (stream.Position < stream.Length - 1)
                    {
                        Log.Warn(
                            $"Still have data to read\n{Packet.HexDump(defStream.ReadBytes((int) (stream.Length - stream.Position)))}");
                    }

                    //Done processing this chunk, send to world
                    callback?.Invoke(chunkColumn);
                }
            }
            catch (Exception ex)
            {
                Log.Error($"Exception in chunk loading: {ex.ToString()}");
            }
            finally
            {
                profiler?.Stop();
                MeasureProfiler.SaveData();
            }
        }
示例#21
0
 public void ResetWater(ByteArray blocks, NibbleArray data)
 {
     for (int i = 0; i < blocks.Length; i++) {
         if ((blocks[i] == BlockInfo.StationaryWater.ID || blocks[i] == BlockInfo.Water.ID) && data[i] != 0) {
             blocks[i] = (byte)BlockInfo.Air.ID;
             data[i] = 0;
         }
         else if (blocks[i] == BlockInfo.Water.ID) {
             blocks[i] = (byte)BlockInfo.StationaryWater.ID;
         }
     }
 }
 public virtual void Func_48715_h()
 {
     BlockMSBArray = null;
 }
示例#23
0
 public void ResetLava(ByteArray blocks, NibbleArray data)
 {
     for (int i = 0; i < blocks.Length; i++) {
         if ((blocks[i] == BlockType.STATIONARY_LAVA || blocks[i] == BlockType.LAVA) && data[i] != 0) {
             blocks[i] = BlockType.AIR;
             data[i] = 0;
         }
         else if (blocks[i] == BlockType.LAVA) {
             blocks[i] = BlockType.STATIONARY_LAVA;
         }
     }
 }
 /// <summary>
 /// Sets the NibbleArray instance used for Sky-light values in this particular storage block.
 /// </summary>
 public virtual void SetSkylightArray(NibbleArray par1NibbleArray)
 {
     SkylightArray = par1NibbleArray;
 }
示例#25
0
        public static void ConvertToAnvilFormat(AnvilConverterData par0AnvilConverterData, NBTTagCompound par1NBTTagCompound, WorldChunkManager par2WorldChunkManager)
        {
            par1NBTTagCompound.SetInteger("xPos", par0AnvilConverterData.x);
            par1NBTTagCompound.SetInteger("zPos", par0AnvilConverterData.z);
            par1NBTTagCompound.SetLong("LastUpdate", par0AnvilConverterData.LastUpdated);
            int[] ai = new int[par0AnvilConverterData.Heightmap.Length];

            for (int i = 0; i < par0AnvilConverterData.Heightmap.Length; i++)
            {
                ai[i] = par0AnvilConverterData.Heightmap[i];
            }

            par1NBTTagCompound.Func_48183_a("HeightMap", ai);
            par1NBTTagCompound.Setbool("TerrainPopulated", par0AnvilConverterData.TerrainPopulated);
            NBTTagList nbttaglist = new NBTTagList("Sections");

            for (int j = 0; j < 8; j++)
            {
                bool flag = true;

                for (int l = 0; l < 16 && flag; l++)
                {
label0:

                    for (int j1 = 0; j1 < 16 && flag; j1++)
                    {
                        int k1 = 0;

                        do
                        {
                            if (k1 >= 16)
                            {
                                goto label0;
                            }

                            int  l1    = l << 11 | k1 << 7 | j1 + (j << 4);
                            byte byte0 = par0AnvilConverterData.Blocks[l1];

                            if (byte0 != 0)
                            {
                                flag = false;
                                goto label0;
                            }

                            k1++;
                        }while (true);
                    }
                }

                if (flag)
                {
                    continue;
                }

                byte[]      abyte1       = new byte[4096];
                NibbleArray nibblearray  = new NibbleArray(abyte1.Length, 4);
                NibbleArray nibblearray1 = new NibbleArray(abyte1.Length, 4);
                NibbleArray nibblearray2 = new NibbleArray(abyte1.Length, 4);

                for (int i2 = 0; i2 < 16; i2++)
                {
                    for (int j2 = 0; j2 < 16; j2++)
                    {
                        for (int k2 = 0; k2 < 16; k2++)
                        {
                            int  l2    = i2 << 11 | k2 << 7 | j2 + (j << 4);
                            byte byte1 = par0AnvilConverterData.Blocks[l2];
                            abyte1[j2 << 8 | k2 << 4 | i2] = (byte)(byte1 & 0xff);
                            nibblearray.Set(i2, j2, k2, par0AnvilConverterData.Data.Get(i2, j2 + (j << 4), k2));
                            nibblearray1.Set(i2, j2, k2, par0AnvilConverterData.SkyLight.Get(i2, j2 + (j << 4), k2));
                            nibblearray2.Set(i2, j2, k2, par0AnvilConverterData.BlockLight.Get(i2, j2 + (j << 4), k2));
                        }
                    }
                }

                NBTTagCompound nbttagcompound = new NBTTagCompound();
                nbttagcompound.SetByte("Y", (byte)(j & 0xff));
                nbttagcompound.SetByteArray("Blocks", abyte1);
                nbttagcompound.SetByteArray("Data", nibblearray.Data);
                nbttagcompound.SetByteArray("SkyLight", nibblearray1.Data);
                nbttagcompound.SetByteArray("BlockLight", nibblearray2.Data);
                nbttaglist.AppendTag(nbttagcompound);
            }

            par1NBTTagCompound.SetTag("Sections", nbttaglist);
            byte[] abyte0 = new byte[256];

            for (int k = 0; k < 16; k++)
            {
                for (int i1 = 0; i1 < 16; i1++)
                {
                    abyte0[i1 << 4 | k] = (byte)(par2WorldChunkManager.GetBiomeGenAt(par0AnvilConverterData.x << 4 | k, par0AnvilConverterData.z << 4 | i1).BiomeID & 0xff);
                }
            }

            par1NBTTagCompound.SetByteArray("Biomes", abyte0);
            par1NBTTagCompound.SetTag("Entities", par0AnvilConverterData.Entities);
            par1NBTTagCompound.SetTag("TileEntities", par0AnvilConverterData.TileEntities);

            if (par0AnvilConverterData.TileTicks != null)
            {
                par1NBTTagCompound.SetTag("TileTicks", par0AnvilConverterData.TileTicks);
            }
        }
示例#26
0
        private static bool WriteStore(MemoryStream stream, short[] blocks, NibbleArray metadata, bool forceWrite)
        {
            var  palette  = new Dictionary <uint, byte>();
            uint prevHash = uint.MaxValue;

            for (int i = 0; i < 4096; i++)
            {
                uint hash = (uint)blocks[i] << 4 | metadata[i];                  // 1.7
                if (hash == prevHash)
                {
                    continue;
                }

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

            // log2(number of entries) => bits needed to store them
            int bitsPerBlock = (int)Math.Ceiling(Math.Log(palette.Count, 2));

            switch (bitsPerBlock)
            {
            case 0:
                if (!forceWrite && palette.ContainsKey(0))
                {
                    return(false);
                }
                bitsPerBlock = 1;
                break;

            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;
            }

            stream.WriteByte((byte)((bitsPerBlock << 1) | 1));              // version

            int blocksPerWord = (int)Math.Floor(32f / bitsPerBlock);        // Floor to remove padding bits
            int wordsPerChunk = (int)Math.Ceiling(4096f / 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 | metadata[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;
            }

            byte[] ba = new byte[indexes.Length * 4];
            Buffer.BlockCopy(indexes, 0, ba, 0, indexes.Length * 4);
            stream.Write(ba, 0, ba.Length);

            int[] legacyToRuntimeId = BlockFactory.LegacyToRuntimeId;

            VarInt.WriteSInt32(stream, palette.Count);             // count
            foreach (var val in palette)
            {
                VarInt.WriteSInt32(stream, legacyToRuntimeId[val.Key]);
            }

            return(true);
        }
 /// <summary>
 /// Sets the NibbleArray of block metadata (blockMetadataArray) for this ExtendedBlockStorage.
 /// </summary>
 public virtual void SetBlockMetadataArray(NibbleArray par1NibbleArray)
 {
     BlockMetadataArray = par1NibbleArray;
 }
        private CompoundTag ConvertSection(Tag sectionTag)
        {
            byte[]      blockData = new byte[4096];
            NibbleArray metaData  = new NibbleArray(4096);

            CompoundTag section = (CompoundTag)sectionTag;

            long[]  states  = section.GetLongArray("BlockStates");
            ListTag palette = section.GetList("Palette");
            List <RuntimeTable.Table> indexs = new List <RuntimeTable.Table>();

            foreach (Tag paletteTag in palette.Tags)
            {
                if (paletteTag is CompoundTag)
                {
                    CompoundTag pt   = (CompoundTag)paletteTag;
                    string      name = pt.GetString("Name");
                    indexs.Add(RuntimeTable.GetNameToTable(name, pt.GetCompound("Properties").Tags));
                }
            }

            int         bits      = CheckMostBit(indexs.Count - 1);
            List <byte> fixStates = new List <byte>();

            foreach (long state in states)
            {
                fixStates.AddRange(BitConverter.GetBytes((ulong)state));
            }

            BitArray stateBits = new BitArray(fixStates.ToArray());

            for (int i = 0; i < 4096; i++)
            {
                int  bitOffset = i * bits;
                uint index     = stateBits.Get(bitOffset + bits - 1) ? 1u : 0u;
                for (int j = bits - 2; j >= 0; j--)
                {
                    index <<= 1;
                    index  |= stateBits.Get(bitOffset + j) ? 1u : 0u;
                }

                try
                {
                    RuntimeTable.Table table = indexs[(int)index];
                    blockData[i] = (byte)(table.Id & 0xff);
                    metaData[i]  = (byte)(table.Data & 0xf);
                }
                catch (Exception e)
                {
                    Logger.Info(indexs.Count + " = " + states[0] + " >>> " + states[1]);
                    throw e;
                }
            }

            var newSection = (CompoundTag)section.Clone();

            newSection.Remove("BlockStates");
            newSection.Remove("Palette");

            newSection.PutByteArray("Blocks", blockData);
            newSection.PutByteArray("Data", metaData.ArrayData);

            return(newSection);
        }
 /// <summary>
 /// Sets the NibbleArray instance used for Block-light values in this particular storage block.
 /// </summary>
 public virtual void SetBlocklightArray(NibbleArray par1NibbleArray)
 {
     BlocklightArray = par1NibbleArray;
 }
示例#30
0
 public void GetRawDataNoCheck(out ChunkPos pos, out IWorld world, out BlockData[,,] blocks, out Quaternion[,,] rotations, out NibbleArray skyLights, out byte[,] heightMap)
 {
     pos       = m_Position;
     world     = m_World;
     blocks    = m_Blocks;
     rotations = m_Rotations;
     skyLights = m_SkyLights;
     heightMap = m_HeightMap;
 }