diff --git a/Configs/Defines/Actor.xml b/Configs/Defines/Actor.xml
deleted file mode 100644
index a3096203..00000000
--- a/Configs/Defines/Actor.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Configs/Defines/BuffConfig.xml b/Configs/Defines/BuffConfig.xml
deleted file mode 100644
index e7f4a904..00000000
--- a/Configs/Defines/BuffConfig.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Configs/Defines/SkillConfig.xml b/Configs/Defines/SkillConfig.xml
deleted file mode 100644
index 4c32766b..00000000
--- a/Configs/Defines/SkillConfig.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
- 技能元素类型
-
-
-
-
-
- 伤害类型
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Configs/Defines/__root__.xml b/Configs/Defines/__root__.xml
deleted file mode 100644
index efa41cc3..00000000
--- a/Configs/Defines/__root__.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
- client
- server
- editor
-
-
-
- 相对data目录
- 相对data目录
- 相对data目录
-
-
-
-
-
\ No newline at end of file
diff --git a/Configs/Excels/Buff配置表.xlsx b/Configs/Excels/Buff配置表.xlsx
deleted file mode 100644
index c4993753..00000000
Binary files a/Configs/Excels/Buff配置表.xlsx and /dev/null differ
diff --git a/Configs/Excels/__beans__.xlsx b/Configs/Excels/__beans__.xlsx
deleted file mode 100644
index 69887b73..00000000
Binary files a/Configs/Excels/__beans__.xlsx and /dev/null differ
diff --git a/Configs/Excels/__enums__.xlsx b/Configs/Excels/__enums__.xlsx
deleted file mode 100644
index ab619b28..00000000
Binary files a/Configs/Excels/__enums__.xlsx and /dev/null differ
diff --git a/Configs/Excels/__tables__.xlsx b/Configs/Excels/__tables__.xlsx
deleted file mode 100644
index 5d23fa95..00000000
Binary files a/Configs/Excels/__tables__.xlsx and /dev/null differ
diff --git a/Configs/Excels/怪物模型配置表.xlsx b/Configs/Excels/怪物模型配置表.xlsx
deleted file mode 100644
index 735a206f..00000000
Binary files a/Configs/Excels/怪物模型配置表.xlsx and /dev/null differ
diff --git a/Configs/Excels/怪物配置表.xlsx b/Configs/Excels/怪物配置表.xlsx
deleted file mode 100644
index 25f51ee5..00000000
Binary files a/Configs/Excels/怪物配置表.xlsx and /dev/null differ
diff --git a/Configs/Excels/技能配置表.xlsx b/Configs/Excels/技能配置表.xlsx
deleted file mode 100644
index f7f0e3f7..00000000
Binary files a/Configs/Excels/技能配置表.xlsx and /dev/null differ
diff --git a/Configs/Excels/文本配置表_客户端.xlsx b/Configs/Excels/文本配置表_客户端.xlsx
deleted file mode 100644
index efd76968..00000000
Binary files a/Configs/Excels/文本配置表_客户端.xlsx and /dev/null differ
diff --git a/Configs/Excels/模型配置表.xlsx b/Configs/Excels/模型配置表.xlsx
deleted file mode 100644
index e7535906..00000000
Binary files a/Configs/Excels/模型配置表.xlsx and /dev/null differ
diff --git a/Configs/Excels/道具配置表.xlsx b/Configs/Excels/道具配置表.xlsx
deleted file mode 100644
index d04c11b4..00000000
Binary files a/Configs/Excels/道具配置表.xlsx and /dev/null differ
diff --git a/Configs/GameConfig/Datas/__beans__.xlsx b/Configs/GameConfig/Datas/__beans__.xlsx
new file mode 100644
index 00000000..0af4c6ac
Binary files /dev/null and b/Configs/GameConfig/Datas/__beans__.xlsx differ
diff --git a/Configs/GameConfig/Datas/__enums__.xlsx b/Configs/GameConfig/Datas/__enums__.xlsx
new file mode 100644
index 00000000..ec60d067
Binary files /dev/null and b/Configs/GameConfig/Datas/__enums__.xlsx differ
diff --git a/Configs/GameConfig/Datas/__tables__.xlsx b/Configs/GameConfig/Datas/__tables__.xlsx
new file mode 100644
index 00000000..11e4ad23
Binary files /dev/null and b/Configs/GameConfig/Datas/__tables__.xlsx differ
diff --git a/Configs/GameConfig/Datas/item.xlsx b/Configs/GameConfig/Datas/item.xlsx
new file mode 100644
index 00000000..c463653e
Binary files /dev/null and b/Configs/GameConfig/Datas/item.xlsx differ
diff --git a/Configs/GameConfig/Defines/builtin.xml b/Configs/GameConfig/Defines/builtin.xml
new file mode 100644
index 00000000..e535ff48
--- /dev/null
+++ b/Configs/GameConfig/Defines/builtin.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Configs/GameConfig/gen_code_bin_to_project.bat b/Configs/GameConfig/gen_code_bin_to_project.bat
new file mode 100644
index 00000000..9d97b29e
--- /dev/null
+++ b/Configs/GameConfig/gen_code_bin_to_project.bat
@@ -0,0 +1,14 @@
+set WORKSPACE=../..
+set LUBAN_DLL=%WORKSPACE%\Tools\Luban\Luban.dll
+set CONF_ROOT=.
+set DATA_OUTPATH=%WORKSPACE%/UnityProject/Assets/AssetRaw/Configs/bytes/
+set CODE_OUTPATH=%WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig/
+dotnet %LUBAN_DLL% ^
+ -t client ^
+ -c cs-bin ^
+ -d bin^
+ --conf %CONF_ROOT%\luban.conf ^
+ -x outputCodeDir=%CODE_OUTPATH% ^
+ -x outputDataDir=%DATA_OUTPATH%
+pause
+
diff --git a/Configs/GameConfig/gen_code_bin_to_server.bat b/Configs/GameConfig/gen_code_bin_to_server.bat
new file mode 100644
index 00000000..86ac4cab
--- /dev/null
+++ b/Configs/GameConfig/gen_code_bin_to_server.bat
@@ -0,0 +1,15 @@
+set WORKSPACE=../../
+set LUBAN_DLL=%WORKSPACE%/Tools/Luban/Luban.dll
+set CONF_ROOT=.
+set DATA_OUTPATH=%WORKSPACE%/Server/GameConfig
+set CODE_OUTPATH=%WORKSPACE%/Server/Hotfix/Config/GameConfig
+
+dotnet %LUBAN_DLL% ^
+ -t server^
+ -c cs-bin ^
+ -d bin^
+ --conf %CONF_ROOT%\luban.conf ^
+ -x outputCodeDir=%CODE_OUTPATH% ^
+ -x outputDataDir=%DATA_OUTPATH%
+pause
+
diff --git a/Configs/GameConfig/luban.conf b/Configs/GameConfig/luban.conf
new file mode 100644
index 00000000..9bbac950
--- /dev/null
+++ b/Configs/GameConfig/luban.conf
@@ -0,0 +1,22 @@
+{
+ "groups":
+ [
+ {"names":["c"], "default":true},
+ {"names":["s"], "default":true},
+ {"names":["e"], "default":true}
+ ],
+ "schemaFiles":
+ [
+ {"fileName":"Defines", "type":""},
+ {"fileName":"Datas/__tables__.xlsx", "type":"table"},
+ {"fileName":"Datas/__beans__.xlsx", "type":"bean"},
+ {"fileName":"Datas/__enums__.xlsx", "type":"enum"}
+ ],
+ "dataDir": "Datas",
+ "targets":
+ [
+ {"name":"server", "manager":"Tables", "groups":["s"], "topModule":"cfg"},
+ {"name":"client", "manager":"Tables", "groups":["c"], "topModule":"cfg"},
+ {"name":"all", "manager":"Tables", "groups":["c,s,e"], "topModule":"cfg"}
+ ]
+}
\ No newline at end of file
diff --git a/Configs/gen_code_bin_to_project.bat b/Configs/gen_code_bin_to_project.bat
deleted file mode 100644
index 43d5b643..00000000
--- a/Configs/gen_code_bin_to_project.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-cd /d %~dp0
-set WORKSPACE=..
-
-set GEN_CLIENT=%WORKSPACE%\Tools\Luban.ClientServer\Luban.ClientServer.exe
-set CONF_ROOT=%WORKSPACE%\Configs
-set DATA_OUTPUT=%ROOT_PATH%..\GenerateDatas
-set CUSTOM_TEMP=%WORKSPACE%\Configs\CustomTemplate\CustomTemplate_Client
-
-xcopy %CUSTOM_TEMP%\ConfigSystem.cs %WORKSPACE%\UnityProject\Assets\GameScripts\HotFix\GameProto\ConfigSystem.cs /s /e /i /y
-
-%GEN_CLIENT% -j cfg --^
- -d %CONF_ROOT%\Defines\__root__.xml ^
- --input_data_dir %CONF_ROOT%\Excels^
- --output_code_dir %WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig ^
- --output_data_dir %WORKSPACE%/UnityProject/Assets/AssetRaw/Configs/bytes/ ^
- --gen_types code_cs_unity_bin,data_bin ^
- -s client
-
-echo ======== 生成配置文件结束 ========
-
-pause
\ No newline at end of file
diff --git a/Configs/gen_code_bin_to_project_lazyload.bat b/Configs/gen_code_bin_to_project_lazyload.bat
deleted file mode 100644
index fb2cceba..00000000
--- a/Configs/gen_code_bin_to_project_lazyload.bat
+++ /dev/null
@@ -1,40 +0,0 @@
-cd /d %~dp0
-set WORKSPACE=..
-
-set GEN_CLIENT=%WORKSPACE%\Tools\Luban.ClientServer\Luban.ClientServer.exe
-set CONF_ROOT=%WORKSPACE%\Configs
-set DATA_OUTPUT=%ROOT_PATH%..\GenerateDatas
-set CUSTOM_TEMP=%WORKSPACE%\Configs\CustomTemplate\CustomTemplate_Client_LazyLoad
-
-xcopy %CUSTOM_TEMP%\ConfigSystem.cs %WORKSPACE%\UnityProject\Assets\GameScripts\HotFix\GameProto\ConfigSystem.cs /s /e /i /y
-
-%GEN_CLIENT% --template_search_path %CONF_ROOT%\CustomTemplate\CustomTemplate_Client_LazyLoad -j cfg --^
- -d %CONF_ROOT%\Defines\__root__.xml ^
- --input_data_dir %CONF_ROOT%\Excels^
- --output_code_dir %WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig ^
- --output_data_dir %WORKSPACE%/UnityProject/Assets/AssetRaw/Configs/bytes/ ^
- --gen_types data_bin ^
- -s client
-
-%GEN_CLIENT% --template_search_path %CONF_ROOT%\CustomTemplate\CustomTemplate_Client_LazyLoad -j cfg --^
- -d %CONF_ROOT%\Defines\__root__.xml ^
- --input_data_dir %CONF_ROOT%\Excels^
- --output_code_dir %WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig ^
- --output_data_dir ..\GenerateDatas\bidx ^
- --gen_types code_cs_unity_bin,data_bidx ^
- -s client
-
-echo ======== 生成配置文件结束 ========
-set WORKSPACE=..
-
-set "prefix=Idx_"
-
-for %%a in (%DATA_OUTPUT%\bidx\*) do (
- ren "%%a" "Idx_%%~nxa"
-)
-
-echo ======== 所有文件已添加前缀 ========
-
-xcopy %DATA_OUTPUT%\bidx\ %WORKSPACE%\UnityProject\Assets\AssetRaw\Configs\bidx\ /s /e /i /y
-
-pause
\ No newline at end of file
diff --git a/Configs/gen_code_bin_to_project_unitask.bat b/Configs/gen_code_bin_to_project_unitask.bat
deleted file mode 100644
index 4c03d61c..00000000
--- a/Configs/gen_code_bin_to_project_unitask.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-cd /d %~dp0
-set WORKSPACE=..
-
-set GEN_CLIENT=%WORKSPACE%\Tools\Luban.ClientServer\Luban.ClientServer.exe
-set CONF_ROOT=%WORKSPACE%\Configs
-set DATA_OUTPUT=%ROOT_PATH%..\GenerateDatas
-set CUSTOM_TEMP=%WORKSPACE%\Configs\CustomTemplate\CustomTemplate_Client_UniTask
-
-xcopy %CUSTOM_TEMP%\ConfigSystem.cs %WORKSPACE%\UnityProject\Assets\GameScripts\HotFix\GameProto\ConfigSystem.cs /s /e /i /y
-
-%GEN_CLIENT% --template_search_path %CONF_ROOT%\CustomTemplate\CustomTemplate_Client_UniTask -j cfg --^
- -d %CONF_ROOT%\Defines\__root__.xml ^
- --input_data_dir %CONF_ROOT%\Excels^
- --output_code_dir %WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig ^
- --output_data_dir %WORKSPACE%/UnityProject/Assets/AssetRaw/Configs/bytes/ ^
- --gen_types code_cs_unity_bin,data_bin ^
- -s client
-
-echo ======== 生成配置文件结束 ========
-
-pause
\ No newline at end of file
diff --git a/Configs/gen_code_bin_to_server.bat b/Configs/gen_code_bin_to_server.bat
deleted file mode 100644
index 5d01d66b..00000000
--- a/Configs/gen_code_bin_to_server.bat
+++ /dev/null
@@ -1,18 +0,0 @@
-cd /d %~dp0
-set WORKSPACE=..
-
-set GEN_CLIENT=%WORKSPACE%\Tools\Luban.ClientServer\Luban.ClientServer.exe
-set CONF_ROOT=%WORKSPACE%\Configs
-set DATA_OUTPUT=%ROOT_PATH%..\GenerateDatas
-
-%GEN_CLIENT% --template_search_path %CONF_ROOT%\CustomTemplate\CustomTemplate_Server_Task -j cfg --^
- -d %CONF_ROOT%\Defines\__root__.xml ^
- --input_data_dir %CONF_ROOT%\Excels^
- --output_code_dir %WORKSPACE%/DotNet/Logic/src/Config/GameConfig ^
- --output_data_dir ..\DotNet\Config\GameConfig ^
- --gen_types code_cs_bin,data_bin ^
- -s server
-
-echo ======== 生成配置文件结束 ========
-
-pause
\ No newline at end of file
diff --git a/Tools/Luban.ClientServer/about.txt b/Tools/Luban.ClientServer/about.txt
deleted file mode 100644
index 564be2ec..00000000
--- a/Tools/Luban.ClientServer/about.txt
+++ /dev/null
@@ -1 +0,0 @@
-目前使用luban-classic,请自行导入
\ No newline at end of file
diff --git a/Tools/Luban/about.txt b/Tools/Luban/about.txt
new file mode 100644
index 00000000..73d5ea80
--- /dev/null
+++ b/Tools/Luban/about.txt
@@ -0,0 +1 @@
+使用luban-next, 请前往Tools/build-luban编译或者自行导入
\ No newline at end of file
diff --git a/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib.meta b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib.meta
new file mode 100644
index 00000000..f552196a
--- /dev/null
+++ b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 49afb8bbdbfbf014baadbaed2e2bebee
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/BeanBase.cs b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/BeanBase.cs
new file mode 100644
index 00000000..39fc0ec6
--- /dev/null
+++ b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/BeanBase.cs
@@ -0,0 +1,8 @@
+
+namespace Luban
+{
+ public abstract class BeanBase
+ {
+ public abstract int GetTypeId();
+ }
+}
diff --git a/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/BeanBase.cs.meta b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/BeanBase.cs.meta
new file mode 100644
index 00000000..7e53a804
--- /dev/null
+++ b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/BeanBase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 893ae545d065e534bbb7ec9df68e48fe
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ByteBuf.cs b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ByteBuf.cs
new file mode 100644
index 00000000..54b56b13
--- /dev/null
+++ b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ByteBuf.cs
@@ -0,0 +1,1568 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace Luban
+{
+
+ public enum EDeserializeError
+ {
+ OK,
+ NOT_ENOUGH,
+ EXCEED_SIZE,
+ // UNMARSHAL_ERR,
+ }
+
+ public class SerializationException : Exception
+ {
+ public SerializationException() { }
+ public SerializationException(string msg) : base(msg) { }
+
+ public SerializationException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+ }
+
+ public readonly struct SegmentSaveState
+ {
+ public SegmentSaveState(int readerIndex, int writerIndex)
+ {
+ ReaderIndex = readerIndex;
+ WriterIndex = writerIndex;
+ }
+
+ public int ReaderIndex { get; }
+
+ public int WriterIndex { get; }
+ }
+
+ public sealed class ByteBuf : ICloneable, IEquatable
+ {
+ public ByteBuf()
+ {
+ Bytes = Array.Empty();
+ ReaderIndex = WriterIndex = 0;
+ }
+
+ public ByteBuf(int capacity)
+ {
+ Bytes = capacity > 0 ? new byte[capacity] : Array.Empty();
+ ReaderIndex = 0;
+ WriterIndex = 0;
+ }
+
+ public ByteBuf(byte[] bytes)
+ {
+ Bytes = bytes;
+ ReaderIndex = 0;
+ WriterIndex = Capacity;
+ }
+
+ public ByteBuf(byte[] bytes, int readIndex, int writeIndex)
+ {
+ Bytes = bytes;
+ ReaderIndex = readIndex;
+ WriterIndex = writeIndex;
+ }
+
+ public ByteBuf(int capacity, Action releaser) : this(capacity)
+ {
+ _releaser = releaser;
+ }
+
+ public static ByteBuf Wrap(byte[] bytes)
+ {
+ return new ByteBuf(bytes, 0, bytes.Length);
+ }
+
+ public void Replace(byte[] bytes)
+ {
+ Bytes = bytes;
+ ReaderIndex = 0;
+ WriterIndex = Capacity;
+ }
+
+ public void Replace(byte[] bytes, int beginPos, int endPos)
+ {
+ Bytes = bytes;
+ ReaderIndex = beginPos;
+ WriterIndex = endPos;
+ }
+
+ public int ReaderIndex { get; set; }
+
+ public int WriterIndex { get; set; }
+
+ private readonly Action _releaser;
+
+ public int Capacity => Bytes.Length;
+
+ public int Size { get { return WriterIndex - ReaderIndex; } }
+
+ public bool Empty => WriterIndex <= ReaderIndex;
+
+ public bool NotEmpty => WriterIndex > ReaderIndex;
+
+
+ public void AddWriteIndex(int add)
+ {
+ WriterIndex += add;
+ }
+
+ public void AddReadIndex(int add)
+ {
+ ReaderIndex += add;
+ }
+
+#pragma warning disable CA1819 // 属性不应返回数组
+ public byte[] Bytes { get; private set; }
+#pragma warning restore CA1819 // 属性不应返回数组
+
+ public byte[] CopyData()
+ {
+ var n = Remaining;
+ if (n > 0)
+ {
+ var arr = new byte[n];
+ Buffer.BlockCopy(Bytes, ReaderIndex, arr, 0, n);
+ return arr;
+ }
+ else
+ {
+ return Array.Empty();
+ }
+ }
+
+ public int Remaining { get { return WriterIndex - ReaderIndex; } }
+
+ public void DiscardReadBytes()
+ {
+ WriterIndex -= ReaderIndex;
+ Array.Copy(Bytes, ReaderIndex, Bytes, 0, WriterIndex);
+ ReaderIndex = 0;
+ }
+
+ public int NotCompactWritable { get { return Capacity - WriterIndex; } }
+
+ public void WriteBytesWithoutSize(byte[] bs)
+ {
+ WriteBytesWithoutSize(bs, 0, bs.Length);
+ }
+
+ public void WriteBytesWithoutSize(byte[] bs, int offset, int len)
+ {
+ EnsureWrite(len);
+ Buffer.BlockCopy(bs, offset, Bytes, WriterIndex, len);
+ WriterIndex += len;
+ }
+
+ public void Clear()
+ {
+ ReaderIndex = WriterIndex = 0;
+ }
+
+ private const int MIN_CAPACITY = 16;
+
+ private static int PropSize(int initSize, int needSize)
+ {
+ for (int i = Math.Max(initSize, MIN_CAPACITY); ; i <<= 1)
+ {
+ if (i >= needSize)
+ {
+ return i;
+ }
+ }
+ }
+
+ private void EnsureWrite0(int size)
+ {
+ var needSize = WriterIndex + size - ReaderIndex;
+ if (needSize < Capacity)
+ {
+ WriterIndex -= ReaderIndex;
+ Array.Copy(Bytes, ReaderIndex, Bytes, 0, WriterIndex);
+ ReaderIndex = 0;
+ }
+ else
+ {
+ int newCapacity = PropSize(Capacity, needSize);
+ var newBytes = new byte[newCapacity];
+ WriterIndex -= ReaderIndex;
+ Buffer.BlockCopy(Bytes, ReaderIndex, newBytes, 0, WriterIndex);
+ ReaderIndex = 0;
+ Bytes = newBytes;
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void EnsureWrite(int size)
+ {
+ if (WriterIndex + size > Capacity)
+ {
+ EnsureWrite0(size);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void EnsureRead(int size)
+ {
+ if (ReaderIndex + size > WriterIndex)
+ {
+ throw new SerializationException();
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private bool CanRead(int size)
+ {
+ return (ReaderIndex + size <= WriterIndex);
+ }
+
+ public void Append(byte x)
+ {
+ EnsureWrite(1);
+ Bytes[WriterIndex++] = x;
+ }
+
+ public void WriteBool(bool b)
+ {
+ EnsureWrite(1);
+ Bytes[WriterIndex++] = (byte)(b ? 1 : 0);
+ }
+
+ public bool ReadBool()
+ {
+ EnsureRead(1);
+ return Bytes[ReaderIndex++] != 0;
+ }
+
+ public void WriteByte(byte x)
+ {
+ EnsureWrite(1);
+ Bytes[WriterIndex++] = x;
+ }
+
+ public byte ReadByte()
+ {
+ EnsureRead(1);
+ return Bytes[ReaderIndex++];
+ }
+
+
+ public void WriteShort(short x)
+ {
+ if (x >= 0)
+ {
+ if (x < 0x80)
+ {
+ EnsureWrite(1);
+ Bytes[WriterIndex++] = (byte)x;
+ return;
+ }
+ else if (x < 0x4000)
+ {
+ EnsureWrite(2);
+ Bytes[WriterIndex + 1] = (byte)x;
+ Bytes[WriterIndex] = (byte)((x >> 8) | 0x80);
+ WriterIndex += 2;
+ return;
+ }
+ }
+ EnsureWrite(3);
+ Bytes[WriterIndex] = 0xff;
+ Bytes[WriterIndex + 2] = (byte)x;
+ Bytes[WriterIndex + 1] = (byte)(x >> 8);
+ WriterIndex += 3;
+ }
+
+ public short ReadShort()
+ {
+ EnsureRead(1);
+ int h = Bytes[ReaderIndex];
+ if (h < 0x80)
+ {
+ ReaderIndex++;
+ return (short)h;
+ }
+ else if (h < 0xc0)
+ {
+ EnsureRead(2);
+ int x = ((h & 0x3f) << 8) | Bytes[ReaderIndex + 1];
+ ReaderIndex += 2;
+ return (short)x;
+ }
+ else if ((h == 0xff))
+ {
+ EnsureRead(3);
+ int x = (Bytes[ReaderIndex + 1] << 8) | Bytes[ReaderIndex + 2];
+ ReaderIndex += 3;
+ return (short)x;
+ }
+ else
+ {
+ throw new SerializationException();
+ }
+ }
+
+ public short ReadFshort()
+ {
+ EnsureRead(2);
+ short x;
+#if CPU_SUPPORT_MEMORY_NOT_ALIGN
+ unsafe
+ {
+ fixed (byte* b = &Bytes[ReaderIndex])
+ {
+ x = *(short*)b;
+ }
+ }
+#else
+ x = (short)((Bytes[ReaderIndex + 1] << 8) | Bytes[ReaderIndex]);
+
+#endif
+ ReaderIndex += 2;
+ return x;
+ }
+
+ public void WriteFshort(short x)
+ {
+ EnsureWrite(2);
+#if CPU_SUPPORT_MEMORY_NOT_ALIGN
+ unsafe
+ {
+ fixed (byte* b = &Bytes[WriterIndex])
+ {
+ *(short*)b = x;
+ }
+ }
+#else
+ Bytes[WriterIndex] = (byte)x;
+ Bytes[WriterIndex + 1] = (byte)(x >> 8);
+#endif
+ WriterIndex += 2;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void WriteInt(int x)
+ {
+ WriteUint((uint)x);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public int ReadInt()
+ {
+ return (int)ReadUint();
+ }
+
+
+ public void WriteUint(uint x)
+ {
+ // 如果有修改,记得也把 EndWriteSegment改了
+ // 0 111 1111
+ if (x < 0x80)
+ {
+ EnsureWrite(1);
+ Bytes[WriterIndex++] = (byte)x;
+ }
+ else if (x < 0x4000) // 10 11 1111, -
+ {
+ EnsureWrite(2);
+ Bytes[WriterIndex + 1] = (byte)x;
+ Bytes[WriterIndex] = (byte)((x >> 8) | 0x80);
+ WriterIndex += 2;
+ }
+ else if (x < 0x200000) // 110 1 1111, -,-
+ {
+ EnsureWrite(3);
+ Bytes[WriterIndex + 2] = (byte)x;
+ Bytes[WriterIndex + 1] = (byte)(x >> 8);
+ Bytes[WriterIndex] = (byte)((x >> 16) | 0xc0);
+ WriterIndex += 3;
+ }
+ else if (x < 0x10000000) // 1110 1111,-,-,-
+ {
+ EnsureWrite(4);
+ Bytes[WriterIndex + 3] = (byte)x;
+ Bytes[WriterIndex + 2] = (byte)(x >> 8);
+ Bytes[WriterIndex + 1] = (byte)(x >> 16);
+ Bytes[WriterIndex] = (byte)((x >> 24) | 0xe0);
+ WriterIndex += 4;
+ }
+ else
+ {
+ EnsureWrite(5);
+ Bytes[WriterIndex] = 0xf0;
+ Bytes[WriterIndex + 4] = (byte)x;
+ Bytes[WriterIndex + 3] = (byte)(x >> 8);
+ Bytes[WriterIndex + 2] = (byte)(x >> 16);
+ Bytes[WriterIndex + 1] = (byte)(x >> 24);
+ WriterIndex += 5;
+ }
+ }
+
+ public uint ReadUint()
+ {
+ ///
+ /// 警告! 如有修改,记得调整 TryDeserializeInplaceOctets
+ EnsureRead(1);
+ uint h = Bytes[ReaderIndex];
+ if (h < 0x80)
+ {
+ ReaderIndex++;
+ return h;
+ }
+ else if (h < 0xc0)
+ {
+ EnsureRead(2);
+ uint x = ((h & 0x3f) << 8) | Bytes[ReaderIndex + 1];
+ ReaderIndex += 2;
+ return x;
+ }
+ else if (h < 0xe0)
+ {
+ EnsureRead(3);
+ uint x = ((h & 0x1f) << 16) | ((uint)Bytes[ReaderIndex + 1] << 8) | Bytes[ReaderIndex + 2];
+ ReaderIndex += 3;
+ return x;
+ }
+ else if (h < 0xf0)
+ {
+
+ EnsureRead(4);
+ uint x = ((h & 0x0f) << 24) | ((uint)Bytes[ReaderIndex + 1] << 16) | ((uint)Bytes[ReaderIndex + 2] << 8) | Bytes[ReaderIndex + 3];
+ ReaderIndex += 4;
+ return x;
+ }
+ else
+ {
+ EnsureRead(5);
+ uint x = ((uint)Bytes[ReaderIndex + 1] << 24) | ((uint)(Bytes[ReaderIndex + 2] << 16)) | ((uint)Bytes[ReaderIndex + 3] << 8) | Bytes[ReaderIndex + 4];
+ ReaderIndex += 5;
+ return x;
+ }
+ }
+
+ public unsafe void WriteUint_Unsafe(uint x)
+ {
+ // 0 111 1111
+ if (x < 0x80)
+ {
+ EnsureWrite(1);
+ Bytes[WriterIndex++] = (byte)(x << 1);
+ }
+ else if (x < 0x4000)// 10 11 1111, -
+ {
+ EnsureWrite(2);
+
+ fixed (byte* wb = &Bytes[WriterIndex])
+ {
+ *(uint*)(wb) = (x << 2 | 0b01);
+ }
+
+ WriterIndex += 2;
+ }
+ else if (x < 0x200000) // 110 1 1111, -,-
+ {
+ EnsureWrite(3);
+
+ fixed (byte* wb = &Bytes[WriterIndex])
+ {
+ *(uint*)(wb) = (x << 3 | 0b011);
+ }
+ WriterIndex += 3;
+ }
+ else if (x < 0x10000000) // 1110 1111,-,-,-
+ {
+ EnsureWrite(4);
+ fixed (byte* wb = &Bytes[WriterIndex])
+ {
+ *(uint*)(wb) = (x << 4 | 0b0111);
+ }
+ WriterIndex += 4;
+ }
+ else
+ {
+ EnsureWrite(5);
+ fixed (byte* wb = &Bytes[WriterIndex])
+ {
+ *(uint*)(wb) = (x << 5 | 0b01111);
+ }
+ WriterIndex += 5;
+ }
+ }
+
+ public unsafe uint ReadUint_Unsafe()
+ {
+ ///
+ /// 警告! 如有修改,记得调整 TryDeserializeInplaceOctets
+ EnsureRead(1);
+ uint h = Bytes[ReaderIndex];
+ if ((h & 0b1) == 0b0)
+ {
+ ReaderIndex++;
+ return (h >> 1);
+ }
+ else if ((h & 0b11) == 0b01)
+ {
+ EnsureRead(2);
+ fixed (byte* rb = &Bytes[ReaderIndex])
+ {
+ ReaderIndex += 2;
+ return (*(uint*)rb) >> 2;
+ }
+ }
+ else if ((h & 0b111) == 0b011)
+ {
+ EnsureRead(3);
+ fixed (byte* rb = &Bytes[ReaderIndex])
+ {
+ ReaderIndex += 3;
+ return (*(uint*)rb) >> 3;
+ }
+ }
+ else if ((h & 0b1111) == 0b0111)
+ {
+ EnsureRead(4);
+ fixed (byte* rb = &Bytes[ReaderIndex])
+ {
+ ReaderIndex += 4;
+ return (*(uint*)rb) >> 4;
+ }
+ }
+ else
+ {
+ EnsureRead(5);
+ fixed (byte* rb = &Bytes[ReaderIndex])
+ {
+ ReaderIndex += 5;
+ return (*(uint*)rb) >> 5;
+ }
+ }
+ }
+
+ public int ReadFint()
+ {
+ EnsureRead(4);
+ int x;
+#if CPU_SUPPORT_MEMORY_NOT_ALIGN
+ unsafe
+ {
+ fixed (byte* b = &Bytes[ReaderIndex])
+ {
+ x = *(int*)b;
+ }
+ }
+#else
+ x = (Bytes[ReaderIndex + 3] << 24) | (Bytes[ReaderIndex + 2] << 16) | (Bytes[ReaderIndex + 1] << 8) | (Bytes[ReaderIndex]);
+
+#endif
+ ReaderIndex += 4;
+ return x;
+ }
+
+
+ public void WriteFint(int x)
+ {
+ EnsureWrite(4);
+#if CPU_SUPPORT_MEMORY_NOT_ALIGN
+ unsafe
+ {
+ fixed (byte* b = &Bytes[WriterIndex])
+ {
+ *(int*)b = x;
+ }
+ }
+#else
+ Bytes[WriterIndex] = (byte)x;
+ Bytes[WriterIndex + 1] = (byte)(x >> 8);
+ Bytes[WriterIndex + 2] = (byte)(x >> 16);
+ Bytes[WriterIndex + 3] = (byte)(x >> 24);
+#endif
+ WriterIndex += 4;
+ }
+
+ public int ReadFint_Safe()
+ {
+ EnsureRead(4);
+ int x;
+
+ x = (Bytes[ReaderIndex + 3] << 24) | (Bytes[ReaderIndex + 2] << 16) | (Bytes[ReaderIndex + 1] << 8) | (Bytes[ReaderIndex]);
+
+ ReaderIndex += 4;
+ return x;
+ }
+
+
+ public void WriteFint_Safe(int x)
+ {
+ EnsureWrite(4);
+ Bytes[WriterIndex] = (byte)x;
+ Bytes[WriterIndex + 1] = (byte)(x >> 8);
+ Bytes[WriterIndex + 2] = (byte)(x >> 16);
+ Bytes[WriterIndex + 3] = (byte)(x >> 24);
+ WriterIndex += 4;
+ }
+
+ public void WriteLong(long x)
+ {
+ WriteUlong((ulong)x);
+ }
+
+ public long ReadLong()
+ {
+ return (long)ReadUlong();
+ }
+
+ public void WriteNumberAsLong(double x)
+ {
+ WriteLong((long)x);
+ }
+
+ public double ReadLongAsNumber()
+ {
+ return ReadLong();
+ }
+
+ private void WriteUlong(ulong x)
+ {
+ // 0 111 1111
+ if (x < 0x80)
+ {
+ EnsureWrite(1);
+ Bytes[WriterIndex++] = (byte)x;
+ }
+ else if (x < 0x4000) // 10 11 1111, -
+ {
+ EnsureWrite(2);
+ Bytes[WriterIndex + 1] = (byte)x;
+ Bytes[WriterIndex] = (byte)((x >> 8) | 0x80);
+ WriterIndex += 2;
+ }
+ else if (x < 0x200000) // 110 1 1111, -,-
+ {
+ EnsureWrite(3);
+ Bytes[WriterIndex + 2] = (byte)x;
+ Bytes[WriterIndex + 1] = (byte)(x >> 8);
+ Bytes[WriterIndex] = (byte)((x >> 16) | 0xc0);
+ WriterIndex += 3;
+ }
+ else if (x < 0x10000000) // 1110 1111,-,-,-
+ {
+ EnsureWrite(4);
+ Bytes[WriterIndex + 3] = (byte)x;
+ Bytes[WriterIndex + 2] = (byte)(x >> 8);
+ Bytes[WriterIndex + 1] = (byte)(x >> 16);
+ Bytes[WriterIndex] = (byte)((x >> 24) | 0xe0);
+ WriterIndex += 4;
+ }
+ else if (x < 0x800000000L) // 1111 0xxx,-,-,-,-
+ {
+ EnsureWrite(5);
+ Bytes[WriterIndex + 4] = (byte)x;
+ Bytes[WriterIndex + 3] = (byte)(x >> 8);
+ Bytes[WriterIndex + 2] = (byte)(x >> 16);
+ Bytes[WriterIndex + 1] = (byte)(x >> 24);
+ Bytes[WriterIndex] = (byte)((x >> 32) | 0xf0);
+ WriterIndex += 5;
+ }
+ else if (x < 0x40000000000L) // 1111 10xx,
+ {
+ EnsureWrite(6);
+ Bytes[WriterIndex + 5] = (byte)x;
+ Bytes[WriterIndex + 4] = (byte)(x >> 8);
+ Bytes[WriterIndex + 3] = (byte)(x >> 16);
+ Bytes[WriterIndex + 2] = (byte)(x >> 24);
+ Bytes[WriterIndex + 1] = (byte)(x >> 32);
+ Bytes[WriterIndex] = (byte)((x >> 40) | 0xf8);
+ WriterIndex += 6;
+ }
+ else if (x < 0x200000000000L) // 1111 110x,
+ {
+ EnsureWrite(7);
+ Bytes[WriterIndex + 6] = (byte)x;
+ Bytes[WriterIndex + 5] = (byte)(x >> 8);
+ Bytes[WriterIndex + 4] = (byte)(x >> 16);
+ Bytes[WriterIndex + 3] = (byte)(x >> 24);
+ Bytes[WriterIndex + 2] = (byte)(x >> 32);
+ Bytes[WriterIndex + 1] = (byte)(x >> 40);
+ Bytes[WriterIndex] = (byte)((x >> 48) | 0xfc);
+ WriterIndex += 7;
+ }
+ else if (x < 0x100000000000000L) // 1111 1110
+ {
+ EnsureWrite(8);
+ Bytes[WriterIndex + 7] = (byte)x;
+ Bytes[WriterIndex + 6] = (byte)(x >> 8);
+ Bytes[WriterIndex + 5] = (byte)(x >> 16);
+ Bytes[WriterIndex + 4] = (byte)(x >> 24);
+ Bytes[WriterIndex + 3] = (byte)(x >> 32);
+ Bytes[WriterIndex + 2] = (byte)(x >> 40);
+ Bytes[WriterIndex + 1] = (byte)(x >> 48);
+ Bytes[WriterIndex] = 0xfe;
+ WriterIndex += 8;
+ }
+ else // 1111 1111
+ {
+ EnsureWrite(9);
+ Bytes[WriterIndex] = 0xff;
+ Bytes[WriterIndex + 8] = (byte)x;
+ Bytes[WriterIndex + 7] = (byte)(x >> 8);
+ Bytes[WriterIndex + 6] = (byte)(x >> 16);
+ Bytes[WriterIndex + 5] = (byte)(x >> 24);
+ Bytes[WriterIndex + 4] = (byte)(x >> 32);
+ Bytes[WriterIndex + 3] = (byte)(x >> 40);
+ Bytes[WriterIndex + 2] = (byte)(x >> 48);
+ Bytes[WriterIndex + 1] = (byte)(x >> 56);
+ WriterIndex += 9;
+ }
+ }
+
+ public ulong ReadUlong()
+ {
+ EnsureRead(1);
+ uint h = Bytes[ReaderIndex];
+ if (h < 0x80)
+ {
+ ReaderIndex++;
+ return h;
+ }
+ else if (h < 0xc0)
+ {
+ EnsureRead(2);
+ uint x = ((h & 0x3f) << 8) | Bytes[ReaderIndex + 1];
+ ReaderIndex += 2;
+ return x;
+ }
+ else if (h < 0xe0)
+ {
+ EnsureRead(3);
+ uint x = ((h & 0x1f) << 16) | ((uint)Bytes[ReaderIndex + 1] << 8) | Bytes[ReaderIndex + 2];
+ ReaderIndex += 3;
+ return x;
+ }
+ else if (h < 0xf0)
+ {
+ EnsureRead(4);
+ uint x = ((h & 0x0f) << 24) | ((uint)Bytes[ReaderIndex + 1] << 16) | ((uint)Bytes[ReaderIndex + 2] << 8) | Bytes[ReaderIndex + 3];
+ ReaderIndex += 4;
+ return x;
+ }
+ else if (h < 0xf8)
+ {
+ EnsureRead(5);
+ uint xl = ((uint)Bytes[ReaderIndex + 1] << 24) | ((uint)(Bytes[ReaderIndex + 2] << 16)) | ((uint)Bytes[ReaderIndex + 3] << 8) | (Bytes[ReaderIndex + 4]);
+ uint xh = h & 0x07;
+ ReaderIndex += 5;
+ return ((ulong)xh << 32) | xl;
+ }
+ else if (h < 0xfc)
+ {
+ EnsureRead(6);
+ uint xl = ((uint)Bytes[ReaderIndex + 2] << 24) | ((uint)(Bytes[ReaderIndex + 3] << 16)) | ((uint)Bytes[ReaderIndex + 4] << 8) | (Bytes[ReaderIndex + 5]);
+ uint xh = ((h & 0x03) << 8) | Bytes[ReaderIndex + 1];
+ ReaderIndex += 6;
+ return ((ulong)xh << 32) | xl;
+ }
+ else if (h < 0xfe)
+ {
+ EnsureRead(7);
+ uint xl = ((uint)Bytes[ReaderIndex + 3] << 24) | ((uint)(Bytes[ReaderIndex + 4] << 16)) | ((uint)Bytes[ReaderIndex + 5] << 8) | (Bytes[ReaderIndex + 6]);
+ uint xh = ((h & 0x01) << 16) | ((uint)Bytes[ReaderIndex + 1] << 8) | Bytes[ReaderIndex + 2];
+ ReaderIndex += 7;
+ return ((ulong)xh << 32) | xl;
+ }
+ else if (h < 0xff)
+ {
+ EnsureRead(8);
+ uint xl = ((uint)Bytes[ReaderIndex + 4] << 24) | ((uint)(Bytes[ReaderIndex + 5] << 16)) | ((uint)Bytes[ReaderIndex + 6] << 8) | (Bytes[ReaderIndex + 7]);
+ uint xh = /*((h & 0x01) << 24) |*/ ((uint)Bytes[ReaderIndex + 1] << 16) | ((uint)Bytes[ReaderIndex + 2] << 8) | Bytes[ReaderIndex + 3];
+ ReaderIndex += 8;
+ return ((ulong)xh << 32) | xl;
+ }
+ else
+ {
+ EnsureRead(9);
+ uint xl = ((uint)Bytes[ReaderIndex + 5] << 24) | ((uint)(Bytes[ReaderIndex + 6] << 16)) | ((uint)Bytes[ReaderIndex + 7] << 8) | (Bytes[ReaderIndex + 8]);
+ uint xh = ((uint)Bytes[ReaderIndex + 1] << 24) | ((uint)Bytes[ReaderIndex + 2] << 16) | ((uint)Bytes[ReaderIndex + 3] << 8) | Bytes[ReaderIndex + 4];
+ ReaderIndex += 9;
+ return ((ulong)xh << 32) | xl;
+ }
+ }
+
+
+ public void WriteFlong(long x)
+ {
+ EnsureWrite(8);
+#if CPU_SUPPORT_MEMORY_NOT_ALIGN
+ unsafe
+ {
+ fixed (byte* b = &Bytes[WriterIndex])
+ {
+ *(long*)b = x;
+ }
+ }
+#else
+
+ Bytes[WriterIndex] = (byte)x;
+ Bytes[WriterIndex + 1] = (byte)(x >> 8);
+ Bytes[WriterIndex + 2] = (byte)(x >> 16);
+ Bytes[WriterIndex + 3] = (byte)(x >> 24);
+ Bytes[WriterIndex + 4] = (byte)(x >> 32);
+ Bytes[WriterIndex + 5] = (byte)(x >> 40);
+ Bytes[WriterIndex + 6] = (byte)(x >> 48);
+ Bytes[WriterIndex + 7] = (byte)(x >> 56);
+#endif
+ WriterIndex += 8;
+ }
+
+ public long ReadFlong()
+ {
+ EnsureRead(8);
+ long x;
+#if CPU_SUPPORT_MEMORY_NOT_ALIGN
+ unsafe
+ {
+ fixed (byte* b = &Bytes[ReaderIndex])
+ {
+ x = *(long*)b;
+ }
+ }
+#else
+ int xl = (Bytes[ReaderIndex + 3] << 24) | ((Bytes[ReaderIndex + 2] << 16)) | (Bytes[ReaderIndex + 1] << 8) | (Bytes[ReaderIndex]);
+ int xh = (Bytes[ReaderIndex + 7] << 24) | (Bytes[ReaderIndex + 6] << 16) | (Bytes[ReaderIndex + 5] << 8) | Bytes[ReaderIndex + 4];
+ x = ((long)xh << 32) | (long)xl;
+#endif
+ ReaderIndex += 8;
+ return x;
+ }
+
+ private static unsafe void Copy8(byte* dst, byte* src)
+ {
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst[3] = src[3];
+ dst[4] = src[4];
+ dst[5] = src[5];
+ dst[6] = src[6];
+ dst[7] = src[7];
+ }
+
+ private static unsafe void Copy4(byte* dst, byte* src)
+ {
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst[3] = src[3];
+ }
+
+
+ //const bool isLittleEndian = true;
+ public void WriteFloat(float x)
+ {
+ EnsureWrite(4);
+ unsafe
+ {
+ fixed (byte* b = &Bytes[WriterIndex])
+ {
+#if !CPU_SUPPORT_MEMORY_NOT_ALIGN
+ if ((long)b % 4 == 0)
+ {
+ *(float*)b = x;
+ }
+ else
+ {
+ Copy4(b, (byte*)&x);
+ }
+#else
+ *(float*)b = x;
+#endif
+ }
+ }
+
+ //if (!BitConverter.IsLittleEndian)
+ //{
+ // Array.Reverse(data, endPos, 4);
+ //}
+ WriterIndex += 4;
+ }
+
+ public float ReadFloat()
+ {
+ EnsureRead(4);
+ //if (!BitConverter.IsLittleEndian)
+ //{
+ // Array.Reverse(data, beginPos, 4);
+ //}
+ float x;
+ unsafe
+ {
+ fixed (byte* b = &Bytes[ReaderIndex])
+ {
+#if !CPU_SUPPORT_MEMORY_NOT_ALIGN
+ if ((long)b % 4 == 0)
+ {
+ x = *(float*)b;
+ }
+ else
+ {
+ *((int*)&x) = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
+ }
+#else
+ x = *(float*)b;
+#endif
+ }
+ }
+
+ ReaderIndex += 4;
+ return x;
+ }
+
+ public void WriteDouble(double x)
+ {
+ EnsureWrite(8);
+ unsafe
+ {
+ fixed (byte* b = &Bytes[WriterIndex])
+ {
+#if !CPU_SUPPORT_MEMORY_NOT_ALIGN
+ if ((long)b % 8 == 0)
+ {
+ *(double*)b = x;
+ }
+ else
+ {
+ Copy8(b, (byte*)&x);
+ }
+#else
+ *(double*)b = x;
+#endif
+ }
+ //if (!BitConverter.IsLittleEndian)
+ //{
+ // Array.Reverse(data, endPos, 8);
+ //}
+ }
+
+ WriterIndex += 8;
+ }
+
+ public double ReadDouble()
+ {
+ EnsureRead(8);
+ //if (!BitConverter.IsLittleEndian)
+ //{
+ // Array.Reverse(data, beginPos, 8);
+ //}
+ double x;
+ unsafe
+ {
+ fixed (byte* b = &Bytes[ReaderIndex])
+ {
+#if !CPU_SUPPORT_MEMORY_NOT_ALIGN
+ if ((long)b % 8 == 0)
+ {
+ x = *(double*)b;
+ }
+ else
+ {
+ int low = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
+ int high = (b[4]) | (b[5] << 8) | (b[6] << 16) | (b[7] << 24);
+ *((long*)&x) = ((long)high << 32) | (uint)low;
+ }
+#else
+ x = *(double*)b;
+#endif
+ }
+ }
+
+ ReaderIndex += 8;
+ return x;
+ }
+
+ public void WriteSize(int n)
+ {
+ WriteUint((uint)n);
+ }
+
+ public int ReadSize()
+ {
+ return (int)ReadUint();
+ }
+
+ // marshal int
+ // n -> (n << 1) ^ (n >> 31)
+ // Read
+ // (x >>> 1) ^ ((x << 31) >> 31)
+ // (x >>> 1) ^ -(n&1)
+ public void WriteSint(int x)
+ {
+ WriteUint(((uint)x << 1) ^ ((uint)x >> 31));
+ }
+
+ public int ReadSint()
+ {
+ uint x = ReadUint();
+ return (int)((x >> 1) ^ ((x & 1) << 31));
+ }
+
+
+ // marshal long
+ // n -> (n << 1) ^ (n >> 63)
+ // Read
+ // (x >>> 1) ^((x << 63) >> 63)
+ // (x >>> 1) ^ -(n&1L)
+ public void WriteSlong(long x)
+ {
+ WriteUlong(((ulong)x << 1) ^ ((ulong)x >> 63));
+ }
+
+ public long ReadSlong()
+ {
+ long x = ReadLong();
+ return ((long)((ulong)x >> 1) ^ ((x & 1) << 63));
+ }
+
+ public void WriteString(string x)
+ {
+ var n = x != null ? Encoding.UTF8.GetByteCount(x) : 0;
+ WriteSize(n);
+ if (n > 0)
+ {
+ EnsureWrite(n);
+ Encoding.UTF8.GetBytes(x, 0, x.Length, Bytes, WriterIndex);
+ WriterIndex += n;
+ }
+ }
+
+ // byte[], [start, end)
+ public static Func StringCacheFinder { get; set; }
+
+ public string ReadString()
+ {
+ var n = ReadSize();
+ if (n > 0)
+ {
+ EnsureRead(n);
+ string s;
+
+ if (StringCacheFinder == null)
+ {
+ s = Encoding.UTF8.GetString(Bytes, ReaderIndex, n);
+ }
+ else
+ {
+ // 只缓存比较小的字符串
+ s = StringCacheFinder(Bytes, ReaderIndex, n);
+ }
+ ReaderIndex += n;
+ return s;
+ }
+ else
+ {
+ return string.Empty;
+ }
+ }
+
+ public void WriteBytes(byte[] x)
+ {
+ var n = x != null ? x.Length : 0;
+ WriteSize(n);
+ if (n > 0)
+ {
+ EnsureWrite(n);
+ x.CopyTo(Bytes, WriterIndex);
+ WriterIndex += n;
+ }
+ }
+
+ public byte[] ReadBytes()
+ {
+ var n = ReadSize();
+ if (n > 0)
+ {
+ EnsureRead(n);
+ var x = new byte[n];
+ Buffer.BlockCopy(Bytes, ReaderIndex, x, 0, n);
+ ReaderIndex += n;
+ return x;
+ }
+ else
+ {
+ return Array.Empty();
+ }
+ }
+
+ // 以下是一些特殊类型
+
+ public void WriteComplex(Complex x)
+ {
+ WriteDouble(x.Real);
+ WriteDouble(x.Imaginary);
+ }
+
+ public Complex ReadComplex()
+ {
+ var x = ReadDouble();
+ var y = ReadDouble();
+ return new Complex(x, y);
+ }
+
+ public void WriteVector2(Vector2 x)
+ {
+ WriteFloat(x.X);
+ WriteFloat(x.Y);
+ }
+
+ public Vector2 ReadVector2()
+ {
+ float x = ReadFloat();
+ float y = ReadFloat();
+ return new Vector2(x, y);
+ }
+
+ public void WriteVector3(Vector3 x)
+ {
+ WriteFloat(x.X);
+ WriteFloat(x.Y);
+ WriteFloat(x.Z);
+ }
+
+ public Vector3 ReadVector3()
+ {
+ float x = ReadFloat();
+ float y = ReadFloat();
+ float z = ReadFloat();
+ return new Vector3(x, y, z);
+ }
+
+ public void WriteVector4(Vector4 x)
+ {
+ WriteFloat(x.X);
+ WriteFloat(x.Y);
+ WriteFloat(x.Z);
+ WriteFloat(x.W);
+ }
+
+ public Vector4 ReadVector4()
+ {
+ float x = ReadFloat();
+ float y = ReadFloat();
+ float z = ReadFloat();
+ float w = ReadFloat();
+ return new Vector4(x, y, z, w);
+ }
+
+
+ public void WriteQuaternion(Quaternion x)
+ {
+ WriteFloat(x.X);
+ WriteFloat(x.Y);
+ WriteFloat(x.Z);
+ WriteFloat(x.W);
+ }
+
+ public Quaternion ReadQuaternion()
+ {
+ float x = ReadFloat();
+ float y = ReadFloat();
+ float z = ReadFloat();
+ float w = ReadFloat();
+ return new Quaternion(x, y, z, w);
+ }
+
+
+ public void WriteMatrix4x4(Matrix4x4 x)
+ {
+ WriteFloat(x.M11);
+ WriteFloat(x.M12);
+ WriteFloat(x.M13);
+ WriteFloat(x.M14);
+ WriteFloat(x.M21);
+ WriteFloat(x.M22);
+ WriteFloat(x.M23);
+ WriteFloat(x.M24);
+ WriteFloat(x.M31);
+ WriteFloat(x.M32);
+ WriteFloat(x.M33);
+ WriteFloat(x.M34);
+ WriteFloat(x.M41);
+ WriteFloat(x.M42);
+ WriteFloat(x.M43);
+ WriteFloat(x.M44);
+ }
+
+ public Matrix4x4 ReadMatrix4x4()
+ {
+ float m11 = ReadFloat();
+ float m12 = ReadFloat();
+ float m13 = ReadFloat();
+ float m14 = ReadFloat();
+ float m21 = ReadFloat();
+ float m22 = ReadFloat();
+ float m23 = ReadFloat();
+ float m24 = ReadFloat();
+ float m31 = ReadFloat();
+ float m32 = ReadFloat();
+ float m33 = ReadFloat();
+ float m34 = ReadFloat();
+ float m41 = ReadFloat();
+ float m42 = ReadFloat();
+ float m43 = ReadFloat();
+ float m44 = ReadFloat();
+ return new Matrix4x4(m11, m12, m13, m14,
+ m21, m22, m23, m24,
+ m31, m32, m33, m34,
+ m41, m42, m43, m44);
+ }
+
+ internal void SkipBytes()
+ {
+ int n = ReadSize();
+ EnsureRead(n);
+ ReaderIndex += n;
+ }
+
+
+ public void WriteByteBufWithSize(ByteBuf o)
+ {
+ int n = o.Size;
+ if (n > 0)
+ {
+ WriteSize(n);
+ WriteBytesWithoutSize(o.Bytes, o.ReaderIndex, n);
+ }
+ else
+ {
+ WriteByte(0);
+ }
+ }
+
+ public void WriteByteBufWithoutSize(ByteBuf o)
+ {
+ int n = o.Size;
+ if (n > 0)
+ {
+ WriteBytesWithoutSize(o.Bytes, o.ReaderIndex, n);
+ }
+ }
+
+ public bool TryReadByte(out byte x)
+ {
+ if (CanRead(1))
+ {
+ x = Bytes[ReaderIndex++];
+ return true;
+ }
+ else
+ {
+ x = 0;
+ return false;
+ }
+ }
+
+ public EDeserializeError TryDeserializeInplaceByteBuf(int maxSize, ByteBuf inplaceTempBody)
+ {
+ //if (!CanRead(1)) { return EDeserializeError.NOT_ENOUGH; }
+ int oldReadIndex = ReaderIndex;
+ bool commit = false;
+ try
+ {
+ int n;
+ int h = Bytes[ReaderIndex];
+ if (h < 0x80)
+ {
+ ReaderIndex++;
+ n = h;
+ }
+ else if (h < 0xc0)
+ {
+ if (!CanRead(2)) { return EDeserializeError.NOT_ENOUGH; }
+ n = ((h & 0x3f) << 8) | Bytes[ReaderIndex + 1];
+ ReaderIndex += 2;
+ }
+ else if (h < 0xe0)
+ {
+ if (!CanRead(3)) { return EDeserializeError.NOT_ENOUGH; }
+ n = ((h & 0x1f) << 16) | (Bytes[ReaderIndex + 1] << 8) | Bytes[ReaderIndex + 2];
+ ReaderIndex += 3;
+ }
+ else if (h < 0xf0)
+ {
+ if (!CanRead(4)) { return EDeserializeError.NOT_ENOUGH; }
+ n = ((h & 0x0f) << 24) | (Bytes[ReaderIndex + 1] << 16) | (Bytes[ReaderIndex + 2] << 8) | Bytes[ReaderIndex + 3];
+ ReaderIndex += 4;
+ }
+ else
+ {
+ return EDeserializeError.EXCEED_SIZE;
+ }
+
+ if (n > maxSize)
+ {
+ return EDeserializeError.EXCEED_SIZE;
+ }
+ if (Remaining < n)
+ {
+ return EDeserializeError.NOT_ENOUGH;
+ }
+
+ int inplaceReadIndex = ReaderIndex;
+ ReaderIndex += n;
+
+ inplaceTempBody.Replace(Bytes, inplaceReadIndex, ReaderIndex);
+ commit = true;
+ }
+ finally
+ {
+ if (!commit)
+ {
+ ReaderIndex = oldReadIndex;
+ }
+ }
+
+ return EDeserializeError.OK;
+ }
+
+ public void WriteRawTag(byte b1)
+ {
+ EnsureWrite(1);
+ Bytes[WriterIndex++] = b1;
+ }
+
+ public void WriteRawTag(byte b1, byte b2)
+ {
+ EnsureWrite(2);
+ Bytes[WriterIndex] = b1;
+ Bytes[WriterIndex + 1] = b2;
+ WriterIndex += 2;
+ }
+
+ public void WriteRawTag(byte b1, byte b2, byte b3)
+ {
+ EnsureWrite(3);
+ Bytes[WriterIndex] = b1;
+ Bytes[WriterIndex + 1] = b2;
+ Bytes[WriterIndex + 2] = b3;
+ WriterIndex += 3;
+ }
+
+ #region segment
+
+
+ public void BeginWriteSegment(out int oldSize)
+ {
+ oldSize = Size;
+ EnsureWrite(1);
+ WriterIndex += 1;
+ }
+
+ public void EndWriteSegment(int oldSize)
+ {
+ int startPos = ReaderIndex + oldSize;
+ int segmentSize = WriterIndex - startPos - 1;
+
+ // 0 111 1111
+ if (segmentSize < 0x80)
+ {
+ Bytes[startPos] = (byte)segmentSize;
+ }
+ else if (segmentSize < 0x4000) // 10 11 1111, -
+ {
+ EnsureWrite(1);
+ Bytes[WriterIndex] = Bytes[startPos + 1];
+ Bytes[startPos + 1] = (byte)segmentSize;
+
+ Bytes[startPos] = (byte)((segmentSize >> 8) | 0x80);
+ WriterIndex += 1;
+ }
+ else if (segmentSize < 0x200000) // 110 1 1111, -,-
+ {
+ EnsureWrite(2);
+ Bytes[WriterIndex + 1] = Bytes[startPos + 2];
+ Bytes[startPos + 2] = (byte)segmentSize;
+
+ Bytes[WriterIndex] = Bytes[startPos + 1];
+ Bytes[startPos + 1] = (byte)(segmentSize >> 8);
+
+ Bytes[startPos] = (byte)((segmentSize >> 16) | 0xc0);
+ WriterIndex += 2;
+ }
+ else if (segmentSize < 0x10000000) // 1110 1111,-,-,-
+ {
+ EnsureWrite(3);
+ Bytes[WriterIndex + 2] = Bytes[startPos + 3];
+ Bytes[startPos + 3] = (byte)segmentSize;
+
+ Bytes[WriterIndex + 1] = Bytes[startPos + 2];
+ Bytes[startPos + 2] = (byte)(segmentSize >> 8);
+
+ Bytes[WriterIndex] = Bytes[startPos + 1];
+ Bytes[startPos + 1] = (byte)(segmentSize >> 16);
+
+ Bytes[startPos] = (byte)((segmentSize >> 24) | 0xe0);
+ WriterIndex += 3;
+ }
+ else
+ {
+ throw new SerializationException("exceed max segment size");
+ }
+ }
+
+ public void ReadSegment(out int startIndex, out int segmentSize)
+ {
+ EnsureRead(1);
+ int h = Bytes[ReaderIndex++];
+
+ startIndex = ReaderIndex;
+
+ if (h < 0x80)
+ {
+ segmentSize = h;
+ ReaderIndex += segmentSize;
+ }
+ else if (h < 0xc0)
+ {
+ EnsureRead(1);
+ segmentSize = ((h & 0x3f) << 8) | Bytes[ReaderIndex];
+ int endPos = ReaderIndex + segmentSize;
+ Bytes[ReaderIndex] = Bytes[endPos];
+ ReaderIndex += segmentSize + 1;
+ }
+ else if (h < 0xe0)
+ {
+ EnsureRead(2);
+ segmentSize = ((h & 0x1f) << 16) | ((int)Bytes[ReaderIndex] << 8) | Bytes[ReaderIndex + 1];
+ int endPos = ReaderIndex + segmentSize;
+ Bytes[ReaderIndex] = Bytes[endPos];
+ Bytes[ReaderIndex + 1] = Bytes[endPos + 1];
+ ReaderIndex += segmentSize + 2;
+ }
+ else if (h < 0xf0)
+ {
+ EnsureRead(3);
+ segmentSize = ((h & 0x0f) << 24) | ((int)Bytes[ReaderIndex] << 16) | ((int)Bytes[ReaderIndex + 1] << 8) | Bytes[ReaderIndex + 2];
+ int endPos = ReaderIndex + segmentSize;
+ Bytes[ReaderIndex] = Bytes[endPos];
+ Bytes[ReaderIndex + 1] = Bytes[endPos + 1];
+ Bytes[ReaderIndex + 2] = Bytes[endPos + 2];
+ ReaderIndex += segmentSize + 3;
+ }
+ else
+ {
+ throw new SerializationException("exceed max size");
+ }
+ if (ReaderIndex > WriterIndex)
+ {
+ throw new SerializationException("segment data not enough");
+ }
+ }
+
+ public void ReadSegment(ByteBuf buf)
+ {
+ ReadSegment(out int startPos, out var size);
+ buf.Bytes = Bytes;
+ buf.ReaderIndex = startPos;
+ buf.WriterIndex = startPos + size;
+ }
+
+ public void EnterSegment(out SegmentSaveState saveState)
+ {
+ ReadSegment(out int startPos, out int size);
+
+ saveState = new SegmentSaveState(ReaderIndex, WriterIndex);
+ ReaderIndex = startPos;
+ WriterIndex = startPos + size;
+ }
+
+ public void LeaveSegment(SegmentSaveState saveState)
+ {
+ ReaderIndex = saveState.ReaderIndex;
+ WriterIndex = saveState.WriterIndex;
+ }
+
+ #endregion
+
+ public override string ToString()
+ {
+ string[] datas = new string[WriterIndex - ReaderIndex];
+ for (var i = ReaderIndex; i < WriterIndex; i++)
+ {
+ datas[i - ReaderIndex] = Bytes[i].ToString("X2");
+ }
+ return string.Join(".", datas);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return (obj is ByteBuf other) && Equals(other);
+ }
+
+ public bool Equals(ByteBuf other)
+ {
+ if (other == null)
+ {
+ return false;
+ }
+ if (Size != other.Size)
+ {
+ return false;
+ }
+ for (int i = 0, n = Size; i < n; i++)
+ {
+ if (Bytes[ReaderIndex + i] != other.Bytes[other.ReaderIndex + i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public object Clone()
+ {
+ return new ByteBuf(CopyData());
+ }
+
+
+ public static ByteBuf FromString(string value)
+ {
+ var ss = value.Split(',');
+ byte[] data = new byte[ss.Length];
+ for (int i = 0; i < data.Length; i++)
+ {
+ data[i] = byte.Parse(ss[i]);
+ }
+ return new ByteBuf(data);
+ }
+
+ public override int GetHashCode()
+ {
+ int hash = 17;
+ for (int i = ReaderIndex; i < WriterIndex; i++)
+ {
+ hash = hash * 23 + Bytes[i];
+ }
+ return hash;
+ }
+
+ public void Release()
+ {
+ _releaser?.Invoke(this);
+ }
+
+#if SUPPORT_PUERTS_ARRAYBUF
+ // -- add for puerts
+ public Puerts.ArrayBuffer ReadArrayBuffer()
+ {
+ return new Puerts.ArrayBuffer(ReadBytes());
+ }
+
+ public void WriteArrayBuffer(Puerts.ArrayBuffer bytes)
+ {
+ WriteBytes(bytes.Bytes);
+ }
+#endif
+ }
+}
diff --git a/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ByteBuf.cs.meta b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ByteBuf.cs.meta
new file mode 100644
index 00000000..6dc268c7
--- /dev/null
+++ b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ByteBuf.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4e75cc385e3ba2a4a928b3beb7f69b13
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ITypeId.cs b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ITypeId.cs
new file mode 100644
index 00000000..3ea44b39
--- /dev/null
+++ b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ITypeId.cs
@@ -0,0 +1,7 @@
+namespace Luban
+{
+ public interface ITypeId
+ {
+ int GetTypeId();
+ }
+}
diff --git a/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ITypeId.cs.meta b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ITypeId.cs.meta
new file mode 100644
index 00000000..3a62aa1d
--- /dev/null
+++ b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/ITypeId.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 09af473d0f77f7f43ba793fc8c3996a0
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/StringUtil.cs b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/StringUtil.cs
new file mode 100644
index 00000000..0648ffcc
--- /dev/null
+++ b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/StringUtil.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Text;
+
+namespace Luban
+{
+ public static class StringUtil
+ {
+ public static string ToStr(object o)
+ {
+ return ToStr(o, new StringBuilder());
+ }
+
+ public static string ToStr(object o, StringBuilder sb)
+ {
+ foreach (var p in o.GetType().GetFields())
+ {
+
+ sb.Append($"{p.Name} = {p.GetValue(o)},");
+ }
+
+ foreach (var p in o.GetType().GetProperties())
+ {
+ sb.Append($"{p.Name} = {p.GetValue(o)},");
+ }
+ return sb.ToString();
+ }
+
+ public static string ArrayToString(T[] arr)
+ {
+ return "[" + string.Join(",", arr) + "]";
+ }
+
+
+ public static string CollectionToString(IEnumerable arr)
+ {
+ return "[" + string.Join(",", arr) + "]";
+ }
+
+
+ public static string CollectionToString(IDictionary dic)
+ {
+ var sb = new StringBuilder('{');
+ foreach (var e in dic)
+ {
+ sb.Append(e.Key).Append(':');
+ sb.Append(e.Value).Append(',');
+ }
+ sb.Append('}');
+ return sb.ToString();
+ }
+ }
+}
diff --git a/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/StringUtil.cs.meta b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/StringUtil.cs.meta
new file mode 100644
index 00000000..ab6f41a5
--- /dev/null
+++ b/UnityProject/Assets/GameScripts/HotFix/GameProto/LubanLib/StringUtil.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 353da197a63f6004ba2cbd8751e717bf
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/UnityProject/Assets/TEngine/Runtime/Libraries/LubanLib.dll b/UnityProject/Assets/TEngine/Runtime/Libraries/LubanLib.dll
deleted file mode 100644
index b8cddc1b..00000000
Binary files a/UnityProject/Assets/TEngine/Runtime/Libraries/LubanLib.dll and /dev/null differ
diff --git a/UnityProject/Assets/TEngine/Runtime/Libraries/LubanLib.dll.meta b/UnityProject/Assets/TEngine/Runtime/Libraries/LubanLib.dll.meta
deleted file mode 100644
index 30684824..00000000
--- a/UnityProject/Assets/TEngine/Runtime/Libraries/LubanLib.dll.meta
+++ /dev/null
@@ -1,33 +0,0 @@
-fileFormatVersion: 2
-guid: 03804aac55906c846a647bfd1e0b7eca
-PluginImporter:
- externalObjects: {}
- serializedVersion: 2
- iconMap: {}
- executionOrder: {}
- defineConstraints: []
- isPreloaded: 0
- isOverridable: 0
- isExplicitlyReferenced: 0
- validateReferences: 1
- platformData:
- - first:
- Any:
- second:
- enabled: 1
- settings: {}
- - first:
- Editor: Editor
- second:
- enabled: 0
- settings:
- DefaultValueInitialized: true
- - first:
- Windows Store Apps: WindowsStoreApps
- second:
- enabled: 0
- settings:
- CPU: AnyCPU
- userData:
- assetBundleName:
- assetBundleVariant: