1
0
jstzwj 6 жил өмнө
parent
commit
420e3fd7a4

+ 5 - 4
src/MineCase.Core/World/Chunk/BlockStateContainer.cs

@@ -6,13 +6,14 @@ namespace MineCase.World.Chunk
 {
     public class BlockStateContainer<T>
     {
-        protected BitArray _storage;
+        public BitArray Storage { get; set; }
 
-        // private IBlockStatePalette<T> palette;
+        public int Bits { get; set; }
 
-        public int Count { get => _storage.Size(); }
+        // private IBlockStatePalette<T> palette;
+        public int Count { get => Storage.Size(); }
 
-        public int Length { get => _storage.Size(); }
+        public int Length { get => Storage.Size(); }
 
         public int GetSerializedSize()
         {

+ 6 - 3
src/MineCase.Core/World/Chunk/ChunkSection.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Text;
 using MineCase.Block;
 using MineCase.World.Chunk;
@@ -10,16 +11,18 @@ namespace MineCase.World.Chunk
     {
         public static ChunkSection EmptySection = null;
 
-        private BlockStateContainer<BlockState> _data;
+        public BlockStateContainer<BlockState> Data { get; set; }
+
+        public int BlockCount { get; set; }
 
         public bool IsEmpty()
         {
-            return _data.Length == 0;
+            return Data.Length == 0;
         }
 
         public int GetSize()
         {
-            return 2 + _data.GetSerializedSize();
+            return 2 + Data.GetSerializedSize();
         }
     }
 }

+ 14 - 7
src/MineCase.Protocol/Protocol/PacketFactory.cs

@@ -1,7 +1,9 @@
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Text;
 using MineCase.Protocol.Play;
+using MineCase.Serialization;
 using MineCase.World;
 using MineCase.World.Biome;
 using MineCase.World.Chunk;
@@ -33,8 +35,8 @@ namespace MineCase.Protocol
             return i;
         }
 
-        /*
-        public static int WriteAndGetPrimaryBitMask(ChunkData packet, PacketBuffer p_218708_1_, ChunkColumn chunkIn, int changedSectionFilter)
+
+        public static int WriteAndGetPrimaryBitMask(ChunkData packet, BinaryWriter bw, ChunkColumn chunkIn, int changedSectionFilter)
         {
             int i = 0;
             ChunkSection[] achunksection = chunkIn.Sections;
@@ -46,7 +48,7 @@ namespace MineCase.Protocol
                 if (chunksection != ChunkSection.EmptySection && (!packet.FullChunk || !chunksection.IsEmpty()) && (changedSectionFilter & 1 << j) != 0)
                 {
                     i |= 1 << j;
-                    chunksection.write(p_218708_1_);
+                    bw.WriteAsChunkSection(chunksection);
                 }
             }
 
@@ -56,13 +58,12 @@ namespace MineCase.Protocol
 
                 for (int l = 0; l < abiome.Length; ++l)
                 {
-                    p_218708_1_.writeInt(abiome[l].Properties.BiomeId);
+                    bw.WriteAsInt((int)abiome[l].Properties.BiomeId);
                 }
             }
 
             return i;
         }
-        */
 
         public static ChunkData ChunkDataPacket(ChunkColumn chunkIn, int changedSectionFilter)
         {
@@ -82,9 +83,15 @@ namespace MineCase.Protocol
                 }
             }
 
-            ret.Data = new byte[GetChunkDataSize(ret, chunkIn, changedSectionFilter)];
+            using (var stream = new MemoryStream(ret.Data))
+            {
+                using (BinaryWriter bw = new BinaryWriter(stream))
+                {
+                    ret.PrimaryBitMask = (uint)WriteAndGetPrimaryBitMask(ret, bw, chunkIn, changedSectionFilter);
+                    ret.Data = stream.ToArray();
+                }
+            }
 
-            // ret.PrimaryBitMask = WriteAndGetPrimaryBitMask(new PacketBuffer(this.getWriteBuffer()), chunkIn, changedSectionFilter);
             ret.BlockEntities = new List<Nbt.Tags.NbtCompound>();
 
             foreach (var entry in chunkIn.BlockEntities)

+ 19 - 0
src/MineCase.Protocol/Serialization/BinaryReaderExtensions.cs

@@ -98,6 +98,25 @@ namespace MineCase.Serialization
             return Unsafe.As<ulong, double>(ref value);
         }
 
+        public static long[] ReadLongArray(this BinaryReader br, int maxLength = 65535)
+        {
+            uint i = br.ReadAsVarInt(out _);
+
+            if (i > maxLength)
+            {
+                throw new FormatException("LongArray with size " + i + " is bigger than allowed " + maxLength);
+            }
+
+            long[] array = new long[i];
+
+            for (int j = 0; j < array.Length; ++j)
+            {
+                array[j] = br.ReadAsLong();
+            }
+
+            return array;
+        }
+
         public static Position ReadAsPosition(this BinaryReader br)
         {
             var value = br.ReadAsUnsignedLong();

+ 40 - 1
src/MineCase.Protocol/Serialization/BinaryWriterExtensions.cs

@@ -4,8 +4,9 @@ using System.Diagnostics;
 using System.IO;
 using System.Runtime.CompilerServices;
 using System.Text;
-
+using MineCase.Block;
 using MineCase.Protocol;
+using MineCase.World.Chunk;
 
 namespace MineCase.Serialization
 {
@@ -108,6 +109,29 @@ namespace MineCase.Serialization
                 item.Serialize(bw);
         }
 
+        public static void WriteAsIntArray<T>(this BinaryWriter bw, IReadOnlyList<int> array)
+        {
+            bw.WriteAsVarInt((uint)array.Count, out _);
+
+            foreach (int i in array)
+            {
+                bw.WriteAsInt(i);
+            }
+        }
+
+        // TODO write as long
+        // write as var int array
+        // write as var long array
+        public static void WriteAsLongArray(this BinaryWriter bw, IReadOnlyList<long> array)
+        {
+            bw.WriteAsVarInt((uint)array.Count, out _);
+
+            foreach (long i in array)
+            {
+                bw.WriteAsLong(i);
+            }
+        }
+
         public static void WriteAsPosition(this BinaryWriter bw, Position position)
         {
             Debug.Assert(IsValueInRangeInclusive(position.X, -33554432, 33554431), "position X value not in range.");
@@ -120,6 +144,21 @@ namespace MineCase.Serialization
             bw.WriteAsUnsignedLong(value);
         }
 
+        public static void WriteAsChunkSection(this BinaryWriter bw, ChunkSection value)
+        {
+            bw.WriteAsShort((short)value.BlockCount);
+            bw.WriteAsBlockStateContainer(value.Data);
+        }
+
+        public static void WriteAsBlockStateContainer(this BinaryWriter bw, BlockStateContainer<BlockState> value)
+        {
+            bw.WriteAsByte((sbyte)value.Bits);
+
+            // TODO
+            // this.palette.write(buf);
+            bw.WriteAsLongArray(Array.ConvertAll(value.Storage.GetBackingData(), x => (long)x));
+        }
+
         private static bool IsValueInRangeInclusive(long value, long min, long max)
         {
             return (value >= min) && (value <= max);