Example #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);
        }
        public override void WriteTo(BinaryWriter reader)
        {
            Stream stream = reader.BaseStream;

            VarInt.WriteSInt32(stream, Value.X);
            VarInt.WriteSInt32(stream, Value.Y);
            VarInt.WriteSInt32(stream, Value.Z);
        }
Example #3
0
        public byte[] GetBytes()
        {
            if (_cache != null)
            {
                return(_cache);
            }

            using (MemoryStream stream = MiNetServer.MemoryStreamManager.GetStream())
            {
                NbtBinaryWriter writer = new NbtBinaryWriter(stream, true);

                int topEmpty = 16;
                for (int ci = 15; ci >= 0; ci--)
                {
                    if (chunks[ci].IsAllAir())
                    {
                        topEmpty = ci;
                    }
                    else
                    {
                        break;
                    }
                }

                writer.Write((byte)topEmpty);

                int sent = 0;
                for (int ci = 0; ci < topEmpty; ci++)
                {
                    writer.Write((byte)0);
                    writer.Write(chunks[ci].GetBytes());
                    sent++;
                }

                //Log.Debug($"Saved sending {16 - sent} chunks");

                //RecalcHeight();

                byte[] ba = new byte[512];
                Buffer.BlockCopy(height, 0, ba, 0, 512);
                writer.Write(ba);
                //Log.Debug($"Heights:\n{Package.HexDump(ba)}");

                //BiomeUtils utils = new BiomeUtils();
                //utils.PrecomputeBiomeColors();

                //InterpolateBiomes();

                writer.Write(biomeId);

                //for (int i = 0; i < biomeId.Length; i++)
                //{
                //	//var biome = biomeId[i];
                //	int color = biomeColor[i];
                //	writer.Write((int) (color & 0x00ffffff) /*| biome << 24*/);
                //}

                //short extraSize = 0;
                //writer.Write(extraSize); // No extra data

                // Count = SignedVarInt (zigzag)
                // Each entry
                // - Hash SignedVarint x << 12, z << 8, y
                // - Block data short

                writer.Write((byte)0);                 // Border blocks - nope

                VarInt.WriteSInt32(stream, 0);         // Block extradata count
                //VarInt.WriteSInt32(stream, 2);
                //VarInt.WriteSInt32(stream, 1 << 12 | 1 << 8 | 4);
                //writer.Write((byte)31);
                //writer.Write((byte)0);

                if (BlockEntities.Count == 0)
                {
                    //NbtFile file = new NbtFile(new NbtCompound(string.Empty)) {BigEndian = false, UseVarInt = true};
                    //file.SaveToStream(writer.BaseStream, NbtCompression.None);
                }
                else
                {
                    foreach (NbtCompound blockEntity in BlockEntities.Values.ToArray())
                    {
                        NbtFile file = new NbtFile(blockEntity)
                        {
                            BigEndian = false, UseVarInt = true
                        };
                        file.SaveToStream(writer.BaseStream, NbtCompression.None);
                    }
                }

                _cache = stream.ToArray();
            }

            return(_cache);
        }
Example #4
0
        private bool WriteStore(MemoryStream stream, short[] blocks, byte[] loggedBlocks, bool forceWrite, List <int> palette)
        {
            if (palette.Count == 0)
            {
                return(false);
            }

            // 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.Contains(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;

            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;
                    if (blocks != null)
                    {
                        state = (uint)blocks[position];
                    }
                    else
                    {
                        state = (uint)loggedBlocks[position];
                    }
                    word |= state << (bitsPerBlock * block);

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

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

            return(true);
        }
Example #5
0
 public void WriteSignedVarInt(int value)
 {
     VarInt.WriteSInt32(_buffer, value);
 }
Example #6
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);
        }
Example #7
0
 public override void WriteTo(BinaryWriter stream)
 {
     VarInt.WriteSInt32(stream.BaseStream, Value);
 }