ChunkSectionCompactStorageSerializer.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. using MineCase.World;
  6. using MongoDB.Bson.IO;
  7. using MongoDB.Bson.Serialization;
  8. using MongoDB.Bson.Serialization.Serializers;
  9. namespace MineCase.Serialization.Serializers
  10. {
  11. public class ChunkSectionCompactStorageSerializer : SealedClassSerializerBase<ChunkSectionCompactStorage>
  12. {
  13. private readonly IBsonSerializer<ChunkSectionCompactStorage.NibbleArray> _nibbleSerializer = new NibbleArraySerializer();
  14. private readonly IBsonSerializer<ChunkSectionCompactStorage.DataArray> _dataSerializer = new DataArraySerializer();
  15. protected override void SerializeValue(BsonSerializationContext context, BsonSerializationArgs args, ChunkSectionCompactStorage value)
  16. {
  17. var writer = context.Writer;
  18. writer.WriteStartDocument();
  19. writer.WriteName(nameof(ChunkSectionCompactStorage.Data));
  20. _dataSerializer.Serialize(context, value.Data);
  21. writer.WriteName(nameof(ChunkSectionCompactStorage.BlockLight));
  22. _nibbleSerializer.Serialize(context, value.BlockLight);
  23. if (value.SkyLight != null)
  24. {
  25. writer.WriteName(nameof(ChunkSectionCompactStorage.SkyLight));
  26. _nibbleSerializer.Serialize(context, value.SkyLight);
  27. }
  28. writer.WriteEndDocument();
  29. }
  30. protected override ChunkSectionCompactStorage DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
  31. {
  32. var reader = context.Reader;
  33. reader.ReadStartDocument();
  34. var data = default(ChunkSectionCompactStorage.DataArray);
  35. var blockLight = default(ChunkSectionCompactStorage.NibbleArray);
  36. var skyLight = default(ChunkSectionCompactStorage.NibbleArray);
  37. while (reader.ReadBsonType() != MongoDB.Bson.BsonType.EndOfDocument)
  38. {
  39. var name = reader.ReadName();
  40. switch (name)
  41. {
  42. case nameof(ChunkSectionCompactStorage.Data):
  43. data = _dataSerializer.Deserialize(context);
  44. break;
  45. case nameof(ChunkSectionCompactStorage.BlockLight):
  46. blockLight = _nibbleSerializer.Deserialize(context);
  47. break;
  48. case nameof(ChunkSectionCompactStorage.SkyLight):
  49. skyLight = _nibbleSerializer.Deserialize(context);
  50. break;
  51. default:
  52. break;
  53. }
  54. }
  55. reader.ReadEndDocument();
  56. return new ChunkSectionCompactStorage(data, blockLight, skyLight);
  57. }
  58. private class DataArraySerializer : SealedClassSerializerBase<ChunkSectionCompactStorage.DataArray>
  59. {
  60. protected override void SerializeValue(BsonSerializationContext context, BsonSerializationArgs args, ChunkSectionCompactStorage.DataArray value)
  61. {
  62. var writer = context.Writer;
  63. var data = new byte[value.Storage.Length * sizeof(ulong)];
  64. using (var bw = new BinaryWriter(new MemoryStream(data, true)))
  65. {
  66. foreach (var item in value.Storage)
  67. bw.Write(item);
  68. }
  69. writer.WriteBytes(data);
  70. }
  71. protected override ChunkSectionCompactStorage.DataArray DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
  72. {
  73. var reader = context.Reader;
  74. var data = reader.ReadBytes();
  75. var storage = new ulong[data.Length / sizeof(ulong)];
  76. using (var br = new BinaryReader(new MemoryStream(data, false)))
  77. {
  78. for (int i = 0; i < storage.Length; i++)
  79. storage[i] = br.ReadUInt64();
  80. }
  81. return new ChunkSectionCompactStorage.DataArray(storage);
  82. }
  83. }
  84. private class NibbleArraySerializer : SealedClassSerializerBase<ChunkSectionCompactStorage.NibbleArray>
  85. {
  86. protected override void SerializeValue(BsonSerializationContext context, BsonSerializationArgs args, ChunkSectionCompactStorage.NibbleArray value)
  87. {
  88. var writer = context.Writer;
  89. writer.WriteBytes(value.Storage);
  90. }
  91. protected override ChunkSectionCompactStorage.NibbleArray DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
  92. {
  93. var reader = context.Reader;
  94. return new ChunkSectionCompactStorage.NibbleArray(reader.ReadBytes());
  95. }
  96. }
  97. }
  98. }