diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d9b4e5d..0000000 --- a/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -# Specify filepatterns you want git to ignore. -obj/ -Bin/ -bin/ -Temp/ -Library/ -Logs/ -temp/ -DocFx/ -global.json - -# 项目素材 -ResLibrary/ -# Unity项目文件 -examples/**/Unity/*.sln -examples/**/Unity/*.csproj -examples/**/Unity/.vsconfig - -# Client-Unity -HybridCLRData/ -AssetBundles/ -UserSettings/ -# 忽略Packages.Unity包下的.meta -Packages.Unity/**/*.meta - - -# Other -.idea -.vs -.vscode -*.DS_Store -# 不排除示例项目的.vscode -!examples/**/.vscode -!Tools/**/.vscode -examples/**/Unity/.vscode diff --git a/.idea/.idea.Server/.idea/.gitignore b/.idea/.idea.Server/.idea/.gitignore new file mode 100644 index 0000000..52325c1 --- /dev/null +++ b/.idea/.idea.Server/.idea/.gitignore @@ -0,0 +1,13 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# Rider 忽略的文件 +/.idea.Server.iml +/modules.xml +/projectSettingsUpdater.xml +/contentModel.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.Server/.idea/indexLayout.xml b/.idea/.idea.Server/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.Server/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Config/private_key.pem b/Config/private_key.pem deleted file mode 100644 index 8e1c59b..0000000 --- a/Config/private_key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPgvJvOMVwyzhw -CjMXpmuopnsiPVt5OCAlYa4u32MxLbQ/hzGWt5BEnJtrzlHRzgI20Z5pNtco6w5R -JU26y+RixmcNp28kWIVmHKA457HiexdamnThdDVGjsTZ98BZHQNWAdmlR0AWjyaF -Se0w/7qBDLgebn+OENxKfga10i7jVgVfwtomTDBwFl2dDwL+rYVxrt7iWFtAvJ6b -aV9UAjmNXvy/MH9pIBUOAJ6mvDkq/wNSTTrBX1Kun/M7axoheaZ5fDbdLrHnOEew -LAjsncRl1+XXwEbhHa7UQk4qa7DJhUQkx61CT2WS1+q45g2Z0N5Caop+CpVZPWBd -yNkLbedNAgMBAAECggEAM7LwYxjeCfK7giBsZ8NA1cD6cwad3FbJHX8XVhq2HAnC -u0QbrOzZTtrElwiNVmvQnec+JADzfICJbdqRIc2L/jbndF2nYUMDozPVEDBbX21i -3WIXZhcdcdF+hj6FJ76EdwBZgOW+OBCcnH8VTsybouywD3bgpRyawZ1h3xk5MM5p -udZBTv6pHJu4KDCWBziWyLFAFOd2u9NgaRxeHbpq09AvwHyjXK5bKTwOCWFNW9mj -FHGo0Pk7hYeYVGa3HktIQ3oAiMiyKLdeB/4SZc35RH6wWGOhLi1jqDgAKuTzVMt+ -jDWh6ozggEVx8NCrEWtZpSsxlBhWDfxzZd1lFOwMAQKBgQD4KaybHNCPLmJhg8fS -J5MhJZBEfyE5fenrMjftLI7c4wo805idggk8c6mBERstYjLPg+hDnjoQHZmy8i0I -MLfebH2ts+tqyx12gmKC7zRjNfEBW3QjH8mH5Lq0bF9cPrZj7AVDpzxCAuB9xGfn -WwvuNdcx1cWGgAl5zE5CcfvbTQKBgQDWEJ5kHRH39tXbz0Mqbj3CXKsCskZvqSGt -4WH35Jx7lZV1iIU/IL+mmQcZLALczOTRuN0Vq3LcyoZSaS/3d3OQEsKKYzJGZNOg -nqtS4v2sO/ywSBpduw5cQfZrmOk3x4v1CTzsx6IhCCZFR5S9kWrnqSCVzdtvasnV -z3zq3Dw8AQKBgQCaXGnGDhVYipSdbXgUq5MkEhZ71MwY0852AsWw3H98vCi5DzEm -ACW4mYU9CCPsheFvHPCTZs9dCNx655LFPnCQhNFkA78SrYcFGTMnmJzwfTQNERLb -akFUKx1LbwGeAlA3NS9NFrAvq1RyRoIO8Z4pLQpPMFZuRCQgw8mGIRp1HQKBgQCc -EW+5Y+xm0cKnyJuagtdqLi/L/ngWDsRsRmcr2bQw8iUOlOM43EJ+TxF6y7imjIfD -U7l0hBRxXwLBcMk07hUGFHdbd+j+o6Ibd7NG8hGqke2wBFGcxrU4lCr51XkrXsPu -eba+lunglVV5qy+Jakz76zXDolt7ButyhBz6CmmsAQKBgHVDjpIGsyojxq19OtLm -xm3GuK2/+9VruRJ9B4yX2uwj2+x53rCxV6zWkBDMJtjyUjb7epz4xkau73KYoncR -B9om+4Nmo+R/p3ACgGjMDoaadyUD1hVM4R+d4VqNv3Ck7YPd/Ehiz3uZRD4njo8D -w7xwwzHNjgpL5+xeiMsaUOL9 ------END PRIVATE KEY----- diff --git a/Config/public_key.pem b/Config/public_key.pem deleted file mode 100644 index 8c2fea3..0000000 --- a/Config/public_key.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz4LybzjFcMs4cAozF6Zr -qKZ7Ij1beTggJWGuLt9jMS20P4cxlreQRJyba85R0c4CNtGeaTbXKOsOUSVNusvk -YsZnDadvJFiFZhygOOex4nsXWpp04XQ1Ro7E2ffAWR0DVgHZpUdAFo8mhUntMP+6 -gQy4Hm5/jhDcSn4GtdIu41YFX8LaJkwwcBZdnQ8C/q2Fca7e4lhbQLyem2lfVAI5 -jV78vzB/aSAVDgCeprw5Kv8DUk06wV9Srp/zO2saIXmmeXw23S6x5zhHsCwI7J3E -Zdfl18BG4R2u1EJOKmuwyYVEJMetQk9lktfquOYNmdDeQmqKfgqVWT1gXcjZC23n -TQIDAQAB ------END PUBLIC KEY----- diff --git a/Config/密钥20250805230750/应用公钥RSA2048.txt b/Config/密钥20250805230750/应用公钥RSA2048.txt deleted file mode 100644 index 687589b..0000000 --- a/Config/密钥20250805230750/应用公钥RSA2048.txt +++ /dev/null @@ -1 +0,0 @@ -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6EL7hSzceNVL5NFa8HLhtqvxEUHSVh8ChDRhHmltDyZ7pdsesiOBPS2lU++LztOrwNv4Q4KyUnoJ2OPHZAObaZyxXMW89SDJo8hkfx7mgPxhCtLxazcnBBoq+FVEbV24hRlYYpXpEkc2gAu7EmnphnCLpsMLn1WP2d+URxCNbHxy8IKD6Cl9NErKTgbmm5AB0bL+fd2vtxH/u3rVPBHM7Cu3rO37NjsUdY62nE88+IBp6jLT099F7ixz2mVqFeCvubnWv8vowl0Sj9zOhx+xz+h9UjysnJA0fPK6xl0s2ArGfGmNJNHQncAPxDj8t7t4/8oJr4oBiYrw4TChMikmwIDAQAB \ No newline at end of file diff --git a/Config/密钥20250805230750/应用私钥RSA2048-敏感数据,请妥善保管.txt b/Config/密钥20250805230750/应用私钥RSA2048-敏感数据,请妥善保管.txt deleted file mode 100644 index 98577a5..0000000 --- a/Config/密钥20250805230750/应用私钥RSA2048-敏感数据,请妥善保管.txt +++ /dev/null @@ -1 +0,0 @@ -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCPoQvuFLNx41Uvk0VrwcuG2q/ERQdJWHwKENGEeaW0PJnul2x6yI4E9LaVT74vO06vA2/hDgrJSegnY48dkA5tpnLFcxbz1IMmjyGR/HuaA/GEK0vFrNycEGir4VURtXbiFGVhilekSRzaAC7sSaemGcIumwwufVY/Z35RHEI1sfHLwgoPoKX00SspOBuabkAHRsv593a+3Ef+7etU8EczsK7es7fs2OxR1jracTzz4gGnqMtPT30XuLHPaZWoV4K+5uda/y+jCXRKP3M6HH7HP6H1SPKyckDR88rrGXSzYCsZ8aY0k0dCdwA/EOPy3u3j/ygmvigGJivDhMKEyKSbAgMBAAECggEAdMsUlGko8jdWEfXDwbg49FPoEcXAAxh85QKAHSV+ZW3SDn37rGxhcA4+WnQZxvaHKTG2TF/KzZvXuA/xVKzLzsZHFeBcjbIFY9mIBto0+Cy0vDEo0Hmcexuswffd4SSao4TKW+LPGbyKRYtYnLPYK+1ORe+2nCc3dx+FTBeaj2X9d1d4f1PsdvNrPEkNz+p+dhY/g9Gm7FyS3WLSnUt0j25m3p+fvxvUInwhLBE9fyUlP2t/wHXOkd/KR1ncw5HebYK/dgN1RSa/izXmfFpKGGfxb4o5ZeYJgzvn5nkJHfBerki+5nuYhlcXm4qJn95V8LZ8yixSq7hTNy3tJx4CYQKBgQD32JI579iw2F/fLKwjnv1o61uLQJYvGB8JsWACVdny5kJt+AJaggCHNhMUOLgj1/Gywt6V9CEUhCminxIKC5gW12HfQtV6L9/lyA3ymND5lyWZKFqvLlksHqyvqlyK31uLm6UE4nP6NQ+NWfo5ue6gS1vp/wvhiM3LOFsPxDNgzQKBgQCUWrs3wX3YvHIODu8bgYBpgSin6tpNIxm1iojHnp5XtXcP5fNgOpRb0QjJjckdpFoLvCWURybhhDbJDwDiucm69RlT1fkKeQrAeiKpEQuKySN1xUjqQyKYVd4LKJl7rJT7RSgxar5nsbF5dCb98wj8TXeKeTNbYEI6O0MKhVj7BwKBgBpjot4sXYQm5b5bgVChoxXCyZKAI/2LsfJUQoa9IWGthrEy0P1WDjxXU5y5lVGrsn54JT8OKV+H2u8HxOHw7hawhClDcnt6EXrj3ChSgR2yLDysgUtZwgDimzxxBT18HsE0p1Nn0TV45NkGFZCD7ZZ/r5+wmlE/Qbo7m+aH23iZAoGAMHTKPdXnYwl6P3lFRDiyVsOnIeGl2Bgk55UORBVdJszQzNKRAddgafUG5751+EacWsTjiWEMJBDpTBaodWW1rGkuEqILLA6JIoFCHPLCUFyORoNf45R2EkfJtN9X8ntWVhQqoql486mojEESE1R0lORArWwVCD2SpC6DIUaY37UCgYAHbSfZUUeDMHlVMF6ZF4SbDsYw1ATPkhPOWnoBhm2zk0marGnXKlUdsRBL2JwYek648dSQ9Y9G4+sFt6qROBWel1U72Y76zczs34OkeYIEUPYLlL2P859tWtDLv3gnA4m65EdxfrxkUyFJiS+4+c4MDLPt3mNhNHA19/wtRsJsjA== \ No newline at end of file diff --git a/Entity/AssemblyHelper.cs b/Entity/AssemblyHelper.cs index ae347d3..8eae71b 100644 --- a/Entity/AssemblyHelper.cs +++ b/Entity/AssemblyHelper.cs @@ -1,30 +1,30 @@ -using System.Reflection; using System.Runtime.Loader; +using Fantasy.Helper; -namespace NB +namespace Fantasy { public static class AssemblyHelper { private const string HotfixDll = "Hotfix"; private static AssemblyLoadContext? _assemblyLoadContext = null; + - public static System.Reflection.Assembly[] Assemblies + public static void Initialize() { - get - { - var assemblies = new System.Reflection.Assembly[2]; - assemblies[0] = LoadEntityAssembly(); - assemblies[1] = LoadHotfixAssembly(); - return assemblies; - } + LoadEntityAssembly(); + LoadHotfixAssembly(); } - - private static System.Reflection.Assembly LoadEntityAssembly() + + private static void LoadEntityAssembly() { - return typeof(AssemblyHelper).Assembly; + // .NET 运行时采用延迟加载机制,如果代码中不使用程序集的类型,程序集不会被加载 + // 执行一下,触发运行时强制加载从而自动注册到框架中 + // 因为AssemblyHelper代码在Entity项目里,所以需要获取这个项目的Assembly + // 然后调用EnsureLoaded方法强制加载一下 + typeof(AssemblyHelper).Assembly.EnsureLoaded(); } - - private static System.Reflection.Assembly LoadHotfixAssembly() + + public static System.Reflection.Assembly LoadHotfixAssembly() { if (_assemblyLoadContext != null) { @@ -33,9 +33,16 @@ namespace NB } _assemblyLoadContext = new AssemblyLoadContext(HotfixDll, true); - var dllBytes = File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, $"{HotfixDll}.dll")); - var pdbBytes = File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, $"{HotfixDll}.pdb")); - return _assemblyLoadContext.LoadFromStream(new MemoryStream(dllBytes), new MemoryStream(pdbBytes)); + var dllBytes = File.ReadAllBytes(Path.Combine(AppContext.BaseDirectory, $"{HotfixDll}.dll")); + var pdbBytes = File.ReadAllBytes(Path.Combine(AppContext.BaseDirectory, $"{HotfixDll}.pdb")); + var assembly = _assemblyLoadContext.LoadFromStream(new MemoryStream(dllBytes), new MemoryStream(pdbBytes)); + // 强制触发 ModuleInitializer 执行 + // AssemblyLoadContext.LoadFromStream 只加载程序集到内存,不会自动触发 ModuleInitializer + // 必须访问程序集中的类型才能触发初始化,这里通过反射调用生成的 AssemblyMarker + // 注意:此方法仅用于热重载场景(JIT),Native AOT 不支持动态加载 + // 拿到Assembly就用EnsureLoaded()方法强制触发 + assembly.EnsureLoaded(); + return assembly; } } -} \ No newline at end of file +} diff --git a/Entity/LockType.cs b/Entity/Authentication/LockType.cs similarity index 100% rename from Entity/LockType.cs rename to Entity/Authentication/LockType.cs diff --git a/Entity/Entity.csproj b/Entity/Entity.csproj index 5a06389..3641447 100644 --- a/Entity/Entity.csproj +++ b/Entity/Entity.csproj @@ -1,39 +1,21 @@ - + - - enable - enable - Linux - default - net9.0 - + + net9.0 + Entity + latest + enable + enable + - - TRACE;FANTASY_NET - + + + + + - - TRACE;FANTASY_NET - + + + - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/Entity/Fantasy.config b/Entity/Fantasy.config new file mode 100644 index 0000000..b50d8ab --- /dev/null +++ b/Entity/Fantasy.config @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Entity/Fantasy.xsd b/Entity/Fantasy.xsd new file mode 100644 index 0000000..6a64f66 --- /dev/null +++ b/Entity/Fantasy.xsd @@ -0,0 +1,345 @@ + + + + + + + Fantasy框架配置文件根元素 + + + + + + 配置表路径设置 + + + + + 网络运行时配置 + + + + + 会话运行时配置 + + + + + 服务器配置 + + + + + + + + + + + 配置表文件路径 + + + + + + + + + + 机器配置列表 + + + + + 进程配置列表 + + + + + 世界配置列表 + + + + + 场景配置列表 + + + + + 单位配置列表 + + + + + + + + + + + + + + + + 机器ID + + + + + 外网IP地址 + + + + + 外网绑定IP地址 + + + + + 内网绑定IP地址 + + + + + + + + + + + + + + + 进程ID + + + + + 所属机器ID + + + + + 启动分组 + + + + + + + + + + + + + + + + 数据库类型 + + + + + + + + + + + + + + + + + + 数据库名称 + + + + + 数据库连接字符串 + + + + + + + + + 世界中配置的数据库 + + + + + + + + 世界ID + + + + + 世界名称 + + + + + + + + + + + + + + + 场景ID + + + + + 进程配置ID + + + + + 世界配置ID + + + + + 场景运行模式 + + + + + + + + + + + + 场景类型字符串 + + + + + 网络协议类型 + + + + + + + + + + + + + + 外网端口 + + + + + 内网端口 + + + + + + + + + 服务器内部网络协议 + + + + + + + + + + + 消息体最大长度(字节),默认1048560字节(约1.02MB) + + + + + + + + + Session idle check timeout (in milliseconds) + + + + + Session idle check interval (in milliseconds) + + + + + + + + + + + + + + + + 单位字典数据 + + + + + + 单位ID + + + + + 单位名称 + + + + + 单位模型 + + + + + + + + + + + 字典键 + + + + + 字典值 + + + + + + + + \ No newline at end of file diff --git a/Entity/Generate/ConfigTable/Entity/BaitConfig.cs b/Entity/Generate/ConfigTable/Entity/BaitConfig.cs index a38b53c..5a8723f 100644 --- a/Entity/Generate/ConfigTable/Entity/BaitConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/BaitConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class BaitConfig : ASerialize, IProto, IConfigTable + public sealed partial class BaitConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/BasicConfig.cs b/Entity/Generate/ConfigTable/Entity/BasicConfig.cs index a9a9cbb..783a7ea 100644 --- a/Entity/Generate/ConfigTable/Entity/BasicConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/BasicConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class BasicConfig : ASerialize, IProto, IConfigTable + public sealed partial class BasicConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/BobberConfig.cs b/Entity/Generate/ConfigTable/Entity/BobberConfig.cs index d6ca6db..53fe5f7 100644 --- a/Entity/Generate/ConfigTable/Entity/BobberConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/BobberConfig.cs @@ -6,25 +6,20 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class BobberConfig : ASerialize, IProto, IConfigTable + public sealed partial class BobberConfig : ASerialize, IConfigTable { - - [ProtoMember(1)] - public uint Id { get; set; } // Id - [ProtoMember(2)] - public uint Displacement { get; set; } // 位移 - [ProtoMember(3)] - public uint NightLight { get; set; } // 是否夜光 - [ProtoIgnore] - public uint Key => Id; - + [ProtoMember(1)] public uint Id { get; set; } // Id + [ProtoMember(2)] public uint Displacement { get; set; } // 位移 + [ProtoMember(3)] public uint NightLight { get; set; } // 是否夜光 + [ProtoIgnore] public uint Key => Id; + #region Static - + private static ConfigContext Context => ConfigTableHelper.Table(); public static BobberConfig Get(uint key) @@ -36,7 +31,7 @@ namespace NBF { return Context.Get(match); } - + public static BobberConfig Fist() { return Context.Fist(); @@ -56,7 +51,7 @@ namespace NBF { return Context.Last(match); } - + public static int Count() { return Context.Count(); @@ -76,10 +71,12 @@ namespace NBF { return Context.GetList(match); } + public static void ParseJson(Newtonsoft.Json.Linq.JArray arr) { ConfigTableHelper.ParseLine(arr); } + #endregion } } \ No newline at end of file diff --git a/Entity/Generate/ConfigTable/Entity/FeederConfig.cs b/Entity/Generate/ConfigTable/Entity/FeederConfig.cs index efab711..25c867b 100644 --- a/Entity/Generate/ConfigTable/Entity/FeederConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/FeederConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class FeederConfig : ASerialize, IProto, IConfigTable + public sealed partial class FeederConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/FishConfig.cs b/Entity/Generate/ConfigTable/Entity/FishConfig.cs index ed434cf..35aa809 100644 --- a/Entity/Generate/ConfigTable/Entity/FishConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/FishConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class FishConfig : ASerialize, IProto, IConfigTable + public sealed partial class FishConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/HookConfig.cs b/Entity/Generate/ConfigTable/Entity/HookConfig.cs index 4fc28ce..b5316e9 100644 --- a/Entity/Generate/ConfigTable/Entity/HookConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/HookConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class HookConfig : ASerialize, IProto, IConfigTable + public sealed partial class HookConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/InitConfig.cs b/Entity/Generate/ConfigTable/Entity/InitConfig.cs index 7abba17..b4e2547 100644 --- a/Entity/Generate/ConfigTable/Entity/InitConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/InitConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class InitConfig : ASerialize, IProto, IConfigTable + public sealed partial class InitConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/ItemConfig.cs b/Entity/Generate/ConfigTable/Entity/ItemConfig.cs index 89302f0..bdbcd39 100644 --- a/Entity/Generate/ConfigTable/Entity/ItemConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/ItemConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class ItemConfig : ASerialize, IProto, IConfigTable + public sealed partial class ItemConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/LineConfig.cs b/Entity/Generate/ConfigTable/Entity/LineConfig.cs index 0ab44c7..3059d1e 100644 --- a/Entity/Generate/ConfigTable/Entity/LineConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/LineConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class LineConfig : ASerialize, IProto, IConfigTable + public sealed partial class LineConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/LureConfig.cs b/Entity/Generate/ConfigTable/Entity/LureConfig.cs index 0b733e2..95b61f7 100644 --- a/Entity/Generate/ConfigTable/Entity/LureConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/LureConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class LureConfig : ASerialize, IProto, IConfigTable + public sealed partial class LureConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/ReelConfig.cs b/Entity/Generate/ConfigTable/Entity/ReelConfig.cs index 2ea450c..359d6f7 100644 --- a/Entity/Generate/ConfigTable/Entity/ReelConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/ReelConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class ReelConfig : ASerialize, IProto, IConfigTable + public sealed partial class ReelConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/RingConfig.cs b/Entity/Generate/ConfigTable/Entity/RingConfig.cs index 42b537f..ea332f6 100644 --- a/Entity/Generate/ConfigTable/Entity/RingConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/RingConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class RingConfig : ASerialize, IProto, IConfigTable + public sealed partial class RingConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/RodConfig.cs b/Entity/Generate/ConfigTable/Entity/RodConfig.cs index 72659d8..8f7099e 100644 --- a/Entity/Generate/ConfigTable/Entity/RodConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/RodConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class RodConfig : ASerialize, IProto, IConfigTable + public sealed partial class RodConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/RodRingConfig.cs b/Entity/Generate/ConfigTable/Entity/RodRingConfig.cs index 5502d6a..808ae56 100644 --- a/Entity/Generate/ConfigTable/Entity/RodRingConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/RodRingConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class RodRingConfig : ASerialize, IProto, IConfigTable + public sealed partial class RodRingConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/ConfigTable/Entity/WeightConfig.cs b/Entity/Generate/ConfigTable/Entity/WeightConfig.cs index 95d355c..da45f6f 100644 --- a/Entity/Generate/ConfigTable/Entity/WeightConfig.cs +++ b/Entity/Generate/ConfigTable/Entity/WeightConfig.cs @@ -6,12 +6,12 @@ using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; using Fantasy.Serialize; -using Fantasy.ConfigTable; +using NBF.ConfigTable; namespace NBF { [ProtoContract] - public sealed partial class WeightConfig : ASerialize, IProto, IConfigTable + public sealed partial class WeightConfig : ASerialize, IConfigTable { [ProtoMember(1)] diff --git a/Entity/Generate/CustomExport/SceneType.cs b/Entity/Generate/CustomExport/SceneType.cs deleted file mode 100644 index 87363cb..0000000 --- a/Entity/Generate/CustomExport/SceneType.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Fantasy -{ - // 生成器自动生成,请不要手动编辑。 - public static class SceneType - { - public const int Authentication = 1; - public const int Addressable = 2; - public const int Gate = 3; - public const int Game = 4; - public const int Map = 5; - public const int Activity = 6; - public const int Cache = 7; - public const int Social = 8; - - public static readonly Dictionary SceneTypeDic = new Dictionary() - { - { "Authentication", 1 }, - { "Addressable", 2 }, - { "Gate", 3 }, - { "Game", 4 }, - { "Map", 5 }, - { "Activity", 6 }, - { "Cache", 7 }, - { "Social", 8 }, - }; - } -} diff --git a/Entity/Generate/NetworkProtocol/CommonProtoData.cs b/Entity/Generate/NetworkProtocol/CommonProtoData.cs index c90bbd5..86b2633 100644 --- a/Entity/Generate/NetworkProtocol/CommonProtoData.cs +++ b/Entity/Generate/NetworkProtocol/CommonProtoData.cs @@ -1,5 +1,6 @@ using ProtoBuf; +using System; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using Fantasy; @@ -16,12 +17,12 @@ using Fantasy.Serialize; #pragma warning disable CS8618 namespace Fantasy -{ +{ /// /// 角色基础信息 /// [ProtoContract] - public partial class RoleBaseInfo : AMessage, IProto + public partial class RoleBaseInfo : AMessage { public static RoleBaseInfo Create(Scene scene) { @@ -53,7 +54,7 @@ namespace Fantasy public VipInfo VipInfo { get; set; } } [ProtoContract] - public partial class KeyValueInt64 : AMessage, IProto + public partial class KeyValueInt64 : AMessage { public static KeyValueInt64 Create(Scene scene) { @@ -76,7 +77,7 @@ namespace Fantasy /// 角色信息 /// [ProtoContract] - public partial class RoleInfo : AMessage, IProto + public partial class RoleInfo : AMessage { public static RoleInfo Create(Scene scene) { @@ -123,7 +124,7 @@ namespace Fantasy /// 角色信息 /// [ProtoContract] - public partial class RoleSimpleInfo : AMessage, IProto + public partial class RoleSimpleInfo : AMessage { public static RoleSimpleInfo Create(Scene scene) { @@ -161,7 +162,7 @@ namespace Fantasy /// VIP信息 /// [ProtoContract] - public partial class VipInfo : AMessage, IProto + public partial class VipInfo : AMessage { public static VipInfo Create(Scene scene) { @@ -187,7 +188,7 @@ namespace Fantasy /// 奖励信息 /// [ProtoContract] - public partial class AwardInfo : AMessage, IProto + public partial class AwardInfo : AMessage { public static AwardInfo Create(Scene scene) { @@ -210,7 +211,7 @@ namespace Fantasy /// 玩家当前使用钓组信息 /// [ProtoContract] - public partial class ItemBindInfo : AMessage, IProto + public partial class ItemBindInfo : AMessage { public static ItemBindInfo Create(Scene scene) { @@ -233,7 +234,7 @@ namespace Fantasy /// 物品信息 /// [ProtoContract] - public partial class ItemInfo : AMessage, IProto + public partial class ItemInfo : AMessage { public static ItemInfo Create(Scene scene) { @@ -268,7 +269,7 @@ namespace Fantasy /// fish信息 /// [ProtoContract] - public partial class FishInfo : AMessage, IProto + public partial class FishInfo : AMessage { public static FishInfo Create(Scene scene) { @@ -297,7 +298,7 @@ namespace Fantasy public long ExpirationTime { get; set; } } [ProtoContract] - public partial class ActivityInfo : AMessage, IProto + public partial class ActivityInfo : AMessage { public static ActivityInfo Create(Scene scene) { @@ -326,7 +327,7 @@ namespace Fantasy /// 技能情况 /// [ProtoContract] - public partial class SkillInfo : AMessage, IProto + public partial class SkillInfo : AMessage { public static SkillInfo Create(Scene scene) { @@ -349,3 +350,4 @@ namespace Fantasy public int Exp { get; set; } } } + diff --git a/Entity/Generate/NetworkProtocol/GameMessage.cs b/Entity/Generate/NetworkProtocol/GameMessage.cs index 26c8f1c..fee0e91 100644 --- a/Entity/Generate/NetworkProtocol/GameMessage.cs +++ b/Entity/Generate/NetworkProtocol/GameMessage.cs @@ -1,5 +1,6 @@ using ProtoBuf; +using System; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using Fantasy; @@ -16,7 +17,7 @@ using Fantasy.Serialize; #pragma warning disable CS8618 namespace Fantasy -{ +{ /// /// /////////// ******** 物品信息 *******///////////// /// @@ -24,7 +25,7 @@ namespace Fantasy /// 请求背包列表 /// [ProtoContract] - public partial class C2Game_GetItemsRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2Game_GetItemsRequest : AMessage, ICustomRouteRequest { public static C2Game_GetItemsRequest Create(Scene scene) { @@ -46,7 +47,7 @@ namespace Fantasy /// 请求背包列表响应 /// [ProtoContract] - public partial class Game2C_GetItemsResponse : AMessage, ICustomRouteResponse, IProto + public partial class Game2C_GetItemsResponse : AMessage, ICustomRouteResponse { public static Game2C_GetItemsResponse Create(Scene scene) { @@ -73,7 +74,7 @@ namespace Fantasy /// 请求使用物品 /// [ProtoContract] - public partial class C2Game_UseItemRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2Game_UseItemRequest : AMessage, ICustomRouteRequest { public static C2Game_UseItemRequest Create(Scene scene) { @@ -95,7 +96,7 @@ namespace Fantasy /// 请求使用物品响应 /// [ProtoContract] - public partial class Game2C_UseItemResponse : AMessage, ICustomRouteResponse, IProto + public partial class Game2C_UseItemResponse : AMessage, ICustomRouteResponse { public static Game2C_UseItemResponse Create(Scene scene) { @@ -116,7 +117,7 @@ namespace Fantasy /// 物品变化 /// [ProtoContract] - public partial class Game2C_ItemChange : AMessage, ICustomRouteMessage, IProto + public partial class Game2C_ItemChange : AMessage, ICustomRouteMessage { public static Game2C_ItemChange Create(Scene scene) { @@ -148,7 +149,7 @@ namespace Fantasy /// 请求安装或取下配件 /// [ProtoContract] - public partial class C2Game_RigChangeRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2Game_RigChangeRequest : AMessage, ICustomRouteRequest { public static C2Game_RigChangeRequest Create(Scene scene) { @@ -179,7 +180,7 @@ namespace Fantasy /// 请求安装配件响应 /// [ProtoContract] - public partial class Game2C_RigChangeResponse : AMessage, ICustomRouteResponse, IProto + public partial class Game2C_RigChangeResponse : AMessage, ICustomRouteResponse { public static Game2C_RigChangeResponse Create(Scene scene) { @@ -206,7 +207,7 @@ namespace Fantasy /// 请求鱼护列表 /// [ProtoContract] - public partial class C2Game_GetFishsRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2Game_GetFishsRequest : AMessage, ICustomRouteRequest { public static C2Game_GetFishsRequest Create(Scene scene) { @@ -228,7 +229,7 @@ namespace Fantasy /// 请求鱼护列表响应 /// [ProtoContract] - public partial class Game2C_GetFishsResponse : AMessage, ICustomRouteResponse, IProto + public partial class Game2C_GetFishsResponse : AMessage, ICustomRouteResponse { public static Game2C_GetFishsResponse Create(Scene scene) { @@ -252,7 +253,7 @@ namespace Fantasy /// 鱼护变化 /// [ProtoContract] - public partial class Game2C_FishChange : AMessage, ICustomRouteMessage, IProto + public partial class Game2C_FishChange : AMessage, ICustomRouteMessage { public static Game2C_FishChange Create(Scene scene) { @@ -281,7 +282,7 @@ namespace Fantasy /// 请求出售 /// [ProtoContract] - public partial class C2Game_SellFishRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2Game_SellFishRequest : AMessage, ICustomRouteRequest { public static C2Game_SellFishRequest Create(Scene scene) { @@ -306,7 +307,7 @@ namespace Fantasy /// 请求出售响应 /// [ProtoContract] - public partial class Game2C_SellFishResponse : AMessage, ICustomRouteResponse, IProto + public partial class Game2C_SellFishResponse : AMessage, ICustomRouteResponse { public static Game2C_SellFishResponse Create(Scene scene) { @@ -333,7 +334,7 @@ namespace Fantasy /// 请求购买 /// [ProtoContract] - public partial class C2Game_BuyRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2Game_BuyRequest : AMessage, ICustomRouteRequest { public static C2Game_BuyRequest Create(Scene scene) { @@ -355,7 +356,7 @@ namespace Fantasy /// 请求购买响应 /// [ProtoContract] - public partial class Game2C_BuyResponse : AMessage, ICustomRouteResponse, IProto + public partial class Game2C_BuyResponse : AMessage, ICustomRouteResponse { public static Game2C_BuyResponse Create(Scene scene) { @@ -376,3 +377,4 @@ namespace Fantasy public uint ErrorCode { get; set; } } } + diff --git a/Entity/Generate/NetworkProtocol/InnerMessage.cs b/Entity/Generate/NetworkProtocol/InnerMessage.cs index 34819f3..60806ce 100644 --- a/Entity/Generate/NetworkProtocol/InnerMessage.cs +++ b/Entity/Generate/NetworkProtocol/InnerMessage.cs @@ -1,5 +1,6 @@ using ProtoBuf; +using System; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using Fantasy; @@ -16,12 +17,12 @@ using Fantasy.Serialize; #pragma warning disable CS8618 namespace Fantasy -{ +{ /// /// 通知游戏服角色进入该游戏服 /// [ProtoContract] - public partial class G2Common_EnterRequest : AMessage, IRouteRequest, IProto + public partial class G2Common_EnterRequest : AMessage, IRouteRequest { public static G2Common_EnterRequest Create(Scene scene) { @@ -47,7 +48,7 @@ namespace Fantasy public int RouteType { get; set; } } [ProtoContract] - public partial class G2Common_EnterResponse : AMessage, IRouteResponse, IProto + public partial class G2Common_EnterResponse : AMessage, IRouteResponse { public static G2Common_EnterResponse Create(Scene scene) { @@ -71,7 +72,7 @@ namespace Fantasy public uint ErrorCode { get; set; } } [ProtoContract] - public partial class G2Common_ExitRequest : AMessage, IRouteRequest, IProto + public partial class G2Common_ExitRequest : AMessage, IRouteRequest { public static G2Common_ExitRequest Create(Scene scene) { @@ -94,7 +95,7 @@ namespace Fantasy public long GateRouteId { get; set; } } [ProtoContract] - public partial class Common2G_ExitResponse : AMessage, IRouteResponse, IProto + public partial class Common2G_ExitResponse : AMessage, IRouteResponse { public static Common2G_ExitResponse Create(Scene scene) { @@ -115,7 +116,7 @@ namespace Fantasy /// 获取玩家基础信息 /// [ProtoContract] - public partial class S2G_GetPlayerBasicInfoRequest : AMessage, IRouteRequest, IProto + public partial class S2G_GetPlayerBasicInfoRequest : AMessage, IRouteRequest { public static S2G_GetPlayerBasicInfoRequest Create(Scene scene) { @@ -138,7 +139,7 @@ namespace Fantasy /// 获取玩家基础信息响应 /// [ProtoContract] - public partial class G2S_GetPlayerBasicInfoResponse : AMessage, IRouteResponse, IProto + public partial class G2S_GetPlayerBasicInfoResponse : AMessage, IRouteResponse { public static G2S_GetPlayerBasicInfoResponse Create(Scene scene) { @@ -159,7 +160,7 @@ namespace Fantasy public uint ErrorCode { get; set; } } [ProtoContract] - public partial class S2G_ChatMessage : AMessage, IRouteMessage, IProto + public partial class S2G_ChatMessage : AMessage, IRouteMessage { public static S2G_ChatMessage Create(Scene scene) { @@ -183,7 +184,7 @@ namespace Fantasy /// 创建聊天频道 /// [ProtoContract] - public partial class Club2Chat_CreateChannel : AMessage, IRouteMessage, IProto + public partial class Club2Chat_CreateChannel : AMessage, IRouteMessage { public static Club2Chat_CreateChannel Create(Scene scene) { @@ -204,7 +205,7 @@ namespace Fantasy /// 请求进入房间 /// [ProtoContract] - public partial class G2Map_EnterMapRequest : AMessage, IRouteRequest, IProto + public partial class G2Map_EnterMapRequest : AMessage, IRouteRequest { public static G2Map_EnterMapRequest Create(Scene scene) { @@ -233,7 +234,7 @@ namespace Fantasy /// 请求进入房间响应 /// [ProtoContract] - public partial class Map2G_EnterMapResponse : AMessage, IRouteResponse, IProto + public partial class Map2G_EnterMapResponse : AMessage, IRouteResponse { public static Map2G_EnterMapResponse Create(Scene scene) { @@ -263,7 +264,7 @@ namespace Fantasy /// 请求离开房间 /// [ProtoContract] - public partial class G2Map_ExitRoomRequest : AMessage, IRouteRequest, IProto + public partial class G2Map_ExitRoomRequest : AMessage, IRouteRequest { public static G2Map_ExitRoomRequest Create(Scene scene) { @@ -289,7 +290,7 @@ namespace Fantasy /// 请求离开房间响应 /// [ProtoContract] - public partial class Map2G_ExiRoomResponse : AMessage, IRouteResponse, IProto + public partial class Map2G_ExiRoomResponse : AMessage, IRouteResponse { public static Map2G_ExiRoomResponse Create(Scene scene) { @@ -307,3 +308,4 @@ namespace Fantasy public uint ErrorCode { get; set; } } } + diff --git a/Entity/Generate/NetworkProtocol/MapMessage.cs b/Entity/Generate/NetworkProtocol/MapMessage.cs index 2a02cc7..f36fb38 100644 --- a/Entity/Generate/NetworkProtocol/MapMessage.cs +++ b/Entity/Generate/NetworkProtocol/MapMessage.cs @@ -1,5 +1,6 @@ using ProtoBuf; +using System; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using Fantasy; @@ -16,12 +17,12 @@ using Fantasy.Serialize; #pragma warning disable CS8618 namespace Fantasy -{ +{ /// /// 请求创建房间 /// [ProtoContract] - public partial class C2Map_CreateRoomRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2Map_CreateRoomRequest : AMessage, ICustomRouteRequest { public static C2Map_CreateRoomRequest Create(Scene scene) { @@ -46,7 +47,7 @@ namespace Fantasy /// 请求创建房间成功 /// [ProtoContract] - public partial class Map2C_CreateRoomResponse : AMessage, ICustomRouteResponse, IProto + public partial class Map2C_CreateRoomResponse : AMessage, ICustomRouteResponse { public static Map2C_CreateRoomResponse Create(Scene scene) { @@ -73,7 +74,7 @@ namespace Fantasy /// 请求网关离开房间(离开房间,但是不离开地图) /// [ProtoContract] - public partial class C2G_ExitRoomRequest : AMessage, IRequest, IProto + public partial class C2G_ExitRoomRequest : AMessage, IRequest { public static C2G_ExitRoomRequest Create(Scene scene) { @@ -96,7 +97,7 @@ namespace Fantasy /// 请求网关进入离开响应 /// [ProtoContract] - public partial class G2C_ExitRoomResponse : AMessage, IResponse, IProto + public partial class G2C_ExitRoomResponse : AMessage, IResponse { public static G2C_ExitRoomResponse Create(Scene scene) { @@ -120,7 +121,7 @@ namespace Fantasy /// 请求网关进入地图 /// [ProtoContract] - public partial class C2G_EnterMapRequest : AMessage, IRequest, IProto + public partial class C2G_EnterMapRequest : AMessage, IRequest { public static C2G_EnterMapRequest Create(Scene scene) { @@ -146,7 +147,7 @@ namespace Fantasy /// 请求网关进入房间响应 /// [ProtoContract] - public partial class G2C_EnterMapResponse : AMessage, IResponse, IProto + public partial class G2C_EnterMapResponse : AMessage, IResponse { public static G2C_EnterMapResponse Create(Scene scene) { @@ -176,7 +177,7 @@ namespace Fantasy /// 通知客户端切换地图 /// [ProtoContract] - public partial class Map2C_ChangeMap : AMessage, ICustomRouteMessage, IProto + public partial class Map2C_ChangeMap : AMessage, ICustomRouteMessage { public static Map2C_ChangeMap Create(Scene scene) { @@ -199,3 +200,4 @@ namespace Fantasy public int Node { get; set; } } } + diff --git a/Entity/Generate/NetworkProtocol/MapProtoData.cs b/Entity/Generate/NetworkProtocol/MapProtoData.cs index 23552c9..2578965 100644 --- a/Entity/Generate/NetworkProtocol/MapProtoData.cs +++ b/Entity/Generate/NetworkProtocol/MapProtoData.cs @@ -1,5 +1,6 @@ using ProtoBuf; +using System; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using Fantasy; @@ -16,9 +17,9 @@ using Fantasy.Serialize; #pragma warning disable CS8618 namespace Fantasy -{ +{ [ProtoContract] - public partial class Vector3Info : AMessage, IProto + public partial class Vector3Info : AMessage { public static Vector3Info Create(Scene scene) { @@ -41,7 +42,7 @@ namespace Fantasy public float z { get; set; } } [ProtoContract] - public partial class Vector2Info : AMessage, IProto + public partial class Vector2Info : AMessage { public static Vector2Info Create(Scene scene) { @@ -61,7 +62,7 @@ namespace Fantasy public float y { get; set; } } [ProtoContract] - public partial class QuaternionInfo : AMessage, IProto + public partial class QuaternionInfo : AMessage { public static QuaternionInfo Create(Scene scene) { @@ -90,7 +91,7 @@ namespace Fantasy /// 玩家当前使用钓组信息 /// [ProtoContract] - public partial class GearInfo : AMessage, IProto + public partial class GearInfo : AMessage { public static GearInfo Create(Scene scene) { @@ -119,7 +120,7 @@ namespace Fantasy public List Propertys = new List(); } [ProtoContract] - public partial class UnitStateInfo : AMessage, IProto + public partial class UnitStateInfo : AMessage { public static UnitStateInfo Create(Scene scene) { @@ -139,7 +140,7 @@ namespace Fantasy public List Propertys = new List(); } [ProtoContract] - public partial class MapUnitInfo : AMessage, IProto + public partial class MapUnitInfo : AMessage { public static MapUnitInfo Create(Scene scene) { @@ -174,3 +175,4 @@ namespace Fantasy public List Propertys = new List(); } } + diff --git a/Entity/Generate/NetworkProtocol/OuterMessage.cs b/Entity/Generate/NetworkProtocol/OuterMessage.cs index 4af2453..a90f841 100644 --- a/Entity/Generate/NetworkProtocol/OuterMessage.cs +++ b/Entity/Generate/NetworkProtocol/OuterMessage.cs @@ -1,5 +1,6 @@ using ProtoBuf; +using System; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using Fantasy; @@ -16,9 +17,9 @@ using Fantasy.Serialize; #pragma warning disable CS8618 namespace Fantasy -{ +{ [ProtoContract] - public partial class C2A_LoginRequest : AMessage, IRequest, IProto + public partial class C2A_LoginRequest : AMessage, IRequest { public static C2A_LoginRequest Create(Scene scene) { @@ -47,7 +48,7 @@ namespace Fantasy public int Region { get; set; } } [ProtoContract] - public partial class A2C_LoginResponse : AMessage, IResponse, IProto + public partial class A2C_LoginResponse : AMessage, IResponse { public static A2C_LoginResponse Create(Scene scene) { @@ -71,7 +72,7 @@ namespace Fantasy /// 客户端登录到Gate服务器 /// [ProtoContract] - public partial class C2G_LoginRequest : AMessage, IRequest, IProto + public partial class C2G_LoginRequest : AMessage, IRequest { public static C2G_LoginRequest Create(Scene scene) { @@ -91,7 +92,7 @@ namespace Fantasy public string ToKen { get; set; } } [ProtoContract] - public partial class G2C_LoginResponse : AMessage, IResponse, IProto + public partial class G2C_LoginResponse : AMessage, IResponse { public static G2C_LoginResponse Create(Scene scene) { @@ -115,7 +116,7 @@ namespace Fantasy /// 通知客户端重复登录 /// [ProtoContract] - public partial class G2C_RepeatLogin : AMessage, IMessage, IProto + public partial class G2C_RepeatLogin : AMessage, IMessage { public static G2C_RepeatLogin Create(Scene scene) { @@ -130,7 +131,7 @@ namespace Fantasy public uint OpCode() { return OuterOpcode.G2C_RepeatLogin; } } [ProtoContract] - public partial class C2Game_GetRoleInfoRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2Game_GetRoleInfoRequest : AMessage, ICustomRouteRequest { public static C2Game_GetRoleInfoRequest Create(Scene scene) { @@ -149,7 +150,7 @@ namespace Fantasy public int RouteType => Fantasy.RouteType.GameRoute; } [ProtoContract] - public partial class Game2C_GetRoleInfoResponse : AMessage, ICustomRouteResponse, IProto + public partial class Game2C_GetRoleInfoResponse : AMessage, ICustomRouteResponse { public static Game2C_GetRoleInfoResponse Create(Scene scene) { @@ -173,3 +174,4 @@ namespace Fantasy public uint ErrorCode { get; set; } } } + diff --git a/Entity/Generate/NetworkProtocol/RoomMessage.cs b/Entity/Generate/NetworkProtocol/RoomMessage.cs index 8bb37e2..41c37e0 100644 --- a/Entity/Generate/NetworkProtocol/RoomMessage.cs +++ b/Entity/Generate/NetworkProtocol/RoomMessage.cs @@ -1,5 +1,6 @@ using ProtoBuf; +using System; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using Fantasy; @@ -16,12 +17,12 @@ using Fantasy.Serialize; #pragma warning disable CS8618 namespace Fantasy -{ +{ /// /// 用户进入地图 /// [ProtoContract] - public partial class Map2C_RoleEnterRoomNotify : AMessage, ICustomRouteMessage, IProto + public partial class Map2C_RoleEnterRoomNotify : AMessage, ICustomRouteMessage { public static Map2C_RoleEnterRoomNotify Create(Scene scene) { @@ -44,7 +45,7 @@ namespace Fantasy /// 用户离开地图 /// [ProtoContract] - public partial class Map2C_RoleExitRoomNotify : AMessage, ICustomRouteMessage, IProto + public partial class Map2C_RoleExitRoomNotify : AMessage, ICustomRouteMessage { public static Map2C_RoleExitRoomNotify Create(Scene scene) { @@ -64,7 +65,7 @@ namespace Fantasy public long Id { get; set; } } [ProtoContract] - public partial class C2Map_RolePropertyChange : AMessage, ICustomRouteMessage, IProto + public partial class C2Map_RolePropertyChange : AMessage, ICustomRouteMessage { public static C2Map_RolePropertyChange Create(Scene scene) { @@ -87,7 +88,7 @@ namespace Fantasy /// 玩家状态变化同步 /// [ProtoContract] - public partial class Map2C_RoleStateNotify : AMessage, ICustomRouteMessage, IProto + public partial class Map2C_RoleStateNotify : AMessage, ICustomRouteMessage { public static Map2C_RoleStateNotify Create(Scene scene) { @@ -113,7 +114,7 @@ namespace Fantasy /// 玩家钓组变化 /// [ProtoContract] - public partial class Map2C_RoleGearChangeNotify : AMessage, ICustomRouteMessage, IProto + public partial class Map2C_RoleGearChangeNotify : AMessage, ICustomRouteMessage { public static Map2C_RoleGearChangeNotify Create(Scene scene) { @@ -136,7 +137,7 @@ namespace Fantasy public List Gears = new List(); } [ProtoContract] - public partial class Map2C_RolePropertyChangeNotify : AMessage, ICustomRouteMessage, IProto + public partial class Map2C_RolePropertyChangeNotify : AMessage, ICustomRouteMessage { public static Map2C_RolePropertyChangeNotify Create(Scene scene) { @@ -159,7 +160,7 @@ namespace Fantasy public List Propertys = new List(); } [ProtoContract] - public partial class C2Map_Move : AMessage, ICustomRouteMessage, IProto + public partial class C2Map_Move : AMessage, ICustomRouteMessage { public static C2Map_Move Create(Scene scene) { @@ -194,7 +195,7 @@ namespace Fantasy public long Timestamp { get; set; } } [ProtoContract] - public partial class C2Map_Look : AMessage, ICustomRouteMessage, IProto + public partial class C2Map_Look : AMessage, ICustomRouteMessage { public static C2Map_Look Create(Scene scene) { @@ -220,7 +221,7 @@ namespace Fantasy /// 玩家移动推送 /// [ProtoContract] - public partial class Map2C_MoveNotify : AMessage, ICustomRouteMessage, IProto + public partial class Map2C_MoveNotify : AMessage, ICustomRouteMessage { public static Map2C_MoveNotify Create(Scene scene) { @@ -261,7 +262,7 @@ namespace Fantasy /// 玩家旋转推送 /// [ProtoContract] - public partial class Map2C_LookeNotify : AMessage, ICustomRouteMessage, IProto + public partial class Map2C_LookeNotify : AMessage, ICustomRouteMessage { public static Map2C_LookeNotify Create(Scene scene) { @@ -287,3 +288,4 @@ namespace Fantasy public long Timestamp { get; set; } } } + diff --git a/Entity/Generate/NetworkProtocol/SocialMessage.cs b/Entity/Generate/NetworkProtocol/SocialMessage.cs index 5a802a5..cf1ab9b 100644 --- a/Entity/Generate/NetworkProtocol/SocialMessage.cs +++ b/Entity/Generate/NetworkProtocol/SocialMessage.cs @@ -1,5 +1,6 @@ using ProtoBuf; +using System; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using Fantasy; @@ -16,7 +17,7 @@ using Fantasy.Serialize; #pragma warning disable CS8618 namespace Fantasy -{ +{ /// /// /////////// ******** 私聊/邮件 *******///////////// /// @@ -24,7 +25,7 @@ namespace Fantasy /// 会话信息 /// [ProtoContract] - public partial class ConversationInfo : AMessage, IProto + public partial class ConversationInfo : AMessage { public static ConversationInfo Create(Scene scene) { @@ -44,7 +45,7 @@ namespace Fantasy public List List = new List(); } [ProtoContract] - public partial class MailInfo : AMessage, IProto + public partial class MailInfo : AMessage { public static MailInfo Create(Scene scene) { @@ -82,7 +83,7 @@ namespace Fantasy /// 请求会话列表 /// [ProtoContract] - public partial class C2S_GetConversationsRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_GetConversationsRequest : AMessage, ICustomRouteRequest { public static C2S_GetConversationsRequest Create(Scene scene) { @@ -104,7 +105,7 @@ namespace Fantasy /// 请求会话列表响应 /// [ProtoContract] - public partial class S2C_GetConversationsResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_GetConversationsResponse : AMessage, ICustomRouteResponse { public static S2C_GetConversationsResponse Create(Scene scene) { @@ -128,7 +129,7 @@ namespace Fantasy /// 发送邮件消息 /// [ProtoContract] - public partial class C2S_SendMailRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_SendMailRequest : AMessage, ICustomRouteRequest { public static C2S_SendMailRequest Create(Scene scene) { @@ -159,7 +160,7 @@ namespace Fantasy /// 发送邮件消息响应 /// [ProtoContract] - public partial class S2C_SendMailResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_SendMailResponse : AMessage, ICustomRouteResponse { public static S2C_SendMailResponse Create(Scene scene) { @@ -180,7 +181,7 @@ namespace Fantasy /// 发送删除会话消息 /// [ProtoContract] - public partial class C2S_DeleteMailRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_DeleteMailRequest : AMessage, ICustomRouteRequest { public static C2S_DeleteMailRequest Create(Scene scene) { @@ -205,7 +206,7 @@ namespace Fantasy /// 发送删除会话消息响应 /// [ProtoContract] - public partial class S2C_DeleteMailResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_DeleteMailResponse : AMessage, ICustomRouteResponse { public static S2C_DeleteMailResponse Create(Scene scene) { @@ -229,7 +230,7 @@ namespace Fantasy /// 新邮件推送 /// [ProtoContract] - public partial class S2C_HaveMail : AMessage, ICustomRouteMessage, IProto + public partial class S2C_HaveMail : AMessage, ICustomRouteMessage { public static S2C_HaveMail Create(Scene scene) { @@ -252,7 +253,7 @@ namespace Fantasy public string Key { get; set; } } [ProtoContract] - public partial class S2C_MailState : AMessage, ICustomRouteMessage, IProto + public partial class S2C_MailState : AMessage, ICustomRouteMessage { public static S2C_MailState Create(Scene scene) { @@ -278,7 +279,7 @@ namespace Fantasy /// /////////// ******** 频道聊天 *******///////////// /// [ProtoContract] - public partial class ChatUserInfo : AMessage, IProto + public partial class ChatUserInfo : AMessage { public static ChatUserInfo Create(Scene scene) { @@ -298,7 +299,7 @@ namespace Fantasy public long Name { get; set; } } [ProtoContract] - public partial class ChatMessageInfo : AMessage, IProto + public partial class ChatMessageInfo : AMessage { public static ChatMessageInfo Create(Scene scene) { @@ -330,7 +331,7 @@ namespace Fantasy /// 创建频道 /// [ProtoContract] - public partial class C2S_CreateChannelRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_CreateChannelRequest : AMessage, ICustomRouteRequest { public static C2S_CreateChannelRequest Create(Scene scene) { @@ -355,7 +356,7 @@ namespace Fantasy /// 创建频道响应 /// [ProtoContract] - public partial class S2C_CreateChannelResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_CreateChannelResponse : AMessage, ICustomRouteResponse { public static S2C_CreateChannelResponse Create(Scene scene) { @@ -379,7 +380,7 @@ namespace Fantasy /// 请求进入频道 /// [ProtoContract] - public partial class C2S_JoinChannelRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_JoinChannelRequest : AMessage, ICustomRouteRequest { public static C2S_JoinChannelRequest Create(Scene scene) { @@ -404,7 +405,7 @@ namespace Fantasy /// 进入频道响应 /// [ProtoContract] - public partial class S2C_JoinChannelResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_JoinChannelResponse : AMessage, ICustomRouteResponse { public static S2C_JoinChannelResponse Create(Scene scene) { @@ -425,7 +426,7 @@ namespace Fantasy /// 发送消息 /// [ProtoContract] - public partial class C2S_SendMessageRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_SendMessageRequest : AMessage, ICustomRouteRequest { public static C2S_SendMessageRequest Create(Scene scene) { @@ -453,7 +454,7 @@ namespace Fantasy /// 发送消息响应 /// [ProtoContract] - public partial class S2C_SendMessageResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_SendMessageResponse : AMessage, ICustomRouteResponse { public static S2C_SendMessageResponse Create(Scene scene) { @@ -474,7 +475,7 @@ namespace Fantasy /// 推送消息 /// [ProtoContract] - public partial class S2C_Message : AMessage, ICustomRouteMessage, IProto + public partial class S2C_Message : AMessage, ICustomRouteMessage { public static S2C_Message Create(Scene scene) { @@ -497,7 +498,7 @@ namespace Fantasy /// /////////// ******** 工会 *******///////////// /// [ProtoContract] - public partial class ClubInfo : AMessage, IProto + public partial class ClubInfo : AMessage { public static ClubInfo Create(Scene scene) { @@ -529,7 +530,7 @@ namespace Fantasy /// 请求创建工会 /// [ProtoContract] - public partial class C2S_CreateClubRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_CreateClubRequest : AMessage, ICustomRouteRequest { public static C2S_CreateClubRequest Create(Scene scene) { @@ -554,7 +555,7 @@ namespace Fantasy /// 创建工会响应 /// [ProtoContract] - public partial class S2C_CreateClubResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_CreateClubResponse : AMessage, ICustomRouteResponse { public static S2C_CreateClubResponse Create(Scene scene) { @@ -578,7 +579,7 @@ namespace Fantasy /// 请求工会信息 /// [ProtoContract] - public partial class C2S_GetClubInfoRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_GetClubInfoRequest : AMessage, ICustomRouteRequest { public static C2S_GetClubInfoRequest Create(Scene scene) { @@ -603,7 +604,7 @@ namespace Fantasy /// 响应工会信息 /// [ProtoContract] - public partial class S2C_GetClubInfoResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_GetClubInfoResponse : AMessage, ICustomRouteResponse { public static S2C_GetClubInfoResponse Create(Scene scene) { @@ -627,7 +628,7 @@ namespace Fantasy /// 请求工会成员列表 /// [ProtoContract] - public partial class C2S_GetMemberListRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_GetMemberListRequest : AMessage, ICustomRouteRequest { public static C2S_GetMemberListRequest Create(Scene scene) { @@ -652,7 +653,7 @@ namespace Fantasy /// 响应工会成员列表 /// [ProtoContract] - public partial class S2C_GetMemberListResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_GetMemberListResponse : AMessage, ICustomRouteResponse { public static S2C_GetMemberListResponse Create(Scene scene) { @@ -676,7 +677,7 @@ namespace Fantasy /// 获取工会列表请求 /// [ProtoContract] - public partial class C2S_GetClubListRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_GetClubListRequest : AMessage, ICustomRouteRequest { public static C2S_GetClubListRequest Create(Scene scene) { @@ -698,7 +699,7 @@ namespace Fantasy /// 获取工会列表响应 /// [ProtoContract] - public partial class S2C_GetClubListResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_GetClubListResponse : AMessage, ICustomRouteResponse { public static S2C_GetClubListResponse Create(Scene scene) { @@ -722,7 +723,7 @@ namespace Fantasy /// 请求加入工会 /// [ProtoContract] - public partial class C2S_JoinClubRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_JoinClubRequest : AMessage, ICustomRouteRequest { public static C2S_JoinClubRequest Create(Scene scene) { @@ -747,7 +748,7 @@ namespace Fantasy /// 响应加入工会 /// [ProtoContract] - public partial class S2C_JoinClubResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_JoinClubResponse : AMessage, ICustomRouteResponse { public static S2C_JoinClubResponse Create(Scene scene) { @@ -771,7 +772,7 @@ namespace Fantasy /// 请求退出工会 /// [ProtoContract] - public partial class C2S_LeaveClubRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_LeaveClubRequest : AMessage, ICustomRouteRequest { public static C2S_LeaveClubRequest Create(Scene scene) { @@ -796,7 +797,7 @@ namespace Fantasy /// 响应退出工会 /// [ProtoContract] - public partial class S2C_LeaveClubResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_LeaveClubResponse : AMessage, ICustomRouteResponse { public static S2C_LeaveClubResponse Create(Scene scene) { @@ -820,7 +821,7 @@ namespace Fantasy /// 请求解散工会 /// [ProtoContract] - public partial class C2S_DissolveClubRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_DissolveClubRequest : AMessage, ICustomRouteRequest { public static C2S_DissolveClubRequest Create(Scene scene) { @@ -845,7 +846,7 @@ namespace Fantasy /// 响应解散工会 /// [ProtoContract] - public partial class S2C_DissolveClubResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_DissolveClubResponse : AMessage, ICustomRouteResponse { public static S2C_DissolveClubResponse Create(Scene scene) { @@ -869,7 +870,7 @@ namespace Fantasy /// 请求操作申请 /// [ProtoContract] - public partial class C2S_DisposeJoinRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_DisposeJoinRequest : AMessage, ICustomRouteRequest { public static C2S_DisposeJoinRequest Create(Scene scene) { @@ -900,7 +901,7 @@ namespace Fantasy /// 响应操作申请 /// [ProtoContract] - public partial class S2C_DisposeJoinResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_DisposeJoinResponse : AMessage, ICustomRouteResponse { public static S2C_DisposeJoinResponse Create(Scene scene) { @@ -930,7 +931,7 @@ namespace Fantasy /// 推送消息 /// [ProtoContract] - public partial class S2C_ClubChange : AMessage, ICustomRouteMessage, IProto + public partial class S2C_ClubChange : AMessage, ICustomRouteMessage { public static S2C_ClubChange Create(Scene scene) { @@ -953,3 +954,4 @@ namespace Fantasy public int ChangeType { get; set; } } } + diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/ConfigContext.cs b/Entity/Modules/ConfigTable/ConfigContext.cs similarity index 97% rename from Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/ConfigContext.cs rename to Entity/Modules/ConfigTable/ConfigContext.cs index c3e1836..c45b677 100644 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/ConfigContext.cs +++ b/Entity/Modules/ConfigTable/ConfigContext.cs @@ -1,4 +1,4 @@ -namespace Fantasy.ConfigTable; +namespace NBF.ConfigTable; public interface IConfigContext { diff --git a/Entity/Modules/ConfigTable/ConfigTableHelper.cs b/Entity/Modules/ConfigTable/ConfigTableHelper.cs new file mode 100644 index 0000000..e7243b8 --- /dev/null +++ b/Entity/Modules/ConfigTable/ConfigTableHelper.cs @@ -0,0 +1,122 @@ +using System.Reflection; +using Fantasy; +using Fantasy.Helper; +using Newtonsoft.Json.Linq; + + +// ReSharper disable SuspiciousTypeConversion.Global + +namespace NBF.ConfigTable +{ + /// + /// 配置表帮助类 + /// + public static class ConfigTableHelper + { + private static readonly Dictionary _dictionary = new Dictionary(); + + public static void Initialize() + { + //解析配置文件 + var gameConfigText = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "configs.Json")); + + Initialize(gameConfigText, typeof(Fantasy.AssemblyHelper).Assembly); + } + + /// + /// 初始化ConfigTableHelper + /// + public static void Initialize(string json, params System.Reflection.Assembly[] assemblies) + { + _dictionary.Clear(); + var jsonObj = JObject.Parse(json); + Dictionary tokens = new(); + foreach (var item in jsonObj) + { + try + { + var name = item.Key; + var value = item.Value; + if (value is JArray jArray) + { + tokens[name] = jArray; + } + } + catch (Exception e) + { + Log.Error($"读表异常,请检查,name={item.Key} ex={e}"); + } + } + + foreach (var type in GetAllConfigTableTypes(assemblies)) + { + var name = type.Name; + if (tokens.TryGetValue(name, out var jArray)) + { + // 通过反射调用 ParseJson 方法 + var parseMethod = type.GetMethod("ParseJson", BindingFlags.Public | BindingFlags.Static); + parseMethod?.Invoke(null, [jArray]); + } + } + + // var d = _dictionary; + } + + public static ConfigContext? Table() where T : IConfigTable + { + var type = typeof(T); + if (_dictionary.TryGetValue(type, out var context)) + { + return context as ConfigContext; + } + + var jsonContext = new ConfigContext(); + _dictionary[type] = jsonContext; + return jsonContext; + } + + public static List ParseLine(JArray arr) where T : IConfigTable, new() + { + List list = new List(); + foreach (var jToken in arr) + { + T? instance = jToken.ToObject(); + + if (instance != null) + { + list.Add(instance); + } + } + + var context = Table(); + context?.Association(list); + + return list; + } + + /// + /// 获取所有实现了 IConfigTable 接口的非抽象类 + /// + /// 所有非抽象的配置对象类 + private static List GetAllConfigTableTypes(params System.Reflection.Assembly[] assemblies) + { + var types = new List(); + var interfaceType = typeof(IConfigTable); + + // 遍历当前程序集中的所有类型 + foreach (var assembly in assemblies) + { + foreach (var type in assembly.GetTypes()) + { + // 检查是否实现了 IConfigTable 接口,并且不是抽象类 + if (interfaceType.IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface) + { + types.Add(type); + } + } + } + + return types; + } + } +} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/Interface/IConfigTable.cs b/Entity/Modules/ConfigTable/Interface/IConfigTable.cs similarity index 83% rename from Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/Interface/IConfigTable.cs rename to Entity/Modules/ConfigTable/Interface/IConfigTable.cs index 56e3c8c..faefeb5 100644 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/Interface/IConfigTable.cs +++ b/Entity/Modules/ConfigTable/Interface/IConfigTable.cs @@ -1,4 +1,4 @@ -namespace Fantasy.ConfigTable +namespace NBF.ConfigTable { /// /// 表示是一个配置文件 diff --git a/Entity/bin/Debug/net9.0/Entity.deps.json b/Entity/bin/Debug/net9.0/Entity.deps.json new file mode 100644 index 0000000..e441805 --- /dev/null +++ b/Entity/bin/Debug/net9.0/Entity.deps.json @@ -0,0 +1,408 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v9.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v9.0": { + "Entity/1.0.0": { + "dependencies": { + "Fantasy-Net": "2025.2.0", + "Microsoft.IdentityModel.Tokens": "8.14.0", + "System.IdentityModel.Tokens.Jwt": "8.14.0", + "ThirdParty": "1.0.0" + }, + "runtime": { + "Entity.dll": {} + } + }, + "CommandLineParser/2.9.1": { + "runtime": { + "lib/netstandard2.0/CommandLine.dll": { + "assemblyVersion": "2.9.1.0", + "fileVersion": "2.9.1.0" + } + } + }, + "DnsClient/1.6.1": { + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0" + }, + "runtime": { + "lib/net5.0/DnsClient.dll": { + "assemblyVersion": "1.6.1.0", + "fileVersion": "1.6.1.0" + } + } + }, + "Fantasy-Net/2025.2.0": { + "dependencies": { + "CommandLineParser": "2.9.1", + "MongoDB.Bson": "3.5.0", + "MongoDB.Driver": "3.5.0", + "Newtonsoft.Json": "13.0.4", + "protobuf-net": "3.2.56" + }, + "runtime": { + "lib/net9.0/Fantasy-Net.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {}, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" + } + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.NETCore.Platforms/5.0.0": {}, + "Microsoft.Win32.Registry/5.0.0": { + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "MongoDB.Bson/3.5.0": { + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "5.0.0" + }, + "runtime": { + "lib/net6.0/MongoDB.Bson.dll": { + "assemblyVersion": "3.5.0.0", + "fileVersion": "3.5.0.0" + } + } + }, + "MongoDB.Driver/3.5.0": { + "dependencies": { + "DnsClient": "1.6.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "MongoDB.Bson": "3.5.0", + "SharpCompress": "0.30.1", + "Snappier": "1.0.0", + "System.Buffers": "4.5.1", + "ZstdSharp.Port": "0.7.3" + }, + "runtime": { + "lib/net6.0/MongoDB.Driver.dll": { + "assemblyVersion": "3.5.0.0", + "fileVersion": "3.5.0.0" + } + } + }, + "Newtonsoft.Json/13.0.4": { + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.4.30916" + } + } + }, + "protobuf-net/3.2.56": { + "dependencies": { + "protobuf-net.Core": "3.2.56" + }, + "runtime": { + "lib/net8.0/protobuf-net.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.2.56.57311" + } + } + }, + "protobuf-net.Core/3.2.56": { + "runtime": { + "lib/net8.0/protobuf-net.Core.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.2.56.57311" + } + } + }, + "SharpCompress/0.30.1": { + "runtime": { + "lib/net5.0/SharpCompress.dll": { + "assemblyVersion": "0.30.1.0", + "fileVersion": "0.30.1.0" + } + } + }, + "Snappier/1.0.0": { + "runtime": { + "lib/net5.0/Snappier.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "System.Buffers/4.5.1": {}, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.14.0", + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "runtime": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "System.Memory/4.5.5": {}, + "System.Runtime.CompilerServices.Unsafe/5.0.0": {}, + "System.Security.AccessControl/5.0.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Principal.Windows/5.0.0": {}, + "ZstdSharp.Port/0.7.3": { + "runtime": { + "lib/net7.0/ZstdSharp.dll": { + "assemblyVersion": "0.7.3.0", + "fileVersion": "0.7.3.0" + } + } + }, + "ThirdParty/1.0.0": { + "runtime": { + "ThirdParty.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + } + } + }, + "libraries": { + "Entity/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "CommandLineParser/2.9.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-OE0sl1/sQ37bjVsPKKtwQlWDgqaxWgtme3xZz7JssWUzg5JpMIyHgCTY9MVMxOg48fJ1AgGT3tgdH5m/kQ5xhA==", + "path": "commandlineparser/2.9.1", + "hashPath": "commandlineparser.2.9.1.nupkg.sha512" + }, + "DnsClient/1.6.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4H/f2uYJOZ+YObZjpY9ABrKZI+JNw3uizp6oMzTXwDw6F+2qIPhpRl/1t68O/6e98+vqNiYGu+lswmwdYUy3gg==", + "path": "dnsclient/1.6.1", + "hashPath": "dnsclient.1.6.1.nupkg.sha512" + }, + "Fantasy-Net/2025.2.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-vCkduwxkMlH8GozyS+ZlWGLC4nGjFGaL13Ah4w5HL55XAJaAhe+RX+gbSRNBeJf1Uu0cjG2MgVyS4NX7bXdN4g==", + "path": "fantasy-net/2025.2.0", + "hashPath": "fantasy-net.2025.2.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "path": "microsoft.extensions.logging.abstractions/8.0.0", + "hashPath": "microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==", + "path": "microsoft.identitymodel.abstractions/8.14.0", + "hashPath": "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==", + "path": "microsoft.identitymodel.jsonwebtokens/8.14.0", + "hashPath": "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==", + "path": "microsoft.identitymodel.logging/8.14.0", + "hashPath": "microsoft.identitymodel.logging.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==", + "path": "microsoft.identitymodel.tokens/8.14.0", + "hashPath": "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==", + "path": "microsoft.netcore.platforms/5.0.0", + "hashPath": "microsoft.netcore.platforms.5.0.0.nupkg.sha512" + }, + "Microsoft.Win32.Registry/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "path": "microsoft.win32.registry/5.0.0", + "hashPath": "microsoft.win32.registry.5.0.0.nupkg.sha512" + }, + "MongoDB.Bson/3.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-JGNK6BanLDEifgkvPLqVFCPus5EDCy416pxf1dxUBRSVd3D9+NB3AvMVX190eXlk5/UXuCxpsQv7jWfNKvppBQ==", + "path": "mongodb.bson/3.5.0", + "hashPath": "mongodb.bson.3.5.0.nupkg.sha512" + }, + "MongoDB.Driver/3.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ST90u7psyMkNNOWFgSkexsrB3kPn7Ynl2DlMFj2rJyYuc6SIxjmzu4ufy51yzM+cPVE1SvVcdb5UFobrRw6cMg==", + "path": "mongodb.driver/3.5.0", + "hashPath": "mongodb.driver.3.5.0.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.4": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pdgNNMai3zv51W5aq268sujXUyx7SNdE2bj1wZcWjAQrKMFZV260lbqYop1d2GM67JI1huLRwxo9ZqnfF/lC6A==", + "path": "newtonsoft.json/13.0.4", + "hashPath": "newtonsoft.json.13.0.4.nupkg.sha512" + }, + "protobuf-net/3.2.56": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4IPJeTYAMNewlN8MDaFkcmR/9hLhJeo9eARnTh104zh7mf+vXT2gu5MUfUnkSQU+CH578Q6vcdU7LQDQPG6eaw==", + "path": "protobuf-net/3.2.56", + "hashPath": "protobuf-net.3.2.56.nupkg.sha512" + }, + "protobuf-net.Core/3.2.56": { + "type": "package", + "serviceable": true, + "sha512": "sha512-d6QOukTpDzs7zZv9tPnBZMtvHDNeHJQXUhMx54g4urUQsXK3oo9U70H9HvklYq7hlQ4A7AHJl7EVEqyCXXIl8Q==", + "path": "protobuf-net.core/3.2.56", + "hashPath": "protobuf-net.core.3.2.56.nupkg.sha512" + }, + "SharpCompress/0.30.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XqD4TpfyYGa7QTPzaGlMVbcecKnXy4YmYLDWrU+JIj7IuRNl7DH2END+Ll7ekWIY8o3dAMWLFDE1xdhfIWD1nw==", + "path": "sharpcompress/0.30.1", + "hashPath": "sharpcompress.0.30.1.nupkg.sha512" + }, + "Snappier/1.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rFtK2KEI9hIe8gtx3a0YDXdHOpedIf9wYCEYtBEmtlyiWVX3XlCNV03JrmmAi/Cdfn7dxK+k0sjjcLv4fpHnqA==", + "path": "snappier/1.0.0", + "hashPath": "snappier.1.0.0.nupkg.sha512" + }, + "System.Buffers/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==", + "path": "system.buffers/4.5.1", + "hashPath": "system.buffers.4.5.1.nupkg.sha512" + }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-EYGgN/S+HK7S6F3GaaPLFAfK0UzMrkXFyWCvXpQWFYmZln3dqtbyIO7VuTM/iIIPMzkelg8ZLlBPvMhxj6nOAA==", + "path": "system.identitymodel.tokens.jwt/8.14.0", + "hashPath": "system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512" + }, + "System.Memory/4.5.5": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "path": "system.memory/4.5.5", + "hashPath": "system.memory.4.5.5.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==", + "path": "system.runtime.compilerservices.unsafe/5.0.0", + "hashPath": "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512" + }, + "System.Security.AccessControl/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "path": "system.security.accesscontrol/5.0.0", + "hashPath": "system.security.accesscontrol.5.0.0.nupkg.sha512" + }, + "System.Security.Principal.Windows/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==", + "path": "system.security.principal.windows/5.0.0", + "hashPath": "system.security.principal.windows.5.0.0.nupkg.sha512" + }, + "ZstdSharp.Port/0.7.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-U9Ix4l4cl58Kzz1rJzj5hoVTjmbx1qGMwzAcbv1j/d3NzrFaESIurQyg+ow4mivCgkE3S413y+U9k4WdnEIkRA==", + "path": "zstdsharp.port/0.7.3", + "hashPath": "zstdsharp.port.0.7.3.nupkg.sha512" + }, + "ThirdParty/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Entity/bin/Debug/net9.0/Entity.dll b/Entity/bin/Debug/net9.0/Entity.dll new file mode 100644 index 0000000..e3649fb Binary files /dev/null and b/Entity/bin/Debug/net9.0/Entity.dll differ diff --git a/Entity/bin/Debug/net9.0/Entity.pdb b/Entity/bin/Debug/net9.0/Entity.pdb new file mode 100644 index 0000000..aa1be2e Binary files /dev/null and b/Entity/bin/Debug/net9.0/Entity.pdb differ diff --git a/Entity/bin/Debug/net9.0/Fantasy.config b/Entity/bin/Debug/net9.0/Fantasy.config new file mode 100644 index 0000000..b50d8ab --- /dev/null +++ b/Entity/bin/Debug/net9.0/Fantasy.config @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Entity/bin/Debug/net9.0/Fantasy.xsd b/Entity/bin/Debug/net9.0/Fantasy.xsd new file mode 100644 index 0000000..6a64f66 --- /dev/null +++ b/Entity/bin/Debug/net9.0/Fantasy.xsd @@ -0,0 +1,345 @@ + + + + + + + Fantasy框架配置文件根元素 + + + + + + 配置表路径设置 + + + + + 网络运行时配置 + + + + + 会话运行时配置 + + + + + 服务器配置 + + + + + + + + + + + 配置表文件路径 + + + + + + + + + + 机器配置列表 + + + + + 进程配置列表 + + + + + 世界配置列表 + + + + + 场景配置列表 + + + + + 单位配置列表 + + + + + + + + + + + + + + + + 机器ID + + + + + 外网IP地址 + + + + + 外网绑定IP地址 + + + + + 内网绑定IP地址 + + + + + + + + + + + + + + + 进程ID + + + + + 所属机器ID + + + + + 启动分组 + + + + + + + + + + + + + + + + 数据库类型 + + + + + + + + + + + + + + + + + + 数据库名称 + + + + + 数据库连接字符串 + + + + + + + + + 世界中配置的数据库 + + + + + + + + 世界ID + + + + + 世界名称 + + + + + + + + + + + + + + + 场景ID + + + + + 进程配置ID + + + + + 世界配置ID + + + + + 场景运行模式 + + + + + + + + + + + + 场景类型字符串 + + + + + 网络协议类型 + + + + + + + + + + + + + + 外网端口 + + + + + 内网端口 + + + + + + + + + 服务器内部网络协议 + + + + + + + + + + + 消息体最大长度(字节),默认1048560字节(约1.02MB) + + + + + + + + + Session idle check timeout (in milliseconds) + + + + + Session idle check interval (in milliseconds) + + + + + + + + + + + + + + + + 单位字典数据 + + + + + + 单位ID + + + + + 单位名称 + + + + + 单位模型 + + + + + + + + + + + 字典键 + + + + + 字典值 + + + + + + + + \ No newline at end of file diff --git a/Entity/bin/Debug/net9.0/ThirdParty.dll b/Entity/bin/Debug/net9.0/ThirdParty.dll new file mode 100644 index 0000000..c68db15 Binary files /dev/null and b/Entity/bin/Debug/net9.0/ThirdParty.dll differ diff --git a/Entity/bin/Debug/net9.0/ThirdParty.pdb b/Entity/bin/Debug/net9.0/ThirdParty.pdb new file mode 100644 index 0000000..6d74378 Binary files /dev/null and b/Entity/bin/Debug/net9.0/ThirdParty.pdb differ diff --git a/Entity/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs b/Entity/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs new file mode 100644 index 0000000..feda5e9 --- /dev/null +++ b/Entity/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")] diff --git a/Entity/obj/Debug/net9.0/Entity.AssemblyInfo.cs b/Entity/obj/Debug/net9.0/Entity.AssemblyInfo.cs new file mode 100644 index 0000000..4e9ca95 --- /dev/null +++ b/Entity/obj/Debug/net9.0/Entity.AssemblyInfo.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("Entity")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+7b10d4cb317c9f310649a9cb4afe3882d4b12624")] +[assembly: System.Reflection.AssemblyProductAttribute("Entity")] +[assembly: System.Reflection.AssemblyTitleAttribute("Entity")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// 由 MSBuild WriteCodeFragment 类生成。 + diff --git a/Entity/obj/Debug/net9.0/Entity.AssemblyInfoInputs.cache b/Entity/obj/Debug/net9.0/Entity.AssemblyInfoInputs.cache new file mode 100644 index 0000000..946fdb5 --- /dev/null +++ b/Entity/obj/Debug/net9.0/Entity.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +4925a41a1713fbdc3c4b16a99814eedf9add8ff230ff3e204d8dc265b8ca499e diff --git a/Entity/obj/Debug/net9.0/Entity.GeneratedMSBuildEditorConfig.editorconfig b/Entity/obj/Debug/net9.0/Entity.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 0000000..3dbeb6a --- /dev/null +++ b/Entity/obj/Debug/net9.0/Entity.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,15 @@ +is_global = true +build_property.TargetFramework = net9.0 +build_property.TargetPlatformMinVersion = +build_property.UsingMicrosoftNETSdkWeb = +build_property.ProjectTypeGuids = +build_property.InvariantGlobalization = +build_property.PlatformNeutralAssembly = +build_property.EnforceExtendedAnalyzerRules = +build_property._SupportedPlatformList = Linux,macOS,Windows +build_property.RootNamespace = Entity +build_property.ProjectDir = D:\work\Fishing2Server\Entity\ +build_property.EnableComHosting = +build_property.EnableGeneratedComInterfaceComImportInterop = +build_property.EffectiveAnalysisLevelStyle = 9.0 +build_property.EnableCodeStyleSeverity = diff --git a/Entity/obj/Debug/net9.0/Entity.GlobalUsings.g.cs b/Entity/obj/Debug/net9.0/Entity.GlobalUsings.g.cs new file mode 100644 index 0000000..8578f3d --- /dev/null +++ b/Entity/obj/Debug/net9.0/Entity.GlobalUsings.g.cs @@ -0,0 +1,8 @@ +// +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Net.Http; +global using global::System.Threading; +global using global::System.Threading.Tasks; diff --git a/Entity/obj/Debug/net9.0/Entity.assets.cache b/Entity/obj/Debug/net9.0/Entity.assets.cache new file mode 100644 index 0000000..79321ef Binary files /dev/null and b/Entity/obj/Debug/net9.0/Entity.assets.cache differ diff --git a/Entity/obj/Debug/net9.0/Entity.csproj.AssemblyReference.cache b/Entity/obj/Debug/net9.0/Entity.csproj.AssemblyReference.cache new file mode 100644 index 0000000..ebe7baf Binary files /dev/null and b/Entity/obj/Debug/net9.0/Entity.csproj.AssemblyReference.cache differ diff --git a/Entity/obj/Debug/net9.0/Entity.csproj.CoreCompileInputs.cache b/Entity/obj/Debug/net9.0/Entity.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..2d32e9b --- /dev/null +++ b/Entity/obj/Debug/net9.0/Entity.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +6062551d1ab69f267bcbdefc9b276d4b2471f6b61b2a4e2cc6c5f261ac8ee2b5 diff --git a/Entity/obj/Debug/net9.0/Entity.csproj.FileListAbsolute.txt b/Entity/obj/Debug/net9.0/Entity.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..7e0352f --- /dev/null +++ b/Entity/obj/Debug/net9.0/Entity.csproj.FileListAbsolute.txt @@ -0,0 +1,17 @@ +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\bin\Debug\net9.0\Fantasy.config +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\bin\Debug\net9.0\Fantasy.xsd +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\bin\Debug\net9.0\Entity.deps.json +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\bin\Debug\net9.0\Entity.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\bin\Debug\net9.0\Entity.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\Entity.csproj.AssemblyReference.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\Entity.GeneratedMSBuildEditorConfig.editorconfig +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\Entity.AssemblyInfoInputs.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\Entity.AssemblyInfo.cs +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\Entity.csproj.CoreCompileInputs.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\Entity.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\refint\Entity.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\Entity.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\ref\Entity.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\bin\Debug\net9.0\ThirdParty.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\bin\Debug\net9.0\ThirdParty.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Entity\obj\Debug\net9.0\Entity.csproj.Up2Date diff --git a/Entity/obj/Debug/net9.0/Entity.csproj.Up2Date b/Entity/obj/Debug/net9.0/Entity.csproj.Up2Date new file mode 100644 index 0000000..e69de29 diff --git a/Entity/obj/Debug/net9.0/Entity.dll b/Entity/obj/Debug/net9.0/Entity.dll new file mode 100644 index 0000000..e3649fb Binary files /dev/null and b/Entity/obj/Debug/net9.0/Entity.dll differ diff --git a/Entity/obj/Debug/net9.0/Entity.pdb b/Entity/obj/Debug/net9.0/Entity.pdb new file mode 100644 index 0000000..aa1be2e Binary files /dev/null and b/Entity/obj/Debug/net9.0/Entity.pdb differ diff --git a/Entity/obj/Debug/net9.0/ref/Entity.dll b/Entity/obj/Debug/net9.0/ref/Entity.dll new file mode 100644 index 0000000..973d2df Binary files /dev/null and b/Entity/obj/Debug/net9.0/ref/Entity.dll differ diff --git a/Entity/obj/Debug/net9.0/refint/Entity.dll b/Entity/obj/Debug/net9.0/refint/Entity.dll new file mode 100644 index 0000000..973d2df Binary files /dev/null and b/Entity/obj/Debug/net9.0/refint/Entity.dll differ diff --git a/Entity/obj/Entity.csproj.nuget.dgspec.json b/Entity/obj/Entity.csproj.nuget.dgspec.json new file mode 100644 index 0000000..941e191 --- /dev/null +++ b/Entity/obj/Entity.csproj.nuget.dgspec.json @@ -0,0 +1,156 @@ +{ + "format": 1, + "restore": { + "D:\\work\\Fishing2Server\\Entity\\Entity.csproj": {} + }, + "projects": { + "D:\\work\\Fishing2Server\\Entity\\Entity.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj", + "projectName": "Entity", + "projectPath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\Entity\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net9.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "projectReferences": { + "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "dependencies": { + "Fantasy-Net": { + "target": "Package", + "version": "[2025.2.0, )" + }, + "Microsoft.IdentityModel.Tokens": { + "target": "Package", + "version": "[8.14.0, )" + }, + "System.IdentityModel.Tokens.Jwt": { + "target": "Package", + "version": "[8.14.0, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + }, + "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "projectName": "ThirdParty", + "projectPath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\ThirdParty\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net8.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/Entity/obj/Entity.csproj.nuget.g.props b/Entity/obj/Entity.csproj.nuget.g.props new file mode 100644 index 0000000..d208a02 --- /dev/null +++ b/Entity/obj/Entity.csproj.nuget.g.props @@ -0,0 +1,19 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + $(UserProfile)\.nuget\packages\ + C:\Users\FIREBAT\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages + PackageReference + 6.14.0 + + + + + + + + + \ No newline at end of file diff --git a/Entity/obj/Entity.csproj.nuget.g.targets b/Entity/obj/Entity.csproj.nuget.g.targets new file mode 100644 index 0000000..eb7028d --- /dev/null +++ b/Entity/obj/Entity.csproj.nuget.g.targets @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Entity/obj/project.assets.json b/Entity/obj/project.assets.json new file mode 100644 index 0000000..7478cbe --- /dev/null +++ b/Entity/obj/project.assets.json @@ -0,0 +1,1215 @@ +{ + "version": 3, + "targets": { + "net9.0": { + "CommandLineParser/2.9.1": { + "type": "package", + "compile": { + "lib/netstandard2.0/CommandLine.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/CommandLine.dll": { + "related": ".xml" + } + } + }, + "DnsClient/1.6.1": { + "type": "package", + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0" + }, + "compile": { + "lib/net5.0/DnsClient.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net5.0/DnsClient.dll": { + "related": ".xml" + } + } + }, + "Fantasy-Net/2025.2.0": { + "type": "package", + "dependencies": { + "CommandLineParser": "2.9.1", + "MongoDB.Bson": "3.5.0", + "MongoDB.Driver": "3.5.0", + "Newtonsoft.Json": "13.0.4", + "protobuf-net": "3.2.56" + }, + "compile": { + "lib/net9.0/Fantasy-Net.dll": {} + }, + "runtime": { + "lib/net9.0/Fantasy-Net.dll": {} + }, + "frameworkReferences": [ + "Microsoft.AspNetCore.App" + ], + "build": { + "build/Fantasy-Net.props": {}, + "buildTransitive/Fantasy-Net.targets": {} + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { + "type": "package", + "compile": { + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "related": ".xml" + } + }, + "build": { + "buildTransitive/net6.0/_._": {} + } + }, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "type": "package", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" + }, + "compile": { + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "related": ".xml" + } + }, + "build": { + "buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets": {} + } + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "type": "package", + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "related": ".xml" + } + } + }, + "Microsoft.NETCore.Platforms/5.0.0": { + "type": "package", + "compile": { + "lib/netstandard1.0/_._": {} + }, + "runtime": { + "lib/netstandard1.0/_._": {} + } + }, + "Microsoft.Win32.Registry/5.0.0": { + "type": "package", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/Microsoft.Win32.Registry.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Win32.Registry.dll": { + "related": ".xml" + } + }, + "runtimeTargets": { + "runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "MongoDB.Bson/3.5.0": { + "type": "package", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "5.0.0" + }, + "compile": { + "lib/net6.0/MongoDB.Bson.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/MongoDB.Bson.dll": { + "related": ".xml" + } + } + }, + "MongoDB.Driver/3.5.0": { + "type": "package", + "dependencies": { + "DnsClient": "1.6.1", + "Microsoft.Extensions.Logging.Abstractions": "2.0.0", + "MongoDB.Bson": "3.5.0", + "SharpCompress": "0.30.1", + "Snappier": "1.0.0", + "System.Buffers": "4.5.1", + "ZstdSharp.Port": "0.7.3" + }, + "compile": { + "lib/net6.0/MongoDB.Driver.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/MongoDB.Driver.dll": { + "related": ".xml" + } + } + }, + "Newtonsoft.Json/13.0.4": { + "type": "package", + "compile": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + }, + "protobuf-net/3.2.56": { + "type": "package", + "dependencies": { + "protobuf-net.Core": "3.2.56" + }, + "compile": { + "lib/net8.0/protobuf-net.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/protobuf-net.dll": { + "related": ".xml" + } + } + }, + "protobuf-net.Core/3.2.56": { + "type": "package", + "compile": { + "lib/net8.0/protobuf-net.Core.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/protobuf-net.Core.dll": { + "related": ".xml" + } + } + }, + "SharpCompress/0.30.1": { + "type": "package", + "compile": { + "lib/net5.0/SharpCompress.dll": {} + }, + "runtime": { + "lib/net5.0/SharpCompress.dll": {} + } + }, + "Snappier/1.0.0": { + "type": "package", + "compile": { + "lib/net5.0/Snappier.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net5.0/Snappier.dll": { + "related": ".xml" + } + } + }, + "System.Buffers/4.5.1": { + "type": "package", + "compile": { + "ref/netcoreapp2.0/_._": {} + }, + "runtime": { + "lib/netcoreapp2.0/_._": {} + } + }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.14.0", + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "compile": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "related": ".xml" + } + } + }, + "System.Memory/4.5.5": { + "type": "package", + "compile": { + "ref/netcoreapp2.1/_._": {} + }, + "runtime": { + "lib/netcoreapp2.1/_._": {} + } + }, + "System.Runtime.CompilerServices.Unsafe/5.0.0": { + "type": "package", + "compile": { + "ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "related": ".xml" + } + } + }, + "System.Security.AccessControl/5.0.0": { + "type": "package", + "dependencies": { + "Microsoft.NETCore.Platforms": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/System.Security.AccessControl.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/System.Security.AccessControl.dll": { + "related": ".xml" + } + }, + "runtimeTargets": { + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "System.Security.Principal.Windows/5.0.0": { + "type": "package", + "compile": { + "ref/netcoreapp3.0/System.Security.Principal.Windows.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/System.Security.Principal.Windows.dll": { + "related": ".xml" + } + }, + "runtimeTargets": { + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": { + "assetType": "runtime", + "rid": "unix" + }, + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "ZstdSharp.Port/0.7.3": { + "type": "package", + "compile": { + "lib/net7.0/ZstdSharp.dll": {} + }, + "runtime": { + "lib/net7.0/ZstdSharp.dll": {} + } + }, + "ThirdParty/1.0.0": { + "type": "project", + "framework": ".NETCoreApp,Version=v8.0", + "compile": { + "bin/placeholder/ThirdParty.dll": {} + }, + "runtime": { + "bin/placeholder/ThirdParty.dll": {} + } + } + } + }, + "libraries": { + "CommandLineParser/2.9.1": { + "sha512": "OE0sl1/sQ37bjVsPKKtwQlWDgqaxWgtme3xZz7JssWUzg5JpMIyHgCTY9MVMxOg48fJ1AgGT3tgdH5m/kQ5xhA==", + "type": "package", + "path": "commandlineparser/2.9.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "CommandLine20.png", + "License.md", + "README.md", + "commandlineparser.2.9.1.nupkg.sha512", + "commandlineparser.nuspec", + "lib/net40/CommandLine.dll", + "lib/net40/CommandLine.xml", + "lib/net45/CommandLine.dll", + "lib/net45/CommandLine.xml", + "lib/net461/CommandLine.dll", + "lib/net461/CommandLine.xml", + "lib/netstandard2.0/CommandLine.dll", + "lib/netstandard2.0/CommandLine.xml" + ] + }, + "DnsClient/1.6.1": { + "sha512": "4H/f2uYJOZ+YObZjpY9ABrKZI+JNw3uizp6oMzTXwDw6F+2qIPhpRl/1t68O/6e98+vqNiYGu+lswmwdYUy3gg==", + "type": "package", + "path": "dnsclient/1.6.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "dnsclient.1.6.1.nupkg.sha512", + "dnsclient.nuspec", + "icon.png", + "lib/net45/DnsClient.dll", + "lib/net45/DnsClient.xml", + "lib/net471/DnsClient.dll", + "lib/net471/DnsClient.xml", + "lib/net5.0/DnsClient.dll", + "lib/net5.0/DnsClient.xml", + "lib/netstandard1.3/DnsClient.dll", + "lib/netstandard1.3/DnsClient.xml", + "lib/netstandard2.0/DnsClient.dll", + "lib/netstandard2.0/DnsClient.xml", + "lib/netstandard2.1/DnsClient.dll", + "lib/netstandard2.1/DnsClient.xml" + ] + }, + "Fantasy-Net/2025.2.0": { + "sha512": "vCkduwxkMlH8GozyS+ZlWGLC4nGjFGaL13Ah4w5HL55XAJaAhe+RX+gbSRNBeJf1Uu0cjG2MgVyS4NX7bXdN4g==", + "type": "package", + "path": "fantasy-net/2025.2.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE", + "README.md", + "analyzers/dotnet/cs/Fantasy.SourceGenerator.dll", + "build/Fantasy-Net.props", + "build/Fantasy-Net.targets", + "build/Fantasy.config", + "build/Fantasy.xsd", + "buildTransitive/Fantasy-Net.targets", + "buildTransitive/Fantasy.config", + "buildTransitive/Fantasy.xsd", + "fantasy-net.2025.2.0.nupkg.sha512", + "fantasy-net.nuspec", + "icon.png", + "lib/net8.0/Fantasy-Net.dll", + "lib/net9.0/Fantasy-Net.dll" + ] + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { + "sha512": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "type": "package", + "path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "PACKAGE.md", + "THIRD-PARTY-NOTICES.TXT", + "buildTransitive/net461/Microsoft.Extensions.DependencyInjection.Abstractions.targets", + "buildTransitive/net462/_._", + "buildTransitive/net6.0/_._", + "buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.Abstractions.targets", + "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512", + "microsoft.extensions.dependencyinjection.abstractions.nuspec", + "useSharedDesignerContext.txt" + ] + }, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "sha512": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "type": "package", + "path": "microsoft.extensions.logging.abstractions/8.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "PACKAGE.md", + "THIRD-PARTY-NOTICES.TXT", + "analyzers/dotnet/roslyn3.11/cs/Microsoft.Extensions.Logging.Generators.dll", + "analyzers/dotnet/roslyn3.11/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/Microsoft.Extensions.Logging.Generators.dll", + "analyzers/dotnet/roslyn4.0/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/Microsoft.Extensions.Logging.Generators.dll", + "analyzers/dotnet/roslyn4.4/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", + "buildTransitive/net461/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/net462/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/netcoreapp2.0/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.targets", + "lib/net462/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net462/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/net6.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net6.0/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net7.0/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.xml", + "microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512", + "microsoft.extensions.logging.abstractions.nuspec", + "useSharedDesignerContext.txt" + ] + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "sha512": "iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==", + "type": "package", + "path": "microsoft.identitymodel.abstractions/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Abstractions.dll", + "lib/net462/Microsoft.IdentityModel.Abstractions.xml", + "lib/net472/Microsoft.IdentityModel.Abstractions.dll", + "lib/net472/Microsoft.IdentityModel.Abstractions.xml", + "lib/net6.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net6.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/net8.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net8.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net9.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.xml", + "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512", + "microsoft.identitymodel.abstractions.nuspec" + ] + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "sha512": "4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==", + "type": "package", + "path": "microsoft.identitymodel.jsonwebtokens/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net462/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net472/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net472/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512", + "microsoft.identitymodel.jsonwebtokens.nuspec" + ] + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "sha512": "eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==", + "type": "package", + "path": "microsoft.identitymodel.logging/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Logging.dll", + "lib/net462/Microsoft.IdentityModel.Logging.xml", + "lib/net472/Microsoft.IdentityModel.Logging.dll", + "lib/net472/Microsoft.IdentityModel.Logging.xml", + "lib/net6.0/Microsoft.IdentityModel.Logging.dll", + "lib/net6.0/Microsoft.IdentityModel.Logging.xml", + "lib/net8.0/Microsoft.IdentityModel.Logging.dll", + "lib/net8.0/Microsoft.IdentityModel.Logging.xml", + "lib/net9.0/Microsoft.IdentityModel.Logging.dll", + "lib/net9.0/Microsoft.IdentityModel.Logging.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Logging.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Logging.xml", + "microsoft.identitymodel.logging.8.14.0.nupkg.sha512", + "microsoft.identitymodel.logging.nuspec" + ] + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "sha512": "lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==", + "type": "package", + "path": "microsoft.identitymodel.tokens/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Tokens.dll", + "lib/net462/Microsoft.IdentityModel.Tokens.xml", + "lib/net472/Microsoft.IdentityModel.Tokens.dll", + "lib/net472/Microsoft.IdentityModel.Tokens.xml", + "lib/net6.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net6.0/Microsoft.IdentityModel.Tokens.xml", + "lib/net8.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net8.0/Microsoft.IdentityModel.Tokens.xml", + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net9.0/Microsoft.IdentityModel.Tokens.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.xml", + "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512", + "microsoft.identitymodel.tokens.nuspec" + ] + }, + "Microsoft.NETCore.Platforms/5.0.0": { + "sha512": "VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==", + "type": "package", + "path": "microsoft.netcore.platforms/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/netstandard1.0/_._", + "microsoft.netcore.platforms.5.0.0.nupkg.sha512", + "microsoft.netcore.platforms.nuspec", + "runtime.json", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "Microsoft.Win32.Registry/5.0.0": { + "sha512": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "type": "package", + "path": "microsoft.win32.registry/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/Microsoft.Win32.Registry.dll", + "lib/net461/Microsoft.Win32.Registry.dll", + "lib/net461/Microsoft.Win32.Registry.xml", + "lib/netstandard1.3/Microsoft.Win32.Registry.dll", + "lib/netstandard2.0/Microsoft.Win32.Registry.dll", + "lib/netstandard2.0/Microsoft.Win32.Registry.xml", + "microsoft.win32.registry.5.0.0.nupkg.sha512", + "microsoft.win32.registry.nuspec", + "ref/net46/Microsoft.Win32.Registry.dll", + "ref/net461/Microsoft.Win32.Registry.dll", + "ref/net461/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/Microsoft.Win32.Registry.dll", + "ref/netstandard1.3/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/de/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/es/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/fr/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/it/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/ja/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/ko/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/ru/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/zh-hans/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/zh-hant/Microsoft.Win32.Registry.xml", + "ref/netstandard2.0/Microsoft.Win32.Registry.dll", + "ref/netstandard2.0/Microsoft.Win32.Registry.xml", + "runtimes/win/lib/net46/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/net461/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/net461/Microsoft.Win32.Registry.xml", + "runtimes/win/lib/netstandard1.3/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.xml", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "MongoDB.Bson/3.5.0": { + "sha512": "JGNK6BanLDEifgkvPLqVFCPus5EDCy416pxf1dxUBRSVd3D9+NB3AvMVX190eXlk5/UXuCxpsQv7jWfNKvppBQ==", + "type": "package", + "path": "mongodb.bson/3.5.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net472/MongoDB.Bson.dll", + "lib/net472/MongoDB.Bson.xml", + "lib/net6.0/MongoDB.Bson.dll", + "lib/net6.0/MongoDB.Bson.xml", + "lib/netstandard2.1/MongoDB.Bson.dll", + "lib/netstandard2.1/MongoDB.Bson.xml", + "mongodb.bson.3.5.0.nupkg.sha512", + "mongodb.bson.nuspec", + "packageIcon.png" + ] + }, + "MongoDB.Driver/3.5.0": { + "sha512": "ST90u7psyMkNNOWFgSkexsrB3kPn7Ynl2DlMFj2rJyYuc6SIxjmzu4ufy51yzM+cPVE1SvVcdb5UFobrRw6cMg==", + "type": "package", + "path": "mongodb.driver/3.5.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net472/MongoDB.Driver.dll", + "lib/net472/MongoDB.Driver.xml", + "lib/net6.0/MongoDB.Driver.dll", + "lib/net6.0/MongoDB.Driver.xml", + "lib/netstandard2.1/MongoDB.Driver.dll", + "lib/netstandard2.1/MongoDB.Driver.xml", + "mongodb.driver.3.5.0.nupkg.sha512", + "mongodb.driver.nuspec", + "packageIcon.png" + ] + }, + "Newtonsoft.Json/13.0.4": { + "sha512": "pdgNNMai3zv51W5aq268sujXUyx7SNdE2bj1wZcWjAQrKMFZV260lbqYop1d2GM67JI1huLRwxo9ZqnfF/lC6A==", + "type": "package", + "path": "newtonsoft.json/13.0.4", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "README.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/net6.0/Newtonsoft.Json.dll", + "lib/net6.0/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.4.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "protobuf-net/3.2.56": { + "sha512": "4IPJeTYAMNewlN8MDaFkcmR/9hLhJeo9eARnTh104zh7mf+vXT2gu5MUfUnkSQU+CH578Q6vcdU7LQDQPG6eaw==", + "type": "package", + "path": "protobuf-net/3.2.56", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net462/protobuf-net.dll", + "lib/net462/protobuf-net.xml", + "lib/net8.0/protobuf-net.dll", + "lib/net8.0/protobuf-net.xml", + "lib/netstandard2.0/protobuf-net.dll", + "lib/netstandard2.0/protobuf-net.xml", + "lib/netstandard2.1/protobuf-net.dll", + "lib/netstandard2.1/protobuf-net.xml", + "protobuf-net.3.2.56.nupkg.sha512", + "protobuf-net.nuspec", + "protobuf-net.png", + "readme.md" + ] + }, + "protobuf-net.Core/3.2.56": { + "sha512": "d6QOukTpDzs7zZv9tPnBZMtvHDNeHJQXUhMx54g4urUQsXK3oo9U70H9HvklYq7hlQ4A7AHJl7EVEqyCXXIl8Q==", + "type": "package", + "path": "protobuf-net.core/3.2.56", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net462/protobuf-net.Core.dll", + "lib/net462/protobuf-net.Core.xml", + "lib/net8.0/protobuf-net.Core.dll", + "lib/net8.0/protobuf-net.Core.xml", + "lib/netstandard2.0/protobuf-net.Core.dll", + "lib/netstandard2.0/protobuf-net.Core.xml", + "lib/netstandard2.1/protobuf-net.Core.dll", + "lib/netstandard2.1/protobuf-net.Core.xml", + "protobuf-net.core.3.2.56.nupkg.sha512", + "protobuf-net.core.nuspec", + "protobuf-net.png", + "readme.md" + ] + }, + "SharpCompress/0.30.1": { + "sha512": "XqD4TpfyYGa7QTPzaGlMVbcecKnXy4YmYLDWrU+JIj7IuRNl7DH2END+Ll7ekWIY8o3dAMWLFDE1xdhfIWD1nw==", + "type": "package", + "path": "sharpcompress/0.30.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net461/SharpCompress.dll", + "lib/net5.0/SharpCompress.dll", + "lib/netcoreapp3.1/SharpCompress.dll", + "lib/netstandard2.0/SharpCompress.dll", + "lib/netstandard2.1/SharpCompress.dll", + "sharpcompress.0.30.1.nupkg.sha512", + "sharpcompress.nuspec" + ] + }, + "Snappier/1.0.0": { + "sha512": "rFtK2KEI9hIe8gtx3a0YDXdHOpedIf9wYCEYtBEmtlyiWVX3XlCNV03JrmmAi/Cdfn7dxK+k0sjjcLv4fpHnqA==", + "type": "package", + "path": "snappier/1.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "COPYING.txt", + "lib/net5.0/Snappier.dll", + "lib/net5.0/Snappier.xml", + "lib/netcoreapp3.0/Snappier.dll", + "lib/netcoreapp3.0/Snappier.xml", + "lib/netstandard2.0/Snappier.dll", + "lib/netstandard2.0/Snappier.xml", + "lib/netstandard2.1/Snappier.dll", + "lib/netstandard2.1/Snappier.xml", + "snappier.1.0.0.nupkg.sha512", + "snappier.nuspec" + ] + }, + "System.Buffers/4.5.1": { + "sha512": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==", + "type": "package", + "path": "system.buffers/4.5.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Buffers.dll", + "lib/net461/System.Buffers.xml", + "lib/netcoreapp2.0/_._", + "lib/netstandard1.1/System.Buffers.dll", + "lib/netstandard1.1/System.Buffers.xml", + "lib/netstandard2.0/System.Buffers.dll", + "lib/netstandard2.0/System.Buffers.xml", + "lib/uap10.0.16299/_._", + "ref/net45/System.Buffers.dll", + "ref/net45/System.Buffers.xml", + "ref/netcoreapp2.0/_._", + "ref/netstandard1.1/System.Buffers.dll", + "ref/netstandard1.1/System.Buffers.xml", + "ref/netstandard2.0/System.Buffers.dll", + "ref/netstandard2.0/System.Buffers.xml", + "ref/uap10.0.16299/_._", + "system.buffers.4.5.1.nupkg.sha512", + "system.buffers.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "sha512": "EYGgN/S+HK7S6F3GaaPLFAfK0UzMrkXFyWCvXpQWFYmZln3dqtbyIO7VuTM/iIIPMzkelg8ZLlBPvMhxj6nOAA==", + "type": "package", + "path": "system.identitymodel.tokens.jwt/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/System.IdentityModel.Tokens.Jwt.dll", + "lib/net462/System.IdentityModel.Tokens.Jwt.xml", + "lib/net472/System.IdentityModel.Tokens.Jwt.dll", + "lib/net472/System.IdentityModel.Tokens.Jwt.xml", + "lib/net6.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net6.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/net8.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net8.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net9.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.xml", + "system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512", + "system.identitymodel.tokens.jwt.nuspec" + ] + }, + "System.Memory/4.5.5": { + "sha512": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "type": "package", + "path": "system.memory/4.5.5", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Memory.dll", + "lib/net461/System.Memory.xml", + "lib/netcoreapp2.1/_._", + "lib/netstandard1.1/System.Memory.dll", + "lib/netstandard1.1/System.Memory.xml", + "lib/netstandard2.0/System.Memory.dll", + "lib/netstandard2.0/System.Memory.xml", + "ref/netcoreapp2.1/_._", + "system.memory.4.5.5.nupkg.sha512", + "system.memory.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Runtime.CompilerServices.Unsafe/5.0.0": { + "sha512": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==", + "type": "package", + "path": "system.runtime.compilerservices.unsafe/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net45/System.Runtime.CompilerServices.Unsafe.dll", + "lib/net45/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netstandard1.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netstandard1.0/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/net461/System.Runtime.CompilerServices.Unsafe.dll", + "ref/net461/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard1.0/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard1.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard2.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.xml", + "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512", + "system.runtime.compilerservices.unsafe.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.AccessControl/5.0.0": { + "sha512": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "type": "package", + "path": "system.security.accesscontrol/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/System.Security.AccessControl.dll", + "lib/net461/System.Security.AccessControl.dll", + "lib/net461/System.Security.AccessControl.xml", + "lib/netstandard1.3/System.Security.AccessControl.dll", + "lib/netstandard2.0/System.Security.AccessControl.dll", + "lib/netstandard2.0/System.Security.AccessControl.xml", + "lib/uap10.0.16299/_._", + "ref/net46/System.Security.AccessControl.dll", + "ref/net461/System.Security.AccessControl.dll", + "ref/net461/System.Security.AccessControl.xml", + "ref/netstandard1.3/System.Security.AccessControl.dll", + "ref/netstandard1.3/System.Security.AccessControl.xml", + "ref/netstandard1.3/de/System.Security.AccessControl.xml", + "ref/netstandard1.3/es/System.Security.AccessControl.xml", + "ref/netstandard1.3/fr/System.Security.AccessControl.xml", + "ref/netstandard1.3/it/System.Security.AccessControl.xml", + "ref/netstandard1.3/ja/System.Security.AccessControl.xml", + "ref/netstandard1.3/ko/System.Security.AccessControl.xml", + "ref/netstandard1.3/ru/System.Security.AccessControl.xml", + "ref/netstandard1.3/zh-hans/System.Security.AccessControl.xml", + "ref/netstandard1.3/zh-hant/System.Security.AccessControl.xml", + "ref/netstandard2.0/System.Security.AccessControl.dll", + "ref/netstandard2.0/System.Security.AccessControl.xml", + "ref/uap10.0.16299/_._", + "runtimes/win/lib/net46/System.Security.AccessControl.dll", + "runtimes/win/lib/net461/System.Security.AccessControl.dll", + "runtimes/win/lib/net461/System.Security.AccessControl.xml", + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll", + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.xml", + "runtimes/win/lib/netstandard1.3/System.Security.AccessControl.dll", + "runtimes/win/lib/uap10.0.16299/_._", + "system.security.accesscontrol.5.0.0.nupkg.sha512", + "system.security.accesscontrol.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.Principal.Windows/5.0.0": { + "sha512": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==", + "type": "package", + "path": "system.security.principal.windows/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/System.Security.Principal.Windows.dll", + "lib/net461/System.Security.Principal.Windows.dll", + "lib/net461/System.Security.Principal.Windows.xml", + "lib/netstandard1.3/System.Security.Principal.Windows.dll", + "lib/netstandard2.0/System.Security.Principal.Windows.dll", + "lib/netstandard2.0/System.Security.Principal.Windows.xml", + "lib/uap10.0.16299/_._", + "ref/net46/System.Security.Principal.Windows.dll", + "ref/net461/System.Security.Principal.Windows.dll", + "ref/net461/System.Security.Principal.Windows.xml", + "ref/netcoreapp3.0/System.Security.Principal.Windows.dll", + "ref/netcoreapp3.0/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/System.Security.Principal.Windows.dll", + "ref/netstandard1.3/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/de/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/es/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/fr/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/it/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ja/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ko/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ru/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/zh-hans/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/zh-hant/System.Security.Principal.Windows.xml", + "ref/netstandard2.0/System.Security.Principal.Windows.dll", + "ref/netstandard2.0/System.Security.Principal.Windows.xml", + "ref/uap10.0.16299/_._", + "runtimes/unix/lib/netcoreapp2.0/System.Security.Principal.Windows.dll", + "runtimes/unix/lib/netcoreapp2.0/System.Security.Principal.Windows.xml", + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll", + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.xml", + "runtimes/win/lib/net46/System.Security.Principal.Windows.dll", + "runtimes/win/lib/net461/System.Security.Principal.Windows.dll", + "runtimes/win/lib/net461/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netcoreapp2.0/System.Security.Principal.Windows.dll", + "runtimes/win/lib/netcoreapp2.0/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll", + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netstandard1.3/System.Security.Principal.Windows.dll", + "runtimes/win/lib/uap10.0.16299/_._", + "system.security.principal.windows.5.0.0.nupkg.sha512", + "system.security.principal.windows.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "ZstdSharp.Port/0.7.3": { + "sha512": "U9Ix4l4cl58Kzz1rJzj5hoVTjmbx1qGMwzAcbv1j/d3NzrFaESIurQyg+ow4mivCgkE3S413y+U9k4WdnEIkRA==", + "type": "package", + "path": "zstdsharp.port/0.7.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net461/ZstdSharp.dll", + "lib/net5.0/ZstdSharp.dll", + "lib/net6.0/ZstdSharp.dll", + "lib/net7.0/ZstdSharp.dll", + "lib/netcoreapp3.1/ZstdSharp.dll", + "lib/netstandard2.0/ZstdSharp.dll", + "lib/netstandard2.1/ZstdSharp.dll", + "zstdsharp.port.0.7.3.nupkg.sha512", + "zstdsharp.port.nuspec" + ] + }, + "ThirdParty/1.0.0": { + "type": "project", + "path": "../ThirdParty/ThirdParty.csproj", + "msbuildProject": "../ThirdParty/ThirdParty.csproj" + } + }, + "projectFileDependencyGroups": { + "net9.0": [ + "Fantasy-Net >= 2025.2.0", + "Microsoft.IdentityModel.Tokens >= 8.14.0", + "System.IdentityModel.Tokens.Jwt >= 8.14.0", + "ThirdParty >= 1.0.0" + ] + }, + "packageFolders": { + "C:\\Users\\FIREBAT\\.nuget\\packages\\": {}, + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj", + "projectName": "Entity", + "projectPath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\Entity\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net9.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "projectReferences": { + "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "dependencies": { + "Fantasy-Net": { + "target": "Package", + "version": "[2025.2.0, )" + }, + "Microsoft.IdentityModel.Tokens": { + "target": "Package", + "version": "[8.14.0, )" + }, + "System.IdentityModel.Tokens.Jwt": { + "target": "Package", + "version": "[8.14.0, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/Entity/obj/project.nuget.cache b/Entity/obj/project.nuget.cache new file mode 100644 index 0000000..2b32b07 --- /dev/null +++ b/Entity/obj/project.nuget.cache @@ -0,0 +1,34 @@ +{ + "version": 2, + "dgSpecHash": "5DJdEeWOOl4=", + "success": true, + "projectFilePath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj", + "expectedPackageFiles": [ + "C:\\Users\\FIREBAT\\.nuget\\packages\\commandlineparser\\2.9.1\\commandlineparser.2.9.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\dnsclient\\1.6.1\\dnsclient.1.6.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\fantasy-net\\2025.2.0\\fantasy-net.2025.2.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\8.0.0\\microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\8.0.0\\microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.abstractions\\8.14.0\\microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.jsonwebtokens\\8.14.0\\microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.logging\\8.14.0\\microsoft.identitymodel.logging.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.tokens\\8.14.0\\microsoft.identitymodel.tokens.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.netcore.platforms\\5.0.0\\microsoft.netcore.platforms.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.win32.registry\\5.0.0\\microsoft.win32.registry.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\mongodb.bson\\3.5.0\\mongodb.bson.3.5.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\mongodb.driver\\3.5.0\\mongodb.driver.3.5.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\newtonsoft.json\\13.0.4\\newtonsoft.json.13.0.4.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\protobuf-net\\3.2.56\\protobuf-net.3.2.56.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\protobuf-net.core\\3.2.56\\protobuf-net.core.3.2.56.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\sharpcompress\\0.30.1\\sharpcompress.0.30.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\snappier\\1.0.0\\snappier.1.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.buffers\\4.5.1\\system.buffers.4.5.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.identitymodel.tokens.jwt\\8.14.0\\system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.memory\\4.5.5\\system.memory.4.5.5.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\5.0.0\\system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.security.accesscontrol\\5.0.0\\system.security.accesscontrol.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.security.principal.windows\\5.0.0\\system.security.principal.windows.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\zstdsharp.port\\0.7.3\\zstdsharp.port.0.7.3.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/Entity/obj/project.packagespec.json b/Entity/obj/project.packagespec.json new file mode 100644 index 0000000..4a69c86 --- /dev/null +++ b/Entity/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"D:\\work\\Fishing2Server\\Entity\\Entity.csproj","projectName":"Entity","projectPath":"D:\\work\\Fishing2Server\\Entity\\Entity.csproj","outputPath":"D:\\work\\Fishing2Server\\Entity\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"],"originalTargetFrameworks":["net9.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net9.0":{"targetAlias":"net9.0","projectReferences":{"D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj":{"projectPath":"D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj"}}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"},"SdkAnalysisLevel":"9.0.300"}"frameworks":{"net9.0":{"targetAlias":"net9.0","dependencies":{"Fantasy-Net":{"target":"Package","version":"[2025.2.0, )"},"Microsoft.IdentityModel.Tokens":{"target":"Package","version":"[8.14.0, )"},"System.IdentityModel.Tokens.Jwt":{"target":"Package","version":"[8.14.0, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/Entity/obj/rider.project.model.nuget.info b/Entity/obj/rider.project.model.nuget.info new file mode 100644 index 0000000..f10fabb --- /dev/null +++ b/Entity/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17628533859030116 \ No newline at end of file diff --git a/Entity/obj/rider.project.restore.info b/Entity/obj/rider.project.restore.info new file mode 100644 index 0000000..3a75255 --- /dev/null +++ b/Entity/obj/rider.project.restore.info @@ -0,0 +1 @@ +17628541514897177 \ No newline at end of file diff --git a/Examples/Client/Unity/Assets/Scripts/Hotfix/Generate/NetworkProtocol/RoamingType.cs b/Examples/Client/Unity/Assets/Scripts/Hotfix/Generate/NetworkProtocol/RoamingType.cs deleted file mode 100644 index ce3008c..0000000 --- a/Examples/Client/Unity/Assets/Scripts/Hotfix/Generate/NetworkProtocol/RoamingType.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Collections.Generic; -namespace Fantasy -{ - // Roaming协议定义(需要定义10000以上、因为10000以内的框架预留) - public static class RoamingType - { - } -} diff --git a/Examples/Config/NetworkProtocol/RoamingType.Config b/Examples/Config/NetworkProtocol/RoamingType.Config deleted file mode 100644 index 3b89ab1..0000000 --- a/Examples/Config/NetworkProtocol/RoamingType.Config +++ /dev/null @@ -1 +0,0 @@ -// Roaming协议定义(需要定义10000以上、因为10000以内的框架预留) diff --git a/Examples/Config/NetworkProtocol/RouteType.Config b/Examples/Config/NetworkProtocol/RouteType.Config deleted file mode 100644 index b8424a1..0000000 --- a/Examples/Config/NetworkProtocol/RouteType.Config +++ /dev/null @@ -1 +0,0 @@ -// Route协议定义(需要定义1000以上、因为1000以内的框架预留) diff --git a/Examples/Server/Entity/Generate/NetworkProtocol/RoamingType.cs b/Examples/Server/Entity/Generate/NetworkProtocol/RoamingType.cs deleted file mode 100644 index ce3008c..0000000 --- a/Examples/Server/Entity/Generate/NetworkProtocol/RoamingType.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Collections.Generic; -namespace Fantasy -{ - // Roaming协议定义(需要定义10000以上、因为10000以内的框架预留) - public static class RoamingType - { - } -} diff --git a/Fantasy/Fantasy.Benchmark/ConsoleLog.cs b/Fantasy/Fantasy.Benchmark/ConsoleLog.cs deleted file mode 100644 index 4fa540f..0000000 --- a/Fantasy/Fantasy.Benchmark/ConsoleLog.cs +++ /dev/null @@ -1,138 +0,0 @@ - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy -{ - /// - /// 标准的控制台Log - /// - public sealed class ConsoleLog : ILog - { - - /// - /// 记录跟踪级别的日志消息。 - /// - /// 日志消息。 - public void Trace(string message) - { - System.Console.ForegroundColor = ConsoleColor.White; - System.Console.WriteLine(message); - } - - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - public void Warning(string message) - { - System.Console.ForegroundColor = ConsoleColor.Yellow; - System.Console.WriteLine(message); - } - - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - public void Info(string message) - { - System.Console.ForegroundColor = ConsoleColor.Gray; - System.Console.WriteLine(message); - } - - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - public void Debug(string message) - { - System.Console.ForegroundColor = ConsoleColor.DarkGreen; - System.Console.WriteLine(message); - } - - /// - /// 记录错误级别的日志消息。 - /// - /// 日志消息。 - public void Error(string message) - { - System.Console.ForegroundColor = ConsoleColor.DarkRed; - System.Console.WriteLine(message); - } - - /// - /// 记录严重错误级别的日志消息。 - /// - /// 日志消息。 - public void Fatal(string message) - { - System.Console.ForegroundColor = ConsoleColor.Red; - System.Console.WriteLine(message); - } - - /// - /// 记录跟踪级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Trace(string message, params object[] args) - { - System.Console.ForegroundColor = ConsoleColor.White; - System.Console.WriteLine(message, args); - } - - /// - /// 记录警告级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Warning(string message, params object[] args) - { - System.Console.ForegroundColor = ConsoleColor.Yellow; - System.Console.WriteLine(message, args); - } - - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Info(string message, params object[] args) - { - System.Console.ForegroundColor = ConsoleColor.Gray; - System.Console.WriteLine(message, args); - } - - /// - /// 记录调试级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Debug(string message, params object[] args) - { - System.Console.ForegroundColor = ConsoleColor.DarkGreen; - System.Console.WriteLine(message, args); - } - - /// - /// 记录错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Error(string message, params object[] args) - { - System.Console.ForegroundColor = ConsoleColor.DarkRed; - System.Console.WriteLine(message, args); - } - - /// - /// 记录严重错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Fatal(string message, params object[] args) - { - System.Console.ForegroundColor = ConsoleColor.Red; - System.Console.WriteLine(message, args); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Benchmark/Fantasy.Benchmark.csproj b/Fantasy/Fantasy.Benchmark/Fantasy.Benchmark.csproj deleted file mode 100644 index d44402a..0000000 --- a/Fantasy/Fantasy.Benchmark/Fantasy.Benchmark.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - Exe - enable - enable - net8.0;net9.0 - default - - - - TRACE;FANTASY_CONSOLE - true - - - - TRACE;FANTASY_CONSOLE - true - - - - - - - - - - - - - - - diff --git a/Fantasy/Fantasy.Benchmark/NetworkBenchmark.cs b/Fantasy/Fantasy.Benchmark/NetworkBenchmark.cs deleted file mode 100644 index 18e3ea1..0000000 --- a/Fantasy/Fantasy.Benchmark/NetworkBenchmark.cs +++ /dev/null @@ -1,45 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using BenchmarkDotNet.Running; -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Platform.Console; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Benchmark; -[SimpleJob(RuntimeMoniker.Net80, baseline: true)] -public class NetworkBenchmark -{ - private static Scene _scene; - private static Session _session; - private readonly BenchmarkRequest _benchmarkRequest = new BenchmarkRequest(); - - public static async FTask Initialize() - { - // 注册日志实例到框架中 - Log.Register(new ConsoleLog()); - // 初始化框架 - await Entry.Initialize(); - // 执行StartUpdate方法 - Entry.StartUpdate(); - _scene = await Entry.CreateScene(); - // 创建远程连接 - _session = _scene.Connect("127.0.0.1:20000", NetworkProtocolType.WebSocket, - () => - { - Log.Debug("连接到目标服务器成功"); - var summary = BenchmarkRunner.Run(); - Console.WriteLine(summary); - }, - () => { Log.Debug("无法连接到目标服务器"); }, - () => { Log.Debug("与服务器断开连接"); }, false); - } - - [Benchmark] - public async FTask Call() - { - await _session.Call(_benchmarkRequest); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Benchmark/Program.cs b/Fantasy/Fantasy.Benchmark/Program.cs deleted file mode 100644 index 30d8cf3..0000000 --- a/Fantasy/Fantasy.Benchmark/Program.cs +++ /dev/null @@ -1,2 +0,0 @@ -Fantasy.Benchmark.NetworkBenchmark.Initialize().Coroutine(); -Console.ReadKey(); \ No newline at end of file diff --git a/Fantasy/Fantasy.Benchmark/README.md b/Fantasy/Fantasy.Benchmark/README.md deleted file mode 100644 index 8315cc4..0000000 --- a/Fantasy/Fantasy.Benchmark/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Fantasy.Benchmark -使用 Fantasy.Benchmark 工具,我们能够快速评估框架网络的处理性能。目前,该工具提供的基准测试主要集中在 RPC(远程过程调用)消息 方面。这一项测试能够有效测量系统在处理远程调用时的响应时间、吞吐量和资源利用率,帮助开发者优化网络通信性能,确保在高负载情况下系统依然能够稳定运行 -## 操作步骤 -- 1.打开位于 Examples/Server/Server.sln 的解决方案文件。 -- 2.在解决方案中选择并启动 Main 项目。 -- 3.接着,启动 Fantasy.Benchmark 应用程序,并耐心等待其测试结果的生成。 diff --git a/Fantasy/Fantasy.Net/Fantasy.Net.sln b/Fantasy/Fantasy.Net/Fantasy.Net.sln deleted file mode 100644 index 1abdc06..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net.sln +++ /dev/null @@ -1,16 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fantasy.Net", "Fantasy.Net\Fantasy.Net.csproj", "{636FBF87-A6D2-4A31-86FF-F4157F558C95}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {636FBF87-A6D2-4A31-86FF-F4157F558C95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {636FBF87-A6D2-4A31-86FF-F4157F558C95}.Debug|Any CPU.Build.0 = Debug|Any CPU - {636FBF87-A6D2-4A31-86FF-F4157F558C95}.Release|Any CPU.ActiveCfg = Release|Any CPU - {636FBF87-A6D2-4A31-86FF-F4157F558C95}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Fantasy-Net.targets b/Fantasy/Fantasy.Net/Fantasy.Net/Fantasy-Net.targets deleted file mode 100644 index 5426ed6..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Fantasy-Net.targets +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Fantasy.Net.csproj b/Fantasy/Fantasy.Net/Fantasy.Net/Fantasy.Net.csproj deleted file mode 100644 index be19e19..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Fantasy.Net.csproj +++ /dev/null @@ -1,60 +0,0 @@ - - - - Fantasy-Net - 2024.2.26 - Fantasy-Net - qq362946 - qq362946 - ../../nupkg - false - - Fantasy is a high-performance network development framework based on .NET, supporting mainstream protocols. It is designed for development teams or individuals needing a quick start, scalability, and a distributed, cross-platform solution at the commercial level. Fantasy aims to provide easy-to-use tools while ensuring high system performance and scalability. - Copyright 2026 qq362946 - LICENSE - README.md - https://www.code-fantasy.com/ - https://github.com/qq362946/Fantasy - git - Net, c#, Server, Game, GameServer, Fantasy , Network - icon.png - enable - enable - Fantasy-Net - net8.0;net9.0 - default - - - - TRACE;FANTASY_NET - true - true - bin\Debug\net8.0\Fantasy.Net.xml - - - - TRACE;FANTASY_NET - true - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/LICENSE b/Fantasy/Fantasy.Net/Fantasy.Net/LICENSE deleted file mode 100644 index 24a69b2..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -MIT License - -Copyright (c) 2023 qq362946 - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -However, the following entity is explicitly prohibited from using, copying, modifying, or distributing the Software or any of its portions: - -泰课在线(https://www.taikr.com/) -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/README.md b/Fantasy/Fantasy.Net/Fantasy.Net/README.md deleted file mode 100644 index 582e668..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Fantasy -#### 框架支持TCP\KCP\WebSocket\http(支持Unity发布成H5)三种网络协议,采用的Protobuf/MemoryPack/Bson做为消息的序列化方案。 -#### Fantasy是基于.NET的高性能网络开发框架,支持主流协议,前后端分离,适合需要快速上手、可扩展、分布式全平台商业级解决方案的开发团队或个人。它旨在提供易用工具,同时保证系统的高性能和扩展性。 -## 导航 -* [Fantasy介绍网站](https://www.code-fantasy.com/) -* [Fantasy的API文档](https://www.code-fantasy.com/doc/api/Fantasy.html) -* [入门视频观看地址](https://space.bilibili.com/382126312) -## 快速上手 -* 01.快速入门 - * [1.1.获得Fantasy](https://www.code-fantasy.com/top/download-fantasy/) - * [1.2.安装Fantasy](https://www.code-fantasy.com/top/creating-your-app/) - * [1.3.Fantasy的网络](https://www.code-fantasy.com/top/use-network/) - * [1.4.Fantasy的配置文件](https://www.code-fantasy.com/top/config-file/) - * [1.5.Fantasy的命令行参数](https://www.code-fantasy.com/top/command-line-parameter/) - * [1.6.Fantasy的导表工具](https://www.code-fantasy.com/top/guidance/) - * [1.7.如何升级到最新版](https://www.code-fantasy.com/top/upgrade/) -* 02.网络通信 - * [2.1.客户端服务器之间发送消息](https://www.code-fantasy.com/network/session/) - * [2.2.服务器之间发送消息](https://www.code-fantasy.com/network/networkmessagingomponent/) - * [2.3.定义通信协议](https://www.code-fantasy.com/network/network-protocols/) - * [2.4.Route通信协议](https://www.code-fantasy.com/network/network-route/) - * [2.5.Addressable通信协议](https://www.code-fantasy.com/network/network-addressable/) -* 03.系统组件 - * [3.1.ECS系统](https://www.code-fantasy.com/core/ecs/) - * [3.2.事件系统](https://www.code-fantasy.com/core/event/) - * [3.3.任务系统](https://www.code-fantasy.com/core/task/) - * [3.4.异步协程锁](https://www.code-fantasy.com/core/lock/) - * [3.5.数据库](https://www.code-fantasy.com/core/db/) -* [更新日志](https://www.code-fantasy.com/changelog/) -* [API文档](https://www.code-fantasy.com/doc/api/Fantasy.html) -* [常见问题](https://www.code-fantasy.com/question/) - -## 交流与讨论: -__讨论QQ群 : Fantasy服务器开发交流群 569888673 __ \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Assembly/AssemblyInfo.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Assembly/AssemblyInfo.cs deleted file mode 100644 index 3957539..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Assembly/AssemblyInfo.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Fantasy.DataStructure.Collection; - -// ReSharper disable CollectionNeverQueried.Global -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Assembly -{ - /// - /// AssemblyInfo提供有关程序集和类型的信息 - /// - public sealed class AssemblyInfo - { - /// - /// 唯一标识 - /// - public readonly long AssemblyIdentity; - /// - /// 获取或设置与此程序集相关联的 实例。 - /// - public System.Reflection.Assembly Assembly { get; private set; } - /// - /// 程序集类型集合,获取一个列表,包含从程序集加载的所有类型。 - /// - public readonly List AssemblyTypeList = new List(); - /// - /// 程序集类型分组集合,获取一个分组列表,将接口类型映射到实现这些接口的类型。 - /// - public readonly OneToManyList AssemblyTypeGroupList = new OneToManyList(); - - /// - /// 初始化 类的新实例。 - /// - /// - public AssemblyInfo(long assemblyIdentity) - { - AssemblyIdentity = assemblyIdentity; - } - - /// - /// 从指定的程序集加载类型信息并进行分类。 - /// - /// 要加载信息的程序集。 - public void Load(System.Reflection.Assembly assembly) - { - Assembly = assembly; - var assemblyTypes = assembly.GetTypes().ToList(); - - foreach (var type in assemblyTypes) - { - if (type.IsAbstract || type.IsInterface) - { - continue; - } - - var interfaces = type.GetInterfaces(); - - foreach (var interfaceType in interfaces) - { - AssemblyTypeGroupList.Add(interfaceType, type); - } - } - - AssemblyTypeList.AddRange(assemblyTypes); - } - - /// - /// 重新加载程序集的类型信息。 - /// - /// - public void ReLoad(System.Reflection.Assembly assembly) - { - Unload(); - Load(assembly); - } - - /// - /// 卸载程序集的类型信息。 - /// - public void Unload() - { - AssemblyTypeList.Clear(); - AssemblyTypeGroupList.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Assembly/AssemblySystem.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Assembly/AssemblySystem.cs deleted file mode 100644 index deb9da6..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Assembly/AssemblySystem.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Security.Cryptography; -using System.Text; -using Fantasy.Async; -using Fantasy.Helper; -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8603 -#pragma warning disable CS8618 -namespace Fantasy.Assembly -{ - /// - /// 管理程序集加载和卸载的帮助类。 - /// - public static class AssemblySystem - { -#if FANTASY_WEBGL - private static readonly List AssemblySystems = new List(); - private static readonly Dictionary AssemblyList = new Dictionary(); -#else - private static readonly ConcurrentQueue AssemblySystems = new ConcurrentQueue(); - private static readonly ConcurrentDictionary AssemblyList = new ConcurrentDictionary(); -#endif - /// - /// 初始化 AssemblySystem。(仅限内部) - /// - /// - internal static async FTask InnerInitialize(params System.Reflection.Assembly[] assemblies) - { - await LoadAssembly(typeof(AssemblySystem).Assembly); - foreach (var assembly in assemblies) - { - await LoadAssembly(assembly); - } - } - - /// - /// 加载指定的程序集,并触发相应的事件。 - /// - /// 要加载的程序集。 - /// 如果当前Domain中已经存在同名的Assembly,使用Domain中的程序集。 - public static async FTask LoadAssembly(System.Reflection.Assembly assembly, bool isCurrentDomain = true) - { - if (isCurrentDomain) - { - var currentDomainAssemblies = System.AppDomain.CurrentDomain.GetAssemblies(); - var currentAssembly = currentDomainAssemblies.FirstOrDefault(d => d.GetName().Name == assembly.GetName().Name); - if (currentAssembly != null) - { - assembly = currentAssembly; - } - } - - var assemblyIdentity = AssemblyIdentity(assembly); - - if (AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo)) - { - assemblyInfo.ReLoad(assembly); - foreach (var assemblySystem in AssemblySystems) - { - await assemblySystem.ReLoad(assemblyIdentity); - } - } - else - { - assemblyInfo = new AssemblyInfo(assemblyIdentity); - assemblyInfo.Load(assembly); - AssemblyList.TryAdd(assemblyIdentity, assemblyInfo); - foreach (var assemblySystem in AssemblySystems) - { - await assemblySystem.Load(assemblyIdentity); - } - } - } - - /// - /// 卸载程序集 - /// - /// - public static async FTask UnLoadAssembly(System.Reflection.Assembly assembly) - { - var assemblyIdentity = AssemblyIdentity(assembly); - - if (!AssemblyList.Remove(assemblyIdentity, out var assemblyInfo)) - { - return; - } - - assemblyInfo.Unload(); - foreach (var assemblySystem in AssemblySystems) - { - await assemblySystem.OnUnLoad(assemblyIdentity); - } - } - - /// - /// 将AssemblySystem接口的object注册到程序集管理中心 - /// - /// - public static async FTask Register(object obj) - { - if (obj is not IAssembly assemblySystem) - { - return; - } -#if FANTASY_WEBGL - AssemblySystems.Add(assemblySystem); -#else - AssemblySystems.Enqueue(assemblySystem); -#endif - foreach (var (assemblyIdentity, _) in AssemblyList) - { - await assemblySystem.Load(assemblyIdentity); - } - } - - /// - /// 程序集管理中心卸载注册的Load、ReLoad、UnLoad的接口 - /// - /// - public static void UnRegister(object obj) - { - if (obj is not IAssembly assemblySystem) - { - return; - } -#if FANTASY_WEBGL - AssemblySystems.Remove(assemblySystem); -#else - var count = AssemblySystems.Count; - - for (var i = 0; i < count; i++) - { - if (!AssemblySystems.TryDequeue(out var removeAssemblySystem)) - { - continue; - } - - if (removeAssemblySystem == assemblySystem) - { - break; - } - - AssemblySystems.Enqueue(removeAssemblySystem); - } -#endif - } - - /// - /// 获取所有已加载程序集中的所有类型。 - /// - /// 所有已加载程序集中的类型。 - public static IEnumerable ForEach() - { - foreach (var (_, assemblyInfo) in AssemblyList) - { - foreach (var type in assemblyInfo.AssemblyTypeList) - { - yield return type; - } - } - } - - /// - /// 获取指定程序集中的所有类型。 - /// - /// 程序集唯一标识。 - /// 指定程序集中的类型。 - public static IEnumerable ForEach(long assemblyIdentity) - { - if (!AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo)) - { - yield break; - } - - foreach (var type in assemblyInfo.AssemblyTypeList) - { - yield return type; - } - } - - /// - /// 获取所有已加载程序集中实现指定类型的所有类型。 - /// - /// 要查找的基类或接口类型。 - /// 所有已加载程序集中实现指定类型的类型。 - public static IEnumerable ForEach(Type findType) - { - foreach (var (_, assemblyInfo) in AssemblyList) - { - if (!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType, out var assemblyLoad)) - { - continue; - } - - foreach (var type in assemblyLoad) - { - yield return type; - } - } - } - - /// - /// 获取指定程序集中实现指定类型的所有类型。 - /// - /// 程序集唯一标识。 - /// 要查找的基类或接口类型。 - /// 指定程序集中实现指定类型的类型。 - public static IEnumerable ForEach(long assemblyIdentity, Type findType) - { - if (!AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo)) - { - yield break; - } - - if (!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType, out var assemblyLoad)) - { - yield break; - } - - foreach (var type in assemblyLoad) - { - yield return type; - } - } - - /// - /// 获取指定程序集的实例。 - /// - /// 程序集名称。 - /// 指定程序集的实例,如果未加载则返回 null。 - public static System.Reflection.Assembly GetAssembly(long assemblyIdentity) - { - return !AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo) ? null : assemblyInfo.Assembly; - } - - /// - /// 获取当前框架注册的Assembly - /// - /// - public static IEnumerable ForEachAssembly - { - get - { - foreach (var (_, assemblyInfo) in AssemblyList) - { - yield return assemblyInfo.Assembly; - } - } - } - - /// - /// 根据Assembly的强命名计算唯一标识。 - /// - /// - /// - private static long AssemblyIdentity(System.Reflection.Assembly assembly) - { - return HashCodeHelper.ComputeHash64(assembly.GetName().Name); - } - - /// - /// 释放资源,卸载所有加载的程序集。 - /// - public static void Dispose() - { - DisposeAsync().Coroutine(); - } - - private static async FTask DisposeAsync() - { - foreach (var (_, assemblyInfo) in AssemblyList.ToArray()) - { - await UnLoadAssembly(assemblyInfo.Assembly); - } - - AssemblyList.Clear(); - AssemblySystems.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Assembly/IAssembly.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Assembly/IAssembly.cs deleted file mode 100644 index 185e037..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Assembly/IAssembly.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Assembly -{ - /// - /// 实现这个接口、会再程序集首次加载、卸载、重载的时候调用 - /// - public interface IAssembly : IDisposable - { - /// - /// 程序集加载时调用 - /// - /// 程序集标识 - public FTask Load(long assemblyIdentity); - /// - /// 程序集重新加载的时候调用 - /// - /// 程序集标识 - public FTask ReLoad(long assemblyIdentity); - /// - /// 卸载的时候调用 - /// - /// 程序集标识 - public FTask OnUnLoad(long assemblyIdentity); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Benchmark/Handler/BenchmarkRequestHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Benchmark/Handler/BenchmarkRequestHandler.cs deleted file mode 100644 index 8532547..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Benchmark/Handler/BenchmarkRequestHandler.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Benchmark.Handler; - -/// -/// BenchmarkRequestHandler -/// -public sealed class BenchmarkRequestHandler : MessageRPC -{ - /// - /// Run方法 - /// - /// - /// - /// - /// - protected override async FTask Run(Session session, BenchmarkRequest request, BenchmarkResponse response, Action reply) - { - await FTask.CompletedTask; - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/DataBaseType.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/DataBaseType.cs deleted file mode 100644 index 2fb03ec..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/DataBaseType.cs +++ /dev/null @@ -1,20 +0,0 @@ -// ReSharper disable CheckNamespace -// ReSharper disable InconsistentNaming -#if FANTASY_NET -namespace Fantasy.DataBase; - -/// -/// 数据库类型 -/// -public enum DataBaseType -{ - /// - /// 默认 - /// - None = 0, - /// - /// MongoDB - /// - MongoDB = 1 -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/IDataBase.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/IDataBase.cs deleted file mode 100644 index 6a2fe8b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/IDataBase.cs +++ /dev/null @@ -1,210 +0,0 @@ -#if FANTASY_NET -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using Fantasy.Async; -using Fantasy.Entitas; -using MongoDB.Driver; -// ReSharper disable InconsistentNaming -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -#pragma warning disable CS8625 - -namespace Fantasy.DataBase -{ - /// - /// 数据库设置助手 - /// - public static class DataBaseSetting - { - /// - /// 初始化自定义委托,当设置了这个委托后,就不会自动创建MongoClient,需要自己在委托里创建MongoClient。 - /// - public static Func? MongoDBCustomInitialize; - } - - /// - /// MongoDB自定义连接参数 - /// - public sealed class DataBaseCustomConfig - { - /// - /// 当前Scene - /// - public Scene Scene; - /// - /// 连接字符串 - /// - public string ConnectionString; - /// - /// 数据库名字 - /// - public string DBName; - } - - /// - /// 表示用于执行各种数据库操作的数据库接口。 - /// - public interface IDataBase : IDisposable - { - /// - /// 获得当前数据的类型 - /// - public DataBaseType GetDataBaseType { get;} - /// - /// 获得对应数据的操作实例 - /// - /// 如MongoDB就是IMongoDatabase - public object GetDataBaseInstance { get;} - /// - /// 初始化数据库连接。 - /// - IDataBase Initialize(Scene scene, string connectionString, string dbName); - /// - /// 在指定的集合中检索类型 的实体数量。 - /// - FTask Count(string collection = null) where T : Entity; - /// - /// 在指定的集合中检索满足给定筛选条件的类型 的实体数量。 - /// - FTask Count(Expression> filter, string collection = null) where T : Entity; - /// - /// 检查指定集合中是否存在类型 的实体。 - /// - FTask Exist(string collection = null) where T : Entity; - /// - /// 检查指定集合中是否存在满足给定筛选条件的类型 的实体。 - /// - FTask Exist(Expression> filter, string collection = null) where T : Entity; - /// - /// 从指定集合中检索指定 ID 的类型 的实体,不锁定。 - /// - FTask QueryNotLock(long id, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 从指定集合中检索指定 ID 的类型 的实体。 - /// - FTask Query(long id, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 按页查询满足给定筛选条件的类型 的实体数量和日期。 - /// - FTask<(int count, List dates)> QueryCountAndDatesByPage(Expression> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 按页查询满足给定筛选条件的类型 的实体数量和日期。 - /// - FTask<(int count, List dates)> QueryCountAndDatesByPage(Expression> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 分页查询指定集合中满足给定筛选条件的类型 的实体列表。 - /// - FTask> QueryByPage(Expression> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 分页查询指定集合中满足给定筛选条件的类型 的实体列表,仅返回指定列的数据。 - /// - FTask> QueryByPage(Expression> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 从指定集合中按页查询满足给定筛选条件的类型 的实体列表,按指定字段排序。 - /// - FTask> QueryByPageOrderBy(Expression> filter, int pageIndex, int pageSize, Expression> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 检索满足给定筛选条件的类型 的第一个实体,从指定集合中。 - /// - FTask First(Expression> filter, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 查询指定集合中满足给定 JSON 查询字符串的类型 的第一个实体,仅返回指定列的数据。 - /// - FTask First(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 从指定集合中按页查询满足给定筛选条件的类型 的实体列表,按指定字段排序。 - /// - FTask> QueryOrderBy(Expression> filter, Expression> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 从指定集合中按页查询满足给定筛选条件的类型 的实体列表。 - /// - FTask> Query(Expression> filter, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 查询指定集合中满足给定筛选条件的类型 实体列表,仅返回指定字段的数据。 - /// - FTask> Query(Expression> filter, Expression>[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 查询指定 ID 的多个集合,将结果存储在给定的实体列表中。 - /// - FTask Query(long id, List collectionNames, List result, bool isDeserialize = false); - /// - /// 根据给定的 JSON 查询字符串查询指定集合中的类型 实体列表。 - /// - FTask> QueryJson(string json, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 根据给定的 JSON 查询字符串查询指定集合中的类型 实体列表,仅返回指定列的数据。 - /// - FTask> QueryJson(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 根据给定的 JSON 查询字符串查询指定集合中的类型 实体列表,通过指定的任务 ID 进行标识。 - /// - FTask> QueryJson(long taskId, string json, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 查询指定集合中满足给定筛选条件的类型 实体列表,仅返回指定列的数据。 - /// - FTask> Query(Expression> filter, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 保存类型 实体到指定集合中,如果集合不存在将自动创建。 - /// - FTask Save(T entity, string collection = null) where T : Entity, new(); - /// - /// 保存一组实体到数据库中,根据实体列表的 ID 进行区分和存储。 - /// - FTask Save(long id, List entities); - /// - /// 通过事务会话将类型 实体保存到指定集合中,如果集合不存在将自动创建。 - /// - FTask Save(object transactionSession, T entity, string collection = null) where T : Entity; - /// - /// 向指定集合中插入一个类型 实体,如果集合不存在将自动创建。 - /// - FTask Insert(T entity, string collection = null) where T : Entity, new(); - /// - /// 批量插入一组类型 实体到指定集合中,如果集合不存在将自动创建。 - /// - FTask InsertBatch(IEnumerable list, string collection = null) where T : Entity, new(); - /// - /// 通过事务会话,批量插入一组类型 实体到指定集合中,如果集合不存在将自动创建。 - /// - FTask InsertBatch(object transactionSession, IEnumerable list, string collection = null) where T : Entity, new(); - /// - /// 通过事务会话,根据指定的 ID 从数据库中删除指定类型 实体。 - /// - FTask Remove(object transactionSession, long id, string collection = null) where T : Entity, new(); - /// - /// 根据指定的 ID 从数据库中删除指定类型 实体。 - /// - FTask Remove(long id, string collection = null) where T : Entity, new(); - /// - /// 通过事务会话,根据给定的筛选条件从数据库中删除指定类型 实体。 - /// - FTask Remove(long coroutineLockQueueKey, object transactionSession, Expression> filter, string collection = null) where T : Entity, new(); - /// - /// 根据给定的筛选条件从数据库中删除指定类型 实体。 - /// - FTask Remove(long coroutineLockQueueKey, Expression> filter, string collection = null) where T : Entity, new(); - /// - /// 根据给定的筛选条件计算指定集合中类型 实体某个属性的总和。 - /// - FTask Sum(Expression> filter, Expression> sumExpression, string collection = null) where T : Entity; - /// - /// 在指定的集合中创建索引,以提高类型 实体的查询性能。 - /// - FTask CreateIndex(string collection, params object[] keys) where T : Entity; - /// - /// 在默认集合中创建索引,以提高类型 实体的查询性能。 - /// - FTask CreateIndex(params object[] keys) where T : Entity; - /// - /// 创建指定类型 的数据库,用于存储实体。 - /// - FTask CreateDB() where T : Entity; - /// - /// 根据指定类型创建数据库,用于存储实体。 - /// - FTask CreateDB(Type type); - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/MongoDataBase.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/MongoDataBase.cs deleted file mode 100644 index 49948f4..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/MongoDataBase.cs +++ /dev/null @@ -1,1081 +0,0 @@ -#if FANTASY_NET -using System.Linq.Expressions; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; -using Fantasy.Helper; -using Fantasy.Serialize; -using MongoDB.Bson; -using MongoDB.Driver; -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.DataBase -{ - /// - /// 使用 MongoDB 数据库的实现。 - /// - public sealed class MongoDataBase : IDataBase - { - private const int DefaultTaskSize = 1024; - private Scene _scene; - private MongoClient _mongoClient; - private ISerialize _serializer; - private IMongoDatabase _mongoDatabase; - private CoroutineLock _dataBaseLock; - private readonly HashSet _collections = new HashSet(); - /// - /// 获得当前数据的类型 - /// - public DataBaseType GetDataBaseType { get; } = DataBaseType.MongoDB; - /// - /// 获得对应数据的操作实例 - /// - public object GetDataBaseInstance => _mongoDatabase; - /// - /// 初始化 MongoDB 数据库连接并记录所有集合名。 - /// - /// 场景对象。 - /// 数据库连接字符串。 - /// 数据库名称。 - /// 初始化后的数据库实例。 - public IDataBase Initialize(Scene scene, string connectionString, string dbName) - { - _scene = scene; - _mongoClient = DataBaseSetting.MongoDBCustomInitialize != null - ? DataBaseSetting.MongoDBCustomInitialize(new DataBaseCustomConfig() - { - Scene = scene, ConnectionString = connectionString, DBName = dbName - }) - : new MongoClient(connectionString); - _mongoDatabase = _mongoClient.GetDatabase(dbName); - _dataBaseLock = scene.CoroutineLockComponent.Create(GetType().TypeHandle.Value.ToInt64()); - // 记录所有集合名 - _collections.UnionWith(_mongoDatabase.ListCollectionNames().ToList()); - _serializer = SerializerManager.GetSerializer(FantasySerializerType.Bson); - return this; - } - - /// - /// 销毁释放资源。 - /// - public void Dispose() - { - // 优先释放协程锁。 - _dataBaseLock.Dispose(); - // 清理资源。 - _scene = null; - _serializer = null; - _mongoDatabase = null; - _dataBaseLock = null; - _collections.Clear(); - _mongoClient.Dispose(); - } - - #region Other - - /// - /// 对满足条件的文档中的某个数值字段进行求和操作。 - /// - /// 实体类型。 - /// 用于筛选文档的表达式。 - /// 要对其进行求和的字段表达式。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 满足条件的文档中指定字段的求和结果。 - public async FTask Sum(Expression> filter, Expression> sumExpression, string collection = null) where T : Entity - { - var member = (MemberExpression)((UnaryExpression)sumExpression.Body).Operand; - var projection = new BsonDocument("_id", "null").Add("Result", new BsonDocument("$sum", $"${member.Member.Name}")); - var data = await GetCollection(collection).Aggregate().Match(filter).Group(projection).FirstOrDefaultAsync(); - return data == null ? 0 : Convert.ToInt64(data["Result"]); - } - - #endregion - - #region GetCollection - - /// - /// 获取指定集合中的 MongoDB 文档的 IMongoCollection 对象。 - /// - /// 实体类型。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// IMongoCollection 对象。 - private IMongoCollection GetCollection(string collection = null) - { - return _mongoDatabase.GetCollection(collection ?? typeof(T).Name); - } - - /// - /// 获取指定集合中的 MongoDB 文档的 IMongoCollection 对象,其中实体类型为 Entity。 - /// - /// 集合名称。 - /// IMongoCollection 对象。 - private IMongoCollection GetCollection(string name) - { - return _mongoDatabase.GetCollection(name); - } - - #endregion - - #region Count - - /// - /// 统计指定集合中满足条件的文档数量。 - /// - /// 实体类型。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 满足条件的文档数量。 - public async FTask Count(string collection = null) where T : Entity - { - return await GetCollection(collection).CountDocumentsAsync(d => true); - } - - /// - /// 统计指定集合中满足条件的文档数量。 - /// - /// 实体类型。 - /// 用于筛选文档的表达式。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 满足条件的文档数量。 - public async FTask Count(Expression> filter, string collection = null) where T : Entity - { - return await GetCollection(collection).CountDocumentsAsync(filter); - } - - #endregion - - #region Exist - - /// - /// 判断指定集合中是否存在文档。 - /// - /// 实体类型。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 如果存在文档则返回 true,否则返回 false。 - public async FTask Exist(string collection = null) where T : Entity - { - return await Count(collection) > 0; - } - - /// - /// 判断指定集合中是否存在满足条件的文档。 - /// - /// 实体类型。 - /// 用于筛选文档的表达式。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 如果存在满足条件的文档则返回 true,否则返回 false。 - public async FTask Exist(Expression> filter, string collection = null) where T : Entity - { - return await Count(filter, collection) > 0; - } - - #endregion - - #region Query - - /// - /// 在不加数据库锁定的情况下,查询指定 ID 的文档。 - /// - /// 文档实体类型。 - /// 要查询的文档 ID。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 查询到的文档。 - public async FTask QueryNotLock(long id, bool isDeserialize = false, string collection = null) where T : Entity - { - var cursor = await GetCollection(collection).FindAsync(d => d.Id == id); - var v = await cursor.FirstOrDefaultAsync(); - - if (isDeserialize && v != null) - { - v.Deserialize(_scene); - } - - return v; - } - - /// - /// 查询指定 ID 的文档,并加数据库锁定以确保数据一致性。 - /// - /// 文档实体类型。 - /// 要查询的文档 ID。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 查询到的文档。 - public async FTask Query(long id, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(id)) - { - var cursor = await GetCollection(collection).FindAsync(d => d.Id == id); - var v = await cursor.FirstOrDefaultAsync(); - - if (isDeserialize && v != null) - { - v.Deserialize(_scene); - } - - return v; - } - } - - /// - /// 通过分页查询并返回满足条件的文档数量和日期列表(不加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档数量和日期列表。 - public async FTask<(int count, List dates)> QueryCountAndDatesByPage(Expression> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var count = await Count(filter); - var dates = await QueryByPage(filter, pageIndex, pageSize, isDeserialize, collection); - return ((int)count, dates); - } - } - - /// - /// 通过分页查询并返回满足条件的文档数量和日期列表(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档数量和日期列表。 - public async FTask<(int count, List dates)> QueryCountAndDatesByPage(Expression> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var count = await Count(filter); - var dates = await QueryByPage(filter, pageIndex, pageSize, cols, isDeserialize, collection); - return ((int)count, dates); - } - } - - /// - /// 通过分页查询并返回满足条件的文档列表(不加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryByPage(Expression> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var list = await GetCollection(collection).Find(filter).Skip((pageIndex - 1) * pageSize) - .Limit(pageSize) - .ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 通过分页查询并返回满足条件的文档列表(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryByPage(Expression> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include(""); - - foreach (var col in cols) - { - projection = projection.Include(col); - } - - var list = await GetCollection(collection).Find(filter).Project(projection) - .Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 通过分页查询并返回满足条件的文档列表,并按指定表达式进行排序(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 排序表达式。 - /// 是否升序排序。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryByPageOrderBy(Expression> filter, int pageIndex, int pageSize, Expression> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - List list; - - if (isAsc) - { - list = await GetCollection(collection).Find(filter).SortBy(orderByExpression).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); - } - else - { - list = await GetCollection(collection).Find(filter).SortByDescending(orderByExpression).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); - } - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 通过指定过滤条件查询并返回满足条件的第一个文档(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的第一个文档,如果未找到则为 null。 - public async FTask First(Expression> filter, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var cursor = await GetCollection(collection).FindAsync(filter); - var t = await cursor.FirstOrDefaultAsync(); - - if (isDeserialize && t != null) - { - t.Deserialize(_scene); - } - - return t; - } - } - - /// - /// 通过指定 JSON 格式查询并返回满足条件的第一个文档(加锁)。 - /// - /// 文档实体类型。 - /// JSON 查询条件。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的第一个文档。 - public async FTask First(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include(""); - - foreach (var col in cols) - { - projection = projection.Include(col); - } - - var options = new FindOptions { Projection = projection }; - - FilterDefinition filterDefinition = new JsonFilterDefinition(json); - - var cursor = await GetCollection(collection).FindAsync(filterDefinition, options); - var t = await cursor.FirstOrDefaultAsync(); - - if (isDeserialize && t != null) - { - t.Deserialize(_scene); - } - - return t; - } - } - - /// - /// 通过指定过滤条件查询并返回满足条件的文档列表,并按指定表达式进行排序(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 排序表达式。 - /// 是否升序排序。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryOrderBy(Expression> filter, Expression> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - List list; - - if (isAsc) - { - list = await GetCollection(collection).Find(filter).SortBy(orderByExpression).ToListAsync(); - } - else - { - list = await GetCollection(collection).Find(filter).SortByDescending(orderByExpression).ToListAsync(); - } - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 通过指定过滤条件查询并返回满足条件的文档列表(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> Query(Expression> filter, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var cursor = await GetCollection(collection).FindAsync(filter); - var list = await cursor.ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定 ID 加锁查询多个集合中的文档。 - /// - /// 文档 ID。 - /// 要查询的集合名称列表。 - /// 查询结果存储列表。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - public async FTask Query(long id, List? collectionNames, List result, bool isDeserialize = false) - { - using (await _dataBaseLock.Wait(id)) - { - if (collectionNames == null || collectionNames.Count == 0) - { - return; - } - - foreach (var collectionName in collectionNames) - { - var cursor = await GetCollection(collectionName).FindAsync(d => d.Id == id); - - var e = await cursor.FirstOrDefaultAsync(); - - if (e == null) - { - continue; - } - - if (isDeserialize) - { - e.Deserialize(_scene); - } - - result.Add(e); - } - } - } - - /// - /// 根据指定的 JSON 查询条件查询并返回满足条件的文档列表(加锁)。 - /// - /// 文档实体类型。 - /// JSON 查询条件。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryJson(string json, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - FilterDefinition filterDefinition = new JsonFilterDefinition(json); - var cursor = await GetCollection(collection).FindAsync(filterDefinition); - var list = await cursor.ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定的 JSON 查询条件查询并返回满足条件的文档列表,并选择指定的列(加锁)。 - /// - /// 文档实体类型。 - /// JSON 查询条件。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryJson(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include(""); - - foreach (var col in cols) - { - projection = projection.Include(col); - } - - var options = new FindOptions { Projection = projection }; - - FilterDefinition filterDefinition = new JsonFilterDefinition(json); - - var cursor = await GetCollection(collection).FindAsync(filterDefinition, options); - var list = await cursor.ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定的 JSON 查询条件和任务 ID 查询并返回满足条件的文档列表(加锁)。 - /// - /// 文档实体类型。 - /// 任务 ID。 - /// JSON 查询条件。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryJson(long taskId, string json, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(taskId)) - { - FilterDefinition filterDefinition = new JsonFilterDefinition(json); - var cursor = await GetCollection(collection).FindAsync(filterDefinition); - var list = await cursor.ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定过滤条件查询并返回满足条件的文档列表,选择指定的列(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> Query(Expression> filter, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include("_id"); - - foreach (var t in cols) - { - projection = projection.Include(t); - } - - var list = await GetCollection(collection).Find(filter).Project(projection).ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定过滤条件查询并返回满足条件的文档列表,选择指定的列(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// - public async FTask> Query(Expression> filter, Expression>[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include("_id"); - - foreach (var col in cols) - { - if (col.Body is not MemberExpression memberExpression) - { - throw new ArgumentException("Lambda expression must be a member access expression."); - } - - projection = projection.Include(memberExpression.Member.Name); - } - - var list = await GetCollection(collection).Find(filter).Project(projection).ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - #endregion - - #region Save - - /// - /// 保存实体对象到数据库(加锁)。 - /// - /// 实体类型。 - /// 事务会话对象。 - /// 要保存的实体对象。 - /// 集合名称。 - public async FTask Save(object transactionSession, T? entity, string collection = null) where T : Entity - { - if (entity == null) - { - Log.Error($"save entity is null: {typeof(T).Name}"); - return; - } - - var clone = _serializer.Clone(entity); - - using (await _dataBaseLock.Wait(clone.Id)) - { - await GetCollection(collection).ReplaceOneAsync( - (IClientSessionHandle)transactionSession, d => d.Id == clone.Id, clone, - new ReplaceOptions { IsUpsert = true }); - } - } - - /// - /// 保存实体对象到数据库(加锁)。 - /// - /// 实体类型。 - /// 要保存的实体对象。 - /// 集合名称。 - public async FTask Save(T? entity, string collection = null) where T : Entity, new() - { - if (entity == null) - { - Log.Error($"save entity is null: {typeof(T).Name}"); - - return; - } - - var clone = _serializer.Clone(entity); - - using (await _dataBaseLock.Wait(clone.Id)) - { - await GetCollection(collection).ReplaceOneAsync(d => d.Id == clone.Id, clone, new ReplaceOptions { IsUpsert = true }); - } - } - - /// - /// 保存实体对象到数据库(加锁)。 - /// - /// 保存的条件表达式。 - /// 实体类型。 - /// 集合名称。 - /// - public async FTask Save(Expression> filter, T? entity, string collection = null) where T : Entity, new() - { - if (entity == null) - { - Log.Error($"save entity is null: {typeof(T).Name}"); - return; - } - - T clone = _serializer.Clone(entity); - - using (await _dataBaseLock.Wait(clone.Id)) - { - await GetCollection(collection).ReplaceOneAsync(filter, clone, new ReplaceOptions { IsUpsert = true }); - } - } - - /// - /// 保存多个实体对象到数据库(加锁)。 - /// - /// 文档 ID。 - /// 要保存的实体对象列表。 - public async FTask Save(long id, List? entities) - { - if (entities == null || entities.Count == 0) - { - Log.Error("save entity is null"); - return; - } - - using var listPool = ListPool.Create(); - - foreach (var entity in entities) - { - listPool.Add(_serializer.Clone(entity)); - } - - using (await _dataBaseLock.Wait(id)) - { - foreach (var clone in listPool) - { - try - { - await GetCollection(clone.GetType().Name).ReplaceOneAsync(d => d.Id == clone.Id, clone, new ReplaceOptions { IsUpsert = true }); - } - catch (Exception e) - { - Log.Error($"Save List Entity Error: {clone.GetType().Name} {clone}\n{e}"); - } - } - } - } - - #endregion - - #region Insert - - /// - /// 插入单个实体对象到数据库(加锁)。 - /// - /// 实体类型。 - /// 要插入的实体对象。 - /// 集合名称。 - public async FTask Insert(T? entity, string collection = null) where T : Entity, new() - { - if (entity == null) - { - Log.Error($"insert entity is null: {typeof(T).Name}"); - return; - } - - var clone = _serializer.Clone(entity); - - using (await _dataBaseLock.Wait(entity.Id)) - { - await GetCollection(collection).InsertOneAsync(clone); - } - } - - /// - /// 批量插入实体对象列表到数据库(加锁)。 - /// - /// 实体类型。 - /// 要插入的实体对象列表。 - /// 集合名称。 - public async FTask InsertBatch(IEnumerable list, string collection = null) where T : Entity, new() - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - await GetCollection(collection).InsertManyAsync(list); - } - } - - /// - /// 批量插入实体对象列表到数据库(加锁)。 - /// - /// 实体类型。 - /// 事务会话对象。 - /// 要插入的实体对象列表。 - /// 集合名称。 - public async FTask InsertBatch(object transactionSession, IEnumerable list, string collection = null) - where T : Entity, new() - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - await GetCollection(collection).InsertManyAsync((IClientSessionHandle)transactionSession, list); - } - } - - /// - /// 插入BsonDocument到数据库(加锁)。 - /// - /// - /// - /// - public async Task Insert(BsonDocument bsonDocument, long taskId) where T : Entity - { - using (await _dataBaseLock.Wait(taskId)) - { - await GetCollection(typeof(T).Name).InsertOneAsync(bsonDocument); - } - } - - #endregion - - #region Remove - - /// - /// 根据ID删除单个实体对象(加锁)。 - /// - /// 实体类型。 - /// 事务会话对象。 - /// 要删除的实体的ID。 - /// 集合名称。 - /// 删除的实体数量。 - public async FTask Remove(object transactionSession, long id, string collection = null) - where T : Entity, new() - { - using (await _dataBaseLock.Wait(id)) - { - var result = await GetCollection(collection) - .DeleteOneAsync((IClientSessionHandle)transactionSession, d => d.Id == id); - return result.DeletedCount; - } - } - - /// - /// 根据ID删除单个实体对象(加锁)。 - /// - /// 实体类型。 - /// 要删除的实体的ID。 - /// 集合名称。 - /// 删除的实体数量。 - public async FTask Remove(long id, string collection = null) where T : Entity, new() - { - using (await _dataBaseLock.Wait(id)) - { - var result = await GetCollection(collection).DeleteOneAsync(d => d.Id == id); - return result.DeletedCount; - } - } - - /// - /// 根据ID和筛选条件删除多个实体对象(加锁)。 - /// - /// 实体类型。 - /// 异步锁Id。 - /// 事务会话对象。 - /// 筛选条件。 - /// 集合名称。 - /// 删除的实体数量。 - public async FTask Remove(long coroutineLockQueueKey, object transactionSession, - Expression> filter, string collection = null) where T : Entity, new() - { - using (await _dataBaseLock.Wait(coroutineLockQueueKey)) - { - var result = await GetCollection(collection) - .DeleteManyAsync((IClientSessionHandle)transactionSession, filter); - return result.DeletedCount; - } - } - - /// - /// 根据ID和筛选条件删除多个实体对象(加锁)。 - /// - /// 实体类型。 - /// 异步锁Id。 - /// 筛选条件。 - /// 集合名称。 - /// 删除的实体数量。 - public async FTask Remove(long coroutineLockQueueKey, Expression> filter, - string collection = null) where T : Entity, new() - { - using (await _dataBaseLock.Wait(coroutineLockQueueKey)) - { - var result = await GetCollection(collection).DeleteManyAsync(filter); - return result.DeletedCount; - } - } - - #endregion - - #region Index - - /// - /// 创建数据库索引(加锁)。 - /// - /// - /// - /// - /// - /// 使用例子(可多个): - /// 1 : Builders.IndexKeys.Ascending(d=>d.Id) - /// 2 : Builders.IndexKeys.Descending(d=>d.Id).Ascending(d=>d.Name) - /// 3 : Builders.IndexKeys.Descending(d=>d.Id),Builders.IndexKeys.Descending(d=>d.Name) - /// - public async FTask CreateIndex(string collection, params object[]? keys) where T : Entity - { - if (keys == null || keys.Length <= 0) - { - return; - } - - var indexModels = new List>(); - - foreach (object key in keys) - { - IndexKeysDefinition indexKeysDefinition = (IndexKeysDefinition)key; - - indexModels.Add(new CreateIndexModel(indexKeysDefinition)); - } - - await GetCollection(collection).Indexes.CreateManyAsync(indexModels); - } - - /// - /// 创建数据库的索引(加锁)。 - /// - /// 实体类型。 - /// 索引键定义。 - public async FTask CreateIndex(params object[]? keys) where T : Entity - { - if (keys == null) - { - return; - } - - List> indexModels = new List>(); - - foreach (object key in keys) - { - IndexKeysDefinition indexKeysDefinition = (IndexKeysDefinition)key; - - indexModels.Add(new CreateIndexModel(indexKeysDefinition)); - } - - await GetCollection().Indexes.CreateManyAsync(indexModels); - } - - #endregion - - #region CreateDB - - /// - /// 创建数据库集合(如果不存在)。 - /// - /// 实体类型。 - public async FTask CreateDB() where T : Entity - { - // 已经存在数据库表 - string name = typeof(T).Name; - - if (_collections.Contains(name)) - { - return; - } - - await _mongoDatabase.CreateCollectionAsync(name); - - _collections.Add(name); - } - - /// - /// 创建数据库集合(如果不存在)。 - /// - /// 实体类型。 - public async FTask CreateDB(Type type) - { - string name = type.Name; - - if (_collections.Contains(name)) - { - return; - } - - await _mongoDatabase.CreateCollectionAsync(name); - - _collections.Add(name); - } - - #endregion - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/World.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/World.cs deleted file mode 100644 index c53351f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/World.cs +++ /dev/null @@ -1,77 +0,0 @@ -#pragma warning disable CS8603 // Possible null reference return. -#if FANTASY_NET -using Fantasy.Platform.Net; - -namespace Fantasy.DataBase -{ - /// - /// 表示一个游戏世界。 - /// - public sealed class World : IDisposable - { - /// - /// 获取游戏世界的唯一标识。 - /// - public byte Id { get; private init; } - /// - /// 获取游戏世界的数据库接口。 - /// - public IDataBase DataBase { get; private init; } - /// - /// 获取游戏世界的配置信息。 - /// - public WorldConfig Config => WorldConfigData.Instance.Get(Id); - - /// - /// 使用指定的配置信息创建一个游戏世界实例。 - /// - /// - /// - private World(Scene scene, byte worldConfigId) - { - Id = worldConfigId; - var worldConfig = Config; - var dbType = worldConfig.DbType.ToLower(); - - switch (dbType) - { - case "mongodb": - { - DataBase = new MongoDataBase(); - DataBase.Initialize(scene, worldConfig.DbConnection, worldConfig.DbName); - break; - } - default: - { - throw new Exception("No supported database"); - } - } - } - - /// - /// 创建一个指定唯一标识的游戏世界实例。 - /// - /// - /// 游戏世界的唯一标识。 - /// 游戏世界实例。 - internal static World Create(Scene scene, byte id) - { - if (!WorldConfigData.Instance.TryGet(id, out var worldConfigData)) - { - return null; - } - - return string.IsNullOrEmpty(worldConfigData.DbConnection) ? null : new World(scene, id); - } - - /// - /// 释放游戏世界资源。 - /// - public void Dispose() - { - DataBase.Dispose(); - } - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/CircularBuffer.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/CircularBuffer.cs deleted file mode 100644 index d80ec55..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/CircularBuffer.cs +++ /dev/null @@ -1,346 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.DataStructure.Collection -{ - /// 环形缓存(自增式缓存,自动扩充、不会收缩缓存、所以不要用这个操作过大的IO流) - /// 1、环大小8192,溢出的会自动增加环的大小。 - /// 2、每个块都是一个环形缓存,当溢出的时候会自动添加到下一个环中。 - /// 3、当读取完成后用过的环会放在缓存中,不会销毁掉。 - /// - /// 自增式缓存类,继承自 Stream 和 IDisposable 接口。 - /// 环形缓存具有自动扩充的特性,但不会收缩,适用于操作不过大的 IO 流。 - /// - public sealed class CircularBuffer : Stream, IDisposable - { - private byte[] _lastBuffer; - /// - /// 环形缓存块的默认大小 - /// - public const int ChunkSize = 8192; - private readonly Queue _bufferCache = new Queue(); - private readonly Queue _bufferQueue = new Queue(); - /// - /// 获取或设置环形缓存的第一个索引位置 - /// - public int FirstIndex { get; set; } - /// - /// 获取或设置环形缓存的最后一个索引位置 - /// - public int LastIndex { get; set; } - /// - /// 获取环形缓存的总长度 - /// - public override long Length - { - get - { - if (_bufferQueue.Count == 0) - { - return 0; - } - - return (_bufferQueue.Count - 1) * ChunkSize + LastIndex - FirstIndex; - } - } - - /// - /// 获取环形缓存的第一个块 - /// - public byte[] First - { - get - { - if (_bufferQueue.Count == 0) - { - AddLast(); - } - - return _bufferQueue.Peek(); - } - } - - /// - /// 获取环形缓存的最后一个块 - /// - public byte[] Last - { - get - { - if (_bufferQueue.Count == 0) - { - AddLast(); - } - - return _lastBuffer; - } - } - /// - /// 向环形缓存中添加一个新的块 - /// - public void AddLast() - { - var buffer = _bufferCache.Count > 0 ? _bufferCache.Dequeue() : new byte[ChunkSize]; - _bufferQueue.Enqueue(buffer); - _lastBuffer = buffer; - } - /// - /// 从环形缓存中移除第一个块 - /// - public void RemoveFirst() - { - _bufferCache.Enqueue(_bufferQueue.Dequeue()); - } - - /// - /// 从流中读取指定数量的数据到缓存。 - /// - /// 源数据流。 - /// 要读取的字节数。 - public void Read(Stream stream, int count) - { - if (count > Length) - { - throw new Exception($"bufferList length < count, {Length} {count}"); - } - - var copyCount = 0; - while (copyCount < count) - { - var n = count - copyCount; - if (ChunkSize - FirstIndex > n) - { - stream.Write(First, FirstIndex, n); - FirstIndex += n; - copyCount += n; - } - else - { - stream.Write(First, FirstIndex, ChunkSize - FirstIndex); - copyCount += ChunkSize - FirstIndex; - FirstIndex = 0; - RemoveFirst(); - } - } - } - - /// - /// 从缓存中读取指定数量的数据到内存。 - /// - /// 目标内存。 - /// 要读取的字节数。 - public void Read(Memory memory, int count) - { - if (count > Length) - { - throw new Exception($"bufferList length < count, {Length} {count}"); - } - - var copyCount = 0; - while (copyCount < count) - { - var n = count - copyCount; - var asMemory = First.AsMemory(); - - if (ChunkSize - FirstIndex > n) - { - var slice = asMemory.Slice(FirstIndex, n); - slice.CopyTo(memory.Slice(copyCount, n)); - FirstIndex += n; - copyCount += n; - } - else - { - var length = ChunkSize - FirstIndex; - var slice = asMemory.Slice(FirstIndex, length); - slice.CopyTo(memory.Slice(copyCount, length)); - copyCount += ChunkSize - FirstIndex; - FirstIndex = 0; - RemoveFirst(); - } - } - } - - /// - /// 从自定义流中读取数据到指定的缓冲区。 - /// - /// 目标缓冲区,用于存储读取的数据。 - /// 目标缓冲区中的起始偏移量。 - /// 要读取的字节数。 - /// 实际读取的字节数。 - public override int Read(byte[] buffer, int offset, int count) - { - if (buffer.Length < offset + count) - { - throw new Exception($"buffer length < count, buffer length: {buffer.Length} {offset} {count}"); - } - - var length = Length; - if (length < count) - { - count = (int) length; - } - - var copyCount = 0; - - // 循环直到成功读取所需的字节数 - while (copyCount < count) - { - var copyLength = count - copyCount; - - if (ChunkSize - FirstIndex > copyLength) - { - // 将数据从当前块的缓冲区复制到目标缓冲区 - Array.Copy(First, FirstIndex, buffer, copyCount + offset, copyLength); - - FirstIndex += copyLength; - copyCount += copyLength; - continue; - } - - // 复制当前块中剩余的数据,并切换到下一个块 - Array.Copy(First, FirstIndex, buffer, copyCount + offset, ChunkSize - FirstIndex); - copyCount += ChunkSize - FirstIndex; - FirstIndex = 0; - - RemoveFirst(); - } - - return count; - } - - /// - /// 将数据从给定的字节数组写入流中。 - /// - /// 包含要写入的数据的字节数组。 - public void Write(byte[] buffer) - { - Write(buffer, 0, buffer.Length); - } - - /// - /// 将数据从给定的流写入流中。 - /// - /// 包含要写入的数据的流。 - public void Write(Stream stream) - { - var copyCount = 0; - var count = (int) (stream.Length - stream.Position); - - while (copyCount < count) - { - if (LastIndex == ChunkSize) - { - AddLast(); - LastIndex = 0; - } - - var n = count - copyCount; - - if (ChunkSize - LastIndex > n) - { - _ = stream.Read(Last, LastIndex, n); - LastIndex += count - copyCount; - copyCount += n; - } - else - { - _ = stream.Read(Last, LastIndex, ChunkSize - LastIndex); - copyCount += ChunkSize - LastIndex; - LastIndex = ChunkSize; - } - } - } - - /// - /// 将数据从给定的字节数组写入流中。 - /// - /// 包含要写入的数据的字节数组。 - /// 开始写入的缓冲区中的索引。 - /// 要写入的字节数。 - public override void Write(byte[] buffer, int offset, int count) - { - var copyCount = 0; - - while (copyCount < count) - { - if (ChunkSize == LastIndex) - { - AddLast(); - LastIndex = 0; - } - - var byteLength = count - copyCount; - - if (ChunkSize - LastIndex > byteLength) - { - Array.Copy(buffer, copyCount + offset, Last, LastIndex, byteLength); - LastIndex += byteLength; - copyCount += byteLength; - } - else - { - Array.Copy(buffer, copyCount + offset, Last, LastIndex, ChunkSize - LastIndex); - copyCount += ChunkSize - LastIndex; - LastIndex = ChunkSize; - } - } - } - - /// - /// 获取一个值,指示流是否支持读取操作。 - /// - public override bool CanRead { get; } = true; - /// - /// 获取一个值,指示流是否支持寻找操作。 - /// - public override bool CanSeek { get; } = false; - /// - /// 获取一个值,指示流是否支持写入操作。 - /// - public override bool CanWrite { get; } = true; - /// - /// 获取或设置流中的位置。 - /// - public override long Position { get; set; } - - /// - /// 刷新流(在此实现中引发未实现异常)。 - /// - public override void Flush() - { - throw new NotImplementedException(); - } - - /// - /// 在流中寻找特定位置(在此实现中引发未实现异常)。 - /// - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotImplementedException(); - } - - /// - /// 设置流的长度(在此实现中引发未实现异常)。 - /// - public override void SetLength(long value) - { - throw new NotImplementedException(); - } - - /// - /// 释放 CustomStream 使用的所有资源。 - /// - public new void Dispose() - { - _bufferQueue.Clear(); - _lastBuffer = null; - FirstIndex = 0; - LastIndex = 0; - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyListPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyListPool.cs deleted file mode 100644 index e110a0b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyListPool.cs +++ /dev/null @@ -1,197 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 并发的一对多列表池,用于维护具有相同键的多个值的关联关系,实现了 接口。 - /// - /// 关键字的类型,不能为空。 - /// 值的类型。 - public class ConcurrentOneToManyListPool : ConcurrentOneToManyList, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 的实例。 - /// - /// 创建的实例。 - public static ConcurrentOneToManyListPool Create() - { - var a = MultiThreadPool.Rent>(); - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - // 清空实例的数据 - Clear(); - // 将实例返回到池中以便重用 - MultiThreadPool.Return(this); - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 并发的一对多列表,用于维护具有相同键的多个值的关联关系。 - /// - /// 关键字的类型,不能为空。 - /// 值的类型。 - public class ConcurrentOneToManyList : ConcurrentDictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit = 120; - - /// - /// 初始化 类的新实例。 - /// - public ConcurrentOneToManyList() - { - } - - /// - /// 设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public ConcurrentOneToManyList(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断指定键的列表是否包含指定值。 - /// - /// 要搜索的键。 - /// 要搜索的值。 - /// 如果列表包含值,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 向指定键的列表中添加一个值。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - base[key] = list; - return; - } - - list.Add(value); - } - - /// - /// 获取指定键的列表中的第一个值。 - /// - /// 要获取第一个值的键。 - /// 指定键的列表中的第一个值,如果不存在则为默认值。 - public TValue First(TKey key) - { - return !TryGetValue(key, out var list) ? default : list.FirstOrDefault(); - } - - /// - /// 从指定键的列表中移除一个值。 - /// - /// 要移除值的键。 - /// 要移除的值。 - public void RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) return; - - list.Remove(value); - - if (list.Count == 0) RemoveKey(key); - } - - /// - /// 从字典中移除指定键以及其关联的列表。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryRemove(key, out var list)) return; - - Recycle(list); - } - - /// - /// 从队列中获取一个列表,如果队列为空则创建一个新的列表。 - /// - /// 获取的列表。 - private List Fetch() - { - return _queue.Count <= 0 ? new List() : _queue.Dequeue(); - } - - /// - /// 将一个列表回收到队列中。 - /// - /// 要回收的列表。 - private void Recycle(List list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 清空当前类的数据,包括从基类继承的数据以及自定义的数据队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyQueuePool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyQueuePool.cs deleted file mode 100644 index 59c4367..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyQueuePool.cs +++ /dev/null @@ -1,194 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8603 - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 表示一个并发的一对多队列池,用于维护具有相同键的多个值的关联关系,实现了 接口。 - /// - /// 关键字的类型,不能为空。 - /// 值的类型。 - public class ConcurrentOneToManyQueuePool : ConcurrentOneToManyQueue, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建并返回一个 的实例。 - /// - /// 创建的实例。 - public static ConcurrentOneToManyQueuePool Create() - { - var a = MultiThreadPool.Rent>(); - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); - // 将实例返回到对象池中,以便重用 - MultiThreadPool.Return(this); - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 表示一个并发的一对多队列,用于维护具有相同键的多个值的关联关系。 - /// - /// 关键字的类型,不能为空。 - /// 值的类型。 - public class ConcurrentOneToManyQueue : ConcurrentDictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit; - - /// - /// 设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public ConcurrentOneToManyQueue(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断指定键的队列是否包含指定值。 - /// - /// 要搜索的键。 - /// 要搜索的值。 - /// 如果队列包含值,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 向指定键的队列中添加一个值。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Enqueue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Enqueue(value); - TryAdd(key, list); - return; - } - - list.Enqueue(value); - } - - /// - /// 从指定键的队列中出队并返回一个值。 - /// - /// 要出队的键。 - /// 出队的值,如果队列为空则为默认值。 - public TValue Dequeue(TKey key) - { - if (!TryGetValue(key, out var list) || list.Count == 0) return default; - - var value = list.Dequeue(); - - if (list.Count == 0) RemoveKey(key); - - return value; - } - - /// - /// 尝试从指定键的队列中出队一个值。 - /// - /// 要出队的键。 - /// 出队的值,如果队列为空则为默认值。 - /// 如果成功出队,则为 true;否则为 false。 - public bool TryDequeue(TKey key, out TValue value) - { - value = Dequeue(key); - - return value != null; - } - - /// - /// 从字典中移除指定键以及其关联的队列。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) return; - - TryRemove(key, out _); - Recycle(list); - } - - /// - /// 从队列中获取一个新的队列,如果队列为空则创建一个新的队列。 - /// - /// 获取的队列。 - private Queue Fetch() - { - return _queue.Count <= 0 ? new Queue() : _queue.Dequeue(); - } - - /// - /// 将一个队列回收到队列池中。 - /// - /// 要回收的队列。 - private void Recycle(Queue list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 清空当前类的数据,包括从基类继承的键值对字典中的数据以及自定义的队列池。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/HashSetPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/HashSetPool.cs deleted file mode 100644 index bb64ae8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/HashSetPool.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 可释放的哈希集合对象池。 - /// - /// 哈希集合中元素的类型。 - public sealed class HashSetPool : HashSet, IDisposable, IPool - { - private bool _isPool; - private bool _isDispose; - - /// - /// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 创建一个 哈希集合池的实例。 - /// - /// 创建的实例。 - public static HashSetPool Create() - { -#if FANTASY_WEBGL - var list = Pool>.Rent(); - list._isDispose = false; - list._isPool = true; - return list; -#else - var list = MultiThreadPool.Rent>(); - list._isDispose = false; - list._isPool = true; - return list; -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 基本哈希集合对象池,他自持有实际的哈希集合。 - /// - /// 哈希集合中元素的类型。 - public sealed class HashSetBasePool : IDisposable, IPool - { - private bool _isPool; - - /// - /// 存储实际的哈希集合 - /// - public HashSet Set = new HashSet(); - - /// - /// 创建一个 基本哈希集合对象池的实例。 - /// - /// 创建的实例。 - public static HashSetBasePool Create() - { -#if FANTASY_WEBGL - var hashSetBasePool = Pool>.Rent(); - hashSetBasePool._isPool = true; - return hashSetBasePool; -#else - var hashSetBasePool = MultiThreadPool.Rent>(); - hashSetBasePool._isPool = true; - return hashSetBasePool; -#endif - } - - /// - /// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - Set.Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ListPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ListPool.cs deleted file mode 100644 index de70fe2..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ListPool.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 可释放的列表(List)对象池。 - /// - /// 列表中元素的类型。 - public sealed class ListPool : List, IDisposable, IPool - { - private bool _isPool; - private bool _isDispose; - - /// - /// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 使用指定的元素创建一个 列表(List)对象池的实例。 - /// - /// 要添加到列表的元素。 - /// 创建的实例。 - public static ListPool Create(params T[] args) - { -#if FANTASY_WEBGL - var list = Pool>.Rent(); -#else - var list = MultiThreadPool.Rent>(); -#endif - list._isDispose = false; - list._isPool = true; - - if (args != null) - { - list.AddRange(args); - } - - return list; - } - - /// - /// 使用指定的列表创建一个 列表(List)对象池的实例。 - /// - /// 要添加到列表的元素列表。 - /// 创建的实例。 - public static ListPool Create(List args) - { -#if FANTASY_WEBGL - var list = Pool>.Rent(); -#else - var list = MultiThreadPool.Rent>(); -#endif - list._isDispose = false; - list._isPool = true; - - if (args != null) - { - list.AddRange(args); - } - - return list; - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/OneToManyHashSetPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/OneToManyHashSetPool.cs deleted file mode 100644 index 8a5766c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/OneToManyHashSetPool.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 一对多哈希集合(OneToManyHashSet)对象池。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyHashSetPool : OneToManyHashSet, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 一对多哈希集合(OneToManyHashSet)对象池的实例。 - /// - /// 创建的实例。 - public static OneToManyHashSetPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 一对多哈希集合(OneToManyHashSet),用于创建和管理键对应多个值的集合。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyHashSet : Dictionary> where TKey : notnull - { - /// 用于回收和重用的空闲值集合队列。 - private readonly Queue> _queue = new Queue>(); - /// 设置最大回收限制,用于控制值集合的最大数量。 - private readonly int _recyclingLimit = 120; - /// 一个空的、不包含任何元素的哈希集合,用于在查找失败时返回。 - private static HashSet _empty = new HashSet(); - - /// - /// 初始化 类的新实例。 - /// - public OneToManyHashSet() { } - - /// - /// 设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManyHashSet(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断指定的键值对是否存在于集合中。 - /// - /// 键。 - /// 值。 - /// 如果存在则为 true,否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 添加指定的键值对到集合中。 - /// - /// 键。 - /// 值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - Add(key, list); - - return; - } - - list.Add(value); - } - - /// - /// 从集合中移除指定键对应的值。 - /// - /// 键。 - /// 要移除的值。 - public void RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) return; - - list.Remove(value); - - if (list.Count == 0) RemoveKey(key); - } - - /// - /// 从集合中移除指定键及其对应的值集合。 - /// - /// 键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) return; - - Remove(key); - Recycle(list); - } - - /// - /// 获取指定键对应的值集合,如果不存在则返回一个空的哈希集合。 - /// - /// 键。 - /// 对应的值集合或空的哈希集合。 - public HashSet GetValue(TKey key) - { - if (TryGetValue(key, out HashSet value)) - { - return value; - } - - return _empty; - } - - /// - /// 从队列中获取一个空闲的值集合,或者创建一个新的。 - /// - /// 值集合。 - private HashSet Fetch() - { - return _queue.Count <= 0 ? new HashSet() : _queue.Dequeue(); - } - - /// - /// 回收值集合到队列中,以便重复利用。 - /// - /// 要回收的值集合。 - private void Recycle(HashSet list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 清空集合中的数据并和队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/OneToManyListPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/OneToManyListPool.cs deleted file mode 100644 index 80568ef..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/OneToManyListPool.cs +++ /dev/null @@ -1,232 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 可回收的、一对多关系的列表池。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyListPool : OneToManyList, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 一对多关系的列表池的实例。 - /// - /// 创建的实例。 - public static OneToManyListPool Create() - { -#if FANTASY_WEBGL || FANTASY_EXPORTER - var list = Pool>.Rent(); -#else - var list = MultiThreadPool.Rent>(); -#endif - list._isDispose = false; - list._isPool = true; - return list; - } - - /// - /// 释放当前对象所占用的资源,并将对象回收到对象池中。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL || FANTASY_EXPORTER - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 一对多关系的列表字典。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyList : Dictionary> where TKey : notnull - { - private readonly int _recyclingLimit = 120; - private static readonly List Empty = new List(); - private readonly Queue> _queue = new Queue>(); - - /// - /// 初始化一个新的 实例。 - /// - public OneToManyList() { } - - /// - /// 设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManyList(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断给定的键和值是否存在于列表中。 - /// - /// 要搜索的键。 - /// 要搜索的值。 - /// 如果存在则为 ,否则为 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 向列表中添加指定键和值。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - Add(key, list); - - return; - } - - list.Add(value); - } - - /// - /// 获取指定键对应的列表中的第一个值。 - /// - /// 要获取值的键。 - /// 键对应的列表中的第一个值。 - public TValue First(TKey key) - { - return !TryGetValue(key, out var list) ? default : list.FirstOrDefault(); - } - - /// - /// 从列表中移除指定键和值。 - /// - /// 要移除值的键。 - /// 要移除的值。 - /// 如果成功移除则为 ,否则为 - public bool RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - return true; - } - - var isRemove = list.Remove(value); - - if (list.Count == 0) - { - isRemove = RemoveByKey(key); - } - - return isRemove; - } - - /// - /// 从列表中移除指定键及其关联的所有值。 - /// - /// 要移除的键。 - /// 如果成功移除则为 ,否则为 - public bool RemoveByKey(TKey key) - { - if (!TryGetValue(key, out var list)) - { - return false; - } - - Remove(key); - Recycle(list); - return true; - } - - /// - /// 获取指定键关联的所有值的列表。 - /// - /// 要获取值的键。 - /// 键关联的所有值的列表。 - public List GetValues(TKey key) - { - if (TryGetValue(key, out List list)) - { - return list; - } - - return Empty; - } - - /// - /// 清除字典中的所有键值对,并回收相关的值集合。 - /// - public new void Clear() - { - foreach (var keyValuePair in this) Recycle(keyValuePair.Value); - - base.Clear(); - } - - /// - /// 从空闲值集合队列中获取一个值集合,如果队列为空则创建一个新的值集合。 - /// - /// 从队列中获取的值集合。 - private List Fetch() - { - return _queue.Count <= 0 ? new List() : _queue.Dequeue(); - } - - /// - /// 回收一个不再使用的值集合到空闲值集合队列中。 - /// - /// 要回收的值集合。 - private void Recycle(List list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/OneToManyQueuePool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/OneToManyQueuePool.cs deleted file mode 100644 index 222576e..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/OneToManyQueuePool.cs +++ /dev/null @@ -1,204 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8603 - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 支持一对多关系的队列池,用于存储具有相同键的值的队列集合。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyQueuePool : OneToManyQueue, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 一对多关系的队列池的实例。 - /// - /// 创建的实例。 - public static OneToManyQueuePool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前实例所占用的资源,并将实例回收到对象池中。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 支持一对多关系的队列,用于存储具有相同键的值的队列集合。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyQueue : Dictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit; - - /// - /// 创建一个 一对多关系的队列的实例。设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManyQueue(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断指定键的值队列是否包含指定的值。 - /// - /// 要查找的键。 - /// 要查找的值。 - /// 如果存在,则为 true;否则为 false - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 将指定的值添加到指定键的值队列中。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Enqueue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Enqueue(value); - Add(key, list); - return; - } - - list.Enqueue(value); - } - - /// - /// 从指定键的值队列中出队一个值。 - /// - /// 要出队的键。 - /// 出队的值。 - public TValue Dequeue(TKey key) - { - if (!TryGetValue(key, out var list) || list.Count == 0) - { - return default; - } - - var value = list.Dequeue(); - - if (list.Count == 0) - { - RemoveKey(key); - } - - return value; - } - - /// - /// 尝试从指定键的值队列中出队一个值。 - /// - /// 要出队的键。 - /// 出队的值。 - /// 如果成功出队,则为 true;否则为 false - public bool TryDequeue(TKey key, out TValue value) - { - value = Dequeue(key); - - return value != null; - } - - /// - /// 从字典中移除指定键及其对应的值队列。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) return; - - Remove(key); - Recycle(list); - } - - /// - /// 从队列池中获取一个值队列。如果队列池为空,则创建一个新的值队列。 - /// - /// 获取的值队列。 - private Queue Fetch() - { - return _queue.Count <= 0 ? new Queue() : _queue.Dequeue(); - } - - /// - /// 回收一个不再使用的值队列到队列池中,以便重用。 - /// - /// 要回收的值队列。 - private void Recycle(Queue list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 清空当前实例的数据,同时回收所有值队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ReuseList.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ReuseList.cs deleted file mode 100644 index b4395e8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/ReuseList.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 可重用的列表,继承自 类。该类支持通过对象池重用列表实例,以减少对象分配和释放的开销。 - /// - /// 列表中元素的类型。 - public sealed class ReuseList : List, IDisposable, IPool - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 可重用的列表的实例。 - /// - /// 创建的实例。 - public static ReuseList Create() - { -#if FANTASY_WEBGL - var list = Pool>.Rent(); -#else - var list = MultiThreadPool.Rent>(); -#endif - list._isDispose = false; - list._isPool = true; - return list; - } - - /// - /// 释放该实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/SortedConcurrentOneToManyListPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/SortedConcurrentOneToManyListPool.cs deleted file mode 100644 index 464ab58..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/SortedConcurrentOneToManyListPool.cs +++ /dev/null @@ -1,226 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8603 - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 基于排序字典和并发集合实现的一对多映射列表的对象池包装类,继承自 类, - /// 同时实现了 接口,以支持对象的重用和释放。 - /// - /// 键的类型。 - /// 值的类型。 - public class SortedConcurrentOneToManyListPool : SortedConcurrentOneToManyList, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个新的 实例,使用默认的参数设置。 - /// - /// 新创建的 实例。 - public static SortedConcurrentOneToManyListPool Create() - { - var a = MultiThreadPool.Rent>(); - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前对象池实例,将其返回到对象池以供重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); - MultiThreadPool.Return(this); - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 基于排序字典和并发集合实现的一多对映射列表类,继承自 类, - /// 用于在多个值与一个键关联的情况下进行管理和存储。该类支持并发操作,适用于多线程环境。 - /// - /// 键的类型。 - /// 值的类型。 - public class SortedConcurrentOneToManyList : SortedDictionary> where TKey : notnull - { - /// 用于同步操作的锁对象,它确保在多线程环境下对数据的安全访问。 - private readonly object _lockObject = new object(); - /// 用于存储缓存的队列。 - private readonly Queue> _queue = new Queue>(); - /// 控制缓存回收的限制。当缓存的数量超过此限制时,旧的缓存将会被回收。 - private readonly int _recyclingLimit; - - /// - /// 初始化一个新的 类的实例,使用默认的参数设置。 - /// - public SortedConcurrentOneToManyList() - { - } - - /// - /// 初始化一个新的 类的实例,指定最大缓存数量。 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public SortedConcurrentOneToManyList(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 检查指定的键和值是否存在于映射列表中。 - /// - /// 要检查的键。 - /// 要检查的值。 - /// 如果存在,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - lock (_lockObject) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - } - - /// - /// 将指定的值添加到与指定键关联的列表中。 - /// - /// 要关联值的键。 - /// 要添加到列表的值。 - public void Add(TKey key, TValue value) - { - lock (_lockObject) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - base[key] = list; - return; - } - - list.Add(value); - } - } - - /// - /// 获取与指定键关联的列表中的第一个值。 - /// 如果列表不存在或为空,则返回默认值。 - /// - /// 要获取第一个值的键。 - /// 第一个值,或默认值。 - public TValue First(TKey key) - { - lock (_lockObject) - { - return !TryGetValue(key, out var list) ? default : list.FirstOrDefault(); - } - } - - /// - /// 从与指定键关联的列表中移除指定的值。 - /// 如果列表不存在或值不存在于列表中,则不执行任何操作。 - /// - /// 要移除值的键。 - /// 要移除的值。 - public void RemoveValue(TKey key, TValue value) - { - lock (_lockObject) - { - if (!TryGetValue(key, out var list)) return; - - list.Remove(value); - - if (list.Count == 0) RemoveKey(key); - } - } - - /// - /// 从映射列表中移除指定的键及其关联的列表。 - /// 如果键不存在于映射列表中,则不执行任何操作。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - lock (_lockObject) - { - if (!TryGetValue(key, out var list)) return; - - Remove(key); - - Recycle(list); - } - } - - /// - /// 从缓存中获取一个可重用的列表。如果缓存中不存在列表,则创建一个新的列表并返回。 - /// - /// 可重用的列表。 - private List Fetch() - { - lock (_lockObject) - { - return _queue.Count <= 0 ? new List() : _queue.Dequeue(); - } - } - - /// - /// 将不再使用的列表回收到缓存中,以便重复利用。如果缓存数量超过限制,则丢弃列表而不进行回收。 - /// - /// 要回收的列表。 - private void Recycle(List list) - { - lock (_lockObject) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - } - - /// - /// 清空映射列表以及队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/SortedOneToManyHashSetPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/SortedOneToManyHashSetPool.cs deleted file mode 100644 index 8158db5..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/SortedOneToManyHashSetPool.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 基于排序字典实现的一对多关系的映射哈希集合的对象池包装类,将唯一键映射到多个值的哈希集合。 - /// 同时实现了 接口,以支持对象的重用和释放。 - /// - /// 字典中键的类型。 - /// 哈希集合中值的类型。 - public class SortedOneToManyHashSetPool : SortedOneToManyHashSet, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 实例。 - /// - /// 新创建的实例。 - public static SortedOneToManyHashSetPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前对象池实例,将其返回到对象池以供重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 基于排序字典实现的一对多关系的映射哈希集合类,将唯一键映射到多个值的哈希集合。 - /// 用于在多个值与一个键关联的情况下进行管理和存储。 - /// - /// 字典中键的类型。 - /// 集合中值的类型。 - public class SortedOneToManyHashSet : SortedDictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit = 120; - - /// - /// 创建一个新的 实例。 - /// - public SortedOneToManyHashSet() { } - - /// - /// 创建一个新的 实例,设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public SortedOneToManyHashSet(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断哈希集合中是否包含指定的键值对。 - /// - /// 要查找的键。 - /// 要查找的值。 - /// 如果键值对存在,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 将指定值添加到给定键关联的哈希集合中。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - Add(key, list); - - return; - } - - list.Add(value); - } - - /// - /// 从指定键关联的哈希集合中移除特定值。 - /// 如果哈希集合不存在或值不存在于集合中,则不执行任何操作。 - /// - /// 要移除值的键。 - /// 要移除的值。 - public void RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) return; - - list.Remove(value); - - if (list.Count == 0) RemoveKey(key); - } - - /// - /// 从字典中移除指定键以及关联的哈希集合,并将集合进行回收。 - /// 如果键不存在于映射列表中,则不执行任何操作。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) return; - - Remove(key); - - Recycle(list); - } - - /// - /// 获取一个空的或回收的哈希集合。 - /// - /// 获取的哈希集合实例。 - private HashSet Fetch() - { - return _queue.Count <= 0 ? new HashSet() : _queue.Dequeue(); - } - - /// - /// 回收一个哈希集合,将其清空并放入回收队列中。 - /// - /// 要回收的哈希集合。 - private void Recycle(HashSet list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 重写 Clear 方法,清空字典并清空回收队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/SortedOneToManyListPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/SortedOneToManyListPool.cs deleted file mode 100644 index f0bae12..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Collection/SortedOneToManyListPool.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8603 - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 基于排序字典实现的一对多映射列表的对象池包装类,继承自 类, - /// 同时实现了 接口,以支持对象的重用和释放。 - /// - /// 字典中键的类型。 - /// 列表中值的类型。 - public class SortedOneToManyListPool : SortedOneToManyList, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 实例。 - /// - /// 新创建的实例。 - public static SortedOneToManyListPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前对象池实例,将其返回到对象池以供重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 基于排序字典实现的一对多关系的映射列表类,将唯一键映射到包含多个值的列表。 - /// 用于在多个值与一个键关联的情况下进行管理和存储。 - /// - /// 字典中键的类型。 - /// 列表中值的类型。 - public class SortedOneToManyList : SortedDictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit; - - /// - /// 创建一个新的 实例。 - /// - public SortedOneToManyList() - { - } - - /// - /// 创建一个新的 实例,设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public SortedOneToManyList(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断列表中是否包含指定的键值对。 - /// - /// 要查找的键。 - /// 要查找的值。 - /// 如果键值对存在,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 将指定值添加到给定键关联的列表中。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - base[key] = list; - return; - } - - list.Add(value); - } - - /// - /// 获取指定键关联的列表中的第一个值。 - /// - /// 要查找值的键。 - /// 指定键关联的列表中的第一个值,如果列表为空则返回默认值。 - public TValue First(TKey key) - { - return !TryGetValue(key, out var list) ? default : list.FirstOrDefault(); - } - - /// - /// 从指定键关联的列表中移除特定值。 - /// - /// 要移除值的键。 - /// 要移除的值。 - - public void RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - return; - } - - list.Remove(value); - - if (list.Count == 0) - { - RemoveKey(key); - } - } - - /// - /// 从字典中移除指定键以及关联的列表,并将列表进行回收。 - /// - /// 要移除的键。 - - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) - { - return; - } - - Remove(key); - Recycle(list); - } - - /// - /// 获取一个空的或回收的列表。 - /// - /// 获取的列表实例。 - private List Fetch() - { - return _queue.Count <= 0 ? new List() : _queue.Dequeue(); - } - - /// - /// 回收一个列表,将其清空并放入回收队列中。如果缓存数量超过限制,则丢弃列表而不进行回收 - /// - /// 要回收的列表。 - private void Recycle(List list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) - { - return; - } - - _queue.Enqueue(list); - } - - /// - /// 重写 Clear 方法,清空字典并清空回收队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/DictionaryExtensions.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/DictionaryExtensions.cs deleted file mode 100644 index ed0aa57..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/DictionaryExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -#pragma warning disable CS8601 // Possible null reference assignment. - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供对字典的扩展方法。 - /// - public static class DictionaryExtensions - { - /// - /// 尝试从字典中移除指定键,并返回相应的值。 - /// - /// 字典中键的类型。 - /// 字典中值的类型。 - /// 要操作的字典实例。 - /// 要移除的键。 - /// 从字典中移除的值(如果成功移除)。 - /// 如果成功移除键值对,则为 true;否则为 false。 - public static bool TryRemove(this IDictionary self, T key, out TV value) - { - if (!self.TryGetValue(key, out value)) - { - return false; - } - - self.Remove(key); - return true; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/DictionaryPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/DictionaryPool.cs deleted file mode 100644 index 567901c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/DictionaryPool.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个可以使用对象池管理的字典类。 - /// - /// 字典中键的类型。 - /// 字典中值的类型。 - public sealed class DictionaryPool : Dictionary, IDisposable, IPool where TM : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static DictionaryPool Create() - { -#if FANTASY_WEBGL - var dictionary = Pool>.Rent(); -#else - var dictionary = MultiThreadPool.Rent>(); -#endif - dictionary._isDispose = false; - dictionary._isPool = true; - return dictionary; - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/DoubleMapDictionaryPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/DoubleMapDictionaryPool.cs deleted file mode 100644 index e868710..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/DoubleMapDictionaryPool.cs +++ /dev/null @@ -1,289 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个双向映射字典对象池类,用于双向键值对映射。 - /// - /// 字典中键的类型。 - /// 字典中值的类型。 - public class DoubleMapDictionaryPool : DoubleMapDictionary, IDisposable, IPool where TKey : notnull where TValue : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static DoubleMapDictionaryPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 可以实现双向映射的字典类,用于将键和值进行双向映射。 - /// - /// 键的类型,不能为 null。 - /// 值的类型,不能为 null。 - public class DoubleMapDictionary where TK : notnull where TV : notnull - { - private readonly Dictionary _kv = new Dictionary(); - private readonly Dictionary _vk = new Dictionary(); - - /// - /// 创建一个新的空的 实例。 - /// - public DoubleMapDictionary() { } - - /// - /// 创建一个新的具有指定初始容量的 实例。 - /// - /// 初始容量。 - public DoubleMapDictionary(int capacity) - { - _kv = new Dictionary(capacity); - _vk = new Dictionary(capacity); - } - - /// - /// 获取包含字典中所有键的列表。 - /// - public List Keys => new List(_kv.Keys); - - /// - /// 获取包含字典中所有值的列表。 - /// - public List Values => new List(_vk.Keys); - - /// - /// 对字典中的每个键值对执行指定的操作。 - /// - /// 要执行的操作。 - public void ForEach(Action action) - { - if (action == null) - { - return; - } - - var keys = _kv.Keys; - foreach (var key in keys) - { - action(key, _kv[key]); - } - } - - /// - /// 将指定的键值对添加到字典中。 - /// - /// 要添加的键。 - /// 要添加的值。 - public void Add(TK key, TV value) - { - if (key == null || value == null || _kv.ContainsKey(key) || _vk.ContainsKey(value)) - { - return; - } - - _kv.Add(key, value); - _vk.Add(value, key); - } - - /// - /// 根据指定的键获取相应的值。 - /// - /// 要查找值的键。 - /// 与指定键关联的值,如果找不到键,则返回默认值。 - public TV GetValueByKey(TK key) - { - if (key != null && _kv.ContainsKey(key)) - { - return _kv[key]; - } - - return default; - } - - /// - /// 尝试根据指定的键获取相应的值。 - /// - /// 要查找值的键。 - /// 如果找到,则为与指定键关联的值;否则为值的默认值。 - /// 如果找到键,则为 true;否则为 false。 - public bool TryGetValueByKey(TK key, out TV value) - { - var result = key != null && _kv.ContainsKey(key); - - value = result ? _kv[key] : default; - - return result; - } - - /// - /// 根据指定的值获取相应的键。 - /// - /// 要查找键的值。 - /// 与指定值关联的键,如果找不到值,则返回默认键。 - public TK GetKeyByValue(TV value) - { - if (value != null && _vk.ContainsKey(value)) - { - return _vk[value]; - } - - return default; - } - - /// - /// 尝试根据指定的值获取相应的键。 - /// - /// 要查找键的值。 - /// 如果找到,则为与指定值关联的键;否则为键的默认值。 - /// 如果找到值,则为 true;否则为 false。 - public bool TryGetKeyByValue(TV value, out TK key) - { - var result = value != null && _vk.ContainsKey(value); - - key = result ? _vk[value] : default; - - return result; - } - - /// - /// 根据指定的键移除键值对。 - /// - /// 要移除的键。 - public void RemoveByKey(TK key) - { - if (key == null) - { - return; - } - - if (!_kv.TryGetValue(key, out var value)) - { - return; - } - - _kv.Remove(key); - _vk.Remove(value); - } - - /// - /// 根据指定的值移除键值对。 - /// - /// 要移除的值。 - public void RemoveByValue(TV value) - { - if (value == null) - { - return; - } - - if (!_vk.TryGetValue(value, out var key)) - { - return; - } - - _kv.Remove(key); - _vk.Remove(value); - } - - /// - /// 清空字典中的所有键值对。 - /// - public void Clear() - { - _kv.Clear(); - _vk.Clear(); - } - - /// - /// 判断字典是否包含指定的键。 - /// - /// 要检查的键。 - /// 如果字典包含指定的键,则为 true;否则为 false。 - public bool ContainsKey(TK key) - { - return key != null && _kv.ContainsKey(key); - } - - /// - /// 判断字典是否包含指定的值。 - /// - /// 要检查的值。 - /// 如果字典包含指定的值,则为 true;否则为 false。 - public bool ContainsValue(TV value) - { - return value != null && _vk.ContainsKey(value); - } - - /// - /// 判断字典是否包含指定的键值对。 - /// - /// 要检查的键。 - /// 要检查的值。 - /// 如果字典包含指定的键值对,则为 true;否则为 false。 - public bool Contains(TK key, TV value) - { - if (key == null || value == null) - { - return false; - } - - return _kv.ContainsKey(key) && _vk.ContainsKey(value); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/EntityDictionary.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/EntityDictionary.cs deleted file mode 100644 index fc4d44f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/EntityDictionary.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个带资源释放功能的实体字典类,支持使用对象池管理。 - /// - /// 字典中键的类型。 - /// 字典中值的类型,必须实现 IDisposable 接口。 - public sealed class EntityDictionary : Dictionary, IDisposable, IPool where TN : IDisposable where TM : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static EntityDictionary Create() - { -#if FANTASY_WEBGL - var entityDictionary = Pool>.Rent(); -#else - var entityDictionary = MultiThreadPool.Rent>(); -#endif - entityDictionary._isDispose = false; - entityDictionary._isPool = true; - return entityDictionary; - } - - /// - /// 清空字典中的所有键值对,并释放值的资源。 - /// - public new void Clear() - { - foreach (var keyValuePair in this) - { - keyValuePair.Value.Dispose(); - } - - base.Clear(); - } - - /// - /// 清空字典中的所有键值对,但不释放值的资源。 - /// - public void ClearNotDispose() - { - base.Clear(); - } - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/OneToManyDictionaryPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/OneToManyDictionaryPool.cs deleted file mode 100644 index 0515423..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/OneToManyDictionaryPool.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8603 -#pragma warning disable CS8601 - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 一对多映射关系的字典对象池。 - /// - /// 外部字典中的键类型。 - /// 内部字典中的键类型。 - /// 内部字典中的值类型。 - public class OneToManyDictionaryPool : OneToManyDictionary, IDisposable, IPool where TKey : notnull where TValueKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 的实例。 - /// - /// 新创建的 OneToManyDictionaryPool 实例。 - public static OneToManyDictionaryPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前实例及其资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 一对多映射关系的字典。每个键都对应一个内部字典,该内部字典将键值映射到相应的值。 - /// - /// 外部字典中的键类型。 - /// 内部字典中的键类型。 - /// 内部字典中的值类型。 - public class OneToManyDictionary : Dictionary> - where TKey : notnull where TValueKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit = 120; - - /// - /// 创建一个新的 实例。 - /// - public OneToManyDictionary() { } - - /// - /// 创建一个新的 实例,并指定最大缓存数量。 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManyDictionary(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 检查是否包含指定的键值对。 - /// - /// 外部字典中的键。 - /// 内部字典中的键。 - /// 如果包含指定的键值对,则为 true;否则为 false。 - public bool Contains(TKey key, TValueKey valueKey) - { - TryGetValue(key, out var dic); - - return dic != null && dic.ContainsKey(valueKey); - } - - /// - /// 尝试获取指定键值对的值。 - /// - /// 外部字典中的键。 - /// 内部字典中的键。 - /// 获取的值,如果操作成功,则为值;否则为默认值。 - /// 如果操作成功,则为 true;否则为 false。 - public bool TryGetValue(TKey key, TValueKey valueKey, out TValue value) - { - value = default; - return TryGetValue(key, out var dic) && dic.TryGetValue(valueKey, out value); - } - - /// - /// 获取指定键的第一个值。 - /// - /// 要获取第一个值的键。 - public TValue First(TKey key) - { - return !TryGetValue(key, out var dic) ? default : dic.First().Value; - } - - /// - /// 向字典中添加指定的键值对。 - /// - /// 要添加键值对的键。 - /// 要添加键值对的内部字典键。 - /// 要添加的值。 - public void Add(TKey key, TValueKey valueKey, TValue value) - { - if (!TryGetValue(key, out var dic)) - { - dic = Fetch(); - dic[valueKey] = value; - // dic.Add(valueKey, value); - Add(key, dic); - - return; - } - - dic[valueKey] = value; - // dic.Add(valueKey, value); - } - - /// - /// 从字典中移除指定的键值对。 - /// - /// 要移除键值对的键。 - /// 要移除键值对的内部字典键。 - /// 如果成功移除键值对,则为 true;否则为 false。 - public bool Remove(TKey key, TValueKey valueKey) - { - if (!TryGetValue(key, out var dic)) return false; - - var result = dic.Remove(valueKey); - - if (dic.Count == 0) RemoveKey(key); - - return result; - } - - /// - /// 从字典中移除指定的键值对。 - /// - /// 要移除键值对的键。 - /// 要移除键值对的内部字典键。 - /// 如果成功移除键值对,则为移除的值;否则为默认值。 - /// 如果成功移除键值对,则为 true;否则为 false。 - public bool Remove(TKey key, TValueKey valueKey, out TValue value) - { - if (!TryGetValue(key, out var dic)) - { - value = default; - return false; - } - - var result = dic.TryGetValue(valueKey, out value); - - if (result) dic.Remove(valueKey); - - if (dic.Count == 0) RemoveKey(key); - - return result; - } - - /// - /// 移除字典中的指定键及其相关的所有键值对。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var dic)) return; - - Remove(key); - Recycle(dic); - } - - /// - /// 从对象池中获取一个内部字典实例,如果池中没有,则创建一个新实例。 - /// - /// 获取的内部字典实例。 - private Dictionary Fetch() - { - return _queue.Count <= 0 ? new Dictionary() : _queue.Dequeue(); - } - - /// - /// 将不再使用的内部字典实例放回对象池中,以便后续重用。 - /// - /// 要放回对象池的内部字典实例。 - private void Recycle(Dictionary dic) - { - dic.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(dic); - } - - /// - /// 清空字典中的所有键值对,并将不再使用的内部字典实例放回对象池中。 - /// - public new void Clear() - { - foreach (var keyValuePair in this) Recycle(keyValuePair.Value); - - base.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/OneToManySortedDictionaryPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/OneToManySortedDictionaryPool.cs deleted file mode 100644 index 127a8ac..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/OneToManySortedDictionaryPool.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8601 - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 一对多映射关系的排序字典对象池。 - /// - /// 外部字典中的键类型。 - /// 内部字典中的排序键类型。 - /// 内部字典中的值类型。 - public class OneToManySortedDictionaryPool : OneToManySortedDictionary, IDisposable, IPool where TKey : notnull where TSortedKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 的实例。 - /// - /// 新创建的 OneToManySortedDictionaryPool 实例。 - public static OneToManySortedDictionaryPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前实例及其资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 一对多映射关系的排序字典。每个外部键映射到一个内部排序字典,该内部排序字典将排序键映射到相应的值。 - /// - /// 外部字典中的键类型。 - /// 内部字典中的排序键类型。 - /// 内部字典中的值类型。 - public class - OneToManySortedDictionary : Dictionary> - where TSortedKey : notnull where TKey : notnull - { - /// 缓存队列的回收限制 - private readonly int _recyclingLimit = 120; - /// 缓存队列,用于存储已回收的内部排序字典 - private readonly Queue> _queue = new Queue>(); - - /// - /// 创建一个新的 实例。 - /// - protected OneToManySortedDictionary() { } - - /// - /// 创建一个新的 实例。设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManySortedDictionary(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 检查字典是否包含指定的外部键。 - /// - /// 要检查的外部键。 - /// 如果字典包含指定的外部键,则为 true;否则为 false。 - public bool Contains(TKey key) - { - return this.ContainsKey(key); - } - - /// - /// 检查字典是否包含指定的外部键和排序键。 - /// - /// 要检查的外部键。 - /// 要检查的排序键。 - /// 如果字典包含指定的外部键和排序键,则为 true;否则为 false。 - public bool Contains(TKey key, TSortedKey sortedKey) - { - return TryGetValue(key, out var dic) && dic.ContainsKey(sortedKey); - } - - /// - /// 尝试从字典中获取指定外部键对应的内部排序字典。 - /// - /// 要获取内部排序字典的外部键。 - /// 获取到的内部排序字典,如果找不到则为 null。 - /// 如果找到内部排序字典,则为 true;否则为 false。 - public new bool TryGetValue(TKey key, out SortedDictionary dic) - { - return base.TryGetValue(key, out dic); - } - - /// - /// 尝试从字典中获取指定外部键和排序键对应的值。 - /// - /// 要获取值的外部键。 - /// 要获取值的排序键。 - /// 获取到的值,如果找不到则为 default。 - /// 如果找到值,则为 true;否则为 false。 - public bool TryGetValueBySortedKey(TKey key, TSortedKey sortedKey, out TValue value) - { - if (base.TryGetValue(key, out var dic)) - { - return dic.TryGetValue(sortedKey, out value); - } - - value = default; - return false; - } - - /// - /// 向字典中添加一个值,关联到指定的外部键和排序键。 - /// - /// 要关联值的外部键。 - /// 要关联值的排序键。 - /// 要添加的值。 - public void Add(TKey key, TSortedKey sortedKey, TValue value) - { - if (!TryGetValue(key, out var dic)) - { - dic = Fetch(); - dic.Add(sortedKey, value); - Add(key, dic); - - return; - } - - dic.Add(sortedKey, value); - } - - /// - /// 从字典中移除指定外部键和排序键关联的值。 - /// - /// 要移除值的外部键。 - /// 要移除值的排序键。 - /// 如果成功移除值,则为 true;否则为 false。 - public bool RemoveSortedKey(TKey key, TSortedKey sortedKey) - { - if (!TryGetValue(key, out var dic)) - { - return false; - } - - var isRemove = dic.Remove(sortedKey); - - if (dic.Count == 0) - { - isRemove = RemoveKey(key); - } - - return isRemove; - } - - /// - /// 从字典中移除指定外部键及其关联的所有值。 - /// - /// 要移除的外部键。 - /// 如果成功移除外部键及其关联的所有值,则为 true;否则为 false。 - public bool RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) - { - return false; - } - - Remove(key); - Recycle(list); - return true; - } - - /// - /// 从缓存队列中获取一个内部排序字典。 - /// - /// 一个内部排序字典。 - private SortedDictionary Fetch() - { - return _queue.Count <= 0 ? new SortedDictionary() : _queue.Dequeue(); - } - - /// - /// 回收一个内部排序字典到缓存队列。 - /// - /// 要回收的内部排序字典。 - private void Recycle(SortedDictionary dic) - { - dic.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) - { - return; - } - - _queue.Enqueue(dic); - } - - /// - /// 清空字典以及内部排序字典缓存队列,释放所有资源。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/ReuseDictionary.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/ReuseDictionary.cs deleted file mode 100644 index ebe12e9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/ReuseDictionary.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个可以重用的字典类,支持使用对象池管理。 - /// - /// 字典中键的类型。 - /// 字典中值的类型。 - public sealed class ReuseDictionary : Dictionary, IDisposable, IPool where TM : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static ReuseDictionary Create() - { -#if FANTASY_WEBGL - var entityDictionary = Pool>.Rent(); -#else - var entityDictionary = MultiThreadPool.Rent>(); -#endif - entityDictionary._isDispose = false; - entityDictionary._isPool = true; - return entityDictionary; - } - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/SortedDictionaryPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/SortedDictionaryPool.cs deleted file mode 100644 index 8db66a8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/Dictionary/SortedDictionaryPool.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个可以使用对象池管理的排序字典类。 - /// - /// - /// - public sealed class SortedDictionaryPool : SortedDictionary, IDisposable, IPool where TM : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static SortedDictionaryPool Create() - { -#if FANTASY_WEBGL - var dictionary = Pool>.Rent(); -#else - var dictionary = MultiThreadPool.Rent>(); -#endif - dictionary._isDispose = false; - dictionary._isPool = true; - return dictionary; - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueGenerics.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueGenerics.cs deleted file mode 100644 index 2ef6704..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueGenerics.cs +++ /dev/null @@ -1,121 +0,0 @@ -// ReSharper disable SwapViaDeconstruction -// ReSharper disable UseIndexFromEndExpression -// ReSharper disable ConvertToPrimaryConstructor -using System; -using System.Collections.Generic; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -#pragma warning disable CS8601 // Possible null reference assignment. -namespace Fantasy.DataStructure.PriorityQueue -{ - /// - /// 优先队列 - /// - /// 节点数据 - /// 排序的类型、 - public sealed class PriorityQueue where TPriority : IComparable - { - private readonly List> _heap; - - public PriorityQueue(int initialCapacity = 16) - { - _heap = new List>(initialCapacity); - } - - public int Count => _heap.Count; - - public void Enqueue(TElement element, TPriority priority) - { - _heap.Add(new PriorityQueueItem(element, priority)); - HeapifyUp(_heap.Count - 1); - } - - public TElement Dequeue() - { - if (_heap.Count == 0) - { - throw new InvalidOperationException("The queue is empty."); - } - - var item = _heap[0]; - _heap[0] = _heap[_heap.Count - 1]; - _heap.RemoveAt(_heap.Count - 1); - HeapifyDown(0); - return item.Element; - } - - public bool TryDequeue(out TElement element) - { - if (_heap.Count == 0) - { - element = default(TElement); - return false; - } - - element = Dequeue(); - return true; - } - - public TElement Peek() - { - if (_heap.Count == 0) - { - throw new InvalidOperationException("The queue is empty."); - } - return _heap[0].Element; - } - - // ReSharper disable once IdentifierTypo - private void HeapifyUp(int index) - { - while (index > 0) - { - var parentIndex = (index - 1) / 2; - if (_heap[index].Priority.CompareTo(_heap[parentIndex].Priority) >= 0) - { - break; - } - Swap(index, parentIndex); - index = parentIndex; - } - } - - // ReSharper disable once IdentifierTypo - private void HeapifyDown(int index) - { - var lastIndex = _heap.Count - 1; - while (true) - { - var smallestIndex = index; - var leftChildIndex = 2 * index + 1; - var rightChildIndex = 2 * index + 2; - - if (leftChildIndex <= lastIndex && _heap[leftChildIndex].Priority.CompareTo(_heap[smallestIndex].Priority) < 0) - { - smallestIndex = leftChildIndex; - } - - if (rightChildIndex <= lastIndex && _heap[rightChildIndex].Priority.CompareTo(_heap[smallestIndex].Priority) < 0) - { - smallestIndex = rightChildIndex; - } - - if (smallestIndex == index) - { - break; - } - - Swap(index, smallestIndex); - index = smallestIndex; - } - } - - private void Swap(int index1, int index2) - { - var temp = _heap[index1]; - _heap[index1] = _heap[index2]; - _heap[index2] = temp; - } - } -} - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueItem.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueItem.cs deleted file mode 100644 index 5b020b2..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueItem.cs +++ /dev/null @@ -1,30 +0,0 @@ -// ReSharper disable ConvertToPrimaryConstructor -// ReSharper disable SwapViaDeconstruction -// ReSharper disable InconsistentNaming -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.DataStructure.PriorityQueue -{ - public struct PriorityQueueItemUint - { - public T Element { get; set; } - public uint Priority { get; set; } - - public PriorityQueueItemUint(T element, uint priority) - { - Element = element; - Priority = priority; - } - } - - public struct PriorityQueueItem - { - public T Element { get; } - public T1 Priority { get; } - - public PriorityQueueItem(T element, T1 priority) - { - Element = element; - Priority = priority; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueSimple.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueSimple.cs deleted file mode 100644 index 63a4418..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueSimple.cs +++ /dev/null @@ -1,116 +0,0 @@ -// ReSharper disable SwapViaDeconstruction -// ReSharper disable UseIndexFromEndExpression -// ReSharper disable ConvertToPrimaryConstructor -using System; -using System.Collections.Generic; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8601 // Possible null reference assignment. -namespace Fantasy.DataStructure.PriorityQueue -{ - public sealed class PriorityQueue where T : IComparable - { - private readonly List _heap; - - public PriorityQueue(int initialCapacity = 16) - { - _heap = new List(initialCapacity); - } - - public int Count => _heap.Count; - - public void Enqueue(T item) - { - _heap.Add(item); - HeapifyUp(_heap.Count - 1); - } - - public T Dequeue() - { - if (_heap.Count == 0) - { - throw new InvalidOperationException("The queue is empty."); - } - - var item = _heap[0]; - var heapCount = _heap.Count - 1; - _heap[0] = _heap[heapCount]; - _heap.RemoveAt(heapCount); - HeapifyDown(0); - return item; - } - - public bool TryDequeue(out T item) - { - if (_heap.Count == 0) - { - item = default(T); - return false; - } - - item = Dequeue(); - return true; - } - - public T Peek() - { - if (_heap.Count == 0) - { - throw new InvalidOperationException("The queue is empty."); - } - return _heap[0]; - } - - // ReSharper disable once IdentifierTypo - private void HeapifyUp(int index) - { - while (index > 0) - { - var parentIndex = (index - 1) / 2; - if (_heap[index].CompareTo(_heap[parentIndex]) >= 0) - { - break; - } - Swap(index, parentIndex); - index = parentIndex; - } - } - - // ReSharper disable once IdentifierTypo - private void HeapifyDown(int index) - { - var lastIndex = _heap.Count - 1; - while (true) - { - var smallestIndex = index; - var leftChildIndex = 2 * index + 1; - var rightChildIndex = 2 * index + 2; - - if (leftChildIndex <= lastIndex && _heap[leftChildIndex].CompareTo(_heap[smallestIndex]) < 0) - { - smallestIndex = leftChildIndex; - } - - if (rightChildIndex <= lastIndex && _heap[rightChildIndex].CompareTo(_heap[smallestIndex]) < 0) - { - smallestIndex = rightChildIndex; - } - - if (smallestIndex == index) - { - break; - } - - Swap(index, smallestIndex); - index = smallestIndex; - } - } - - private void Swap(int index1, int index2) - { - var temp = _heap[index1]; - _heap[index1] = _heap[index2]; - _heap[index2] = temp; - } - } -} - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTable.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTable.cs deleted file mode 100644 index acbc2c1..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTable.cs +++ /dev/null @@ -1,190 +0,0 @@ - -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -namespace Fantasy.DataStructure.SkipTable -{ - /// - /// 跳表数据结构(升序版) - /// - /// 跳表中存储的值的类型。 - public class SkipTable : SkipTableBase - { - /// - /// 创建一个新的跳表实例。 - /// - /// 跳表的最大层数。 - public SkipTable(int maxLayer = 8) : base(maxLayer) { } - - /// - /// 向跳表中添加一个新节点。 - /// - /// 节点的主排序键。 - /// 节点的副排序键。 - /// 节点的唯一键。 - /// 要添加的值。 - public override void Add(long sortKey, long viceKey, long key, TValue value) - { - var rLevel = 1; - - while (rLevel <= MaxLayer && Random.Next(3) == 0) - { - ++rLevel; - } - - SkipTableNode cur = TopHeader, last = null; - - for (var layer = MaxLayer; layer >= 1; --layer) - { - // 节点有next节点,且 (next主键 < 插入主键) 或 (next主键 == 插入主键 且 next副键 < 插入副键) - while (cur.Right != null && ((cur.Right.SortKey < sortKey) || - (cur.Right.SortKey == sortKey && cur.Right.ViceKey < viceKey))) - { - cur = cur.Right; - } - - if (layer <= rLevel) - { - var currentRight = cur.Right; - - // 在当前层插入新节点 - cur.Right = new SkipTableNode(sortKey, viceKey, key, value, layer == 1 ? cur.Index + 1 : 0, cur, cur.Right, null); - - if (currentRight != null) - { - currentRight.Left = cur.Right; - } - - if (last != null) - { - last.Down = cur.Right; - } - - if (layer == 1) - { - // 更新索引信息 - cur.Right.Index = cur.Index + 1; - Node.Add(key, cur.Right); - - SkipTableNode v = cur.Right.Right; - - while (v != null) - { - v.Index++; - v = v.Right; - } - } - - last = cur.Right; - } - - cur = cur.Down; - } - } - - /// - /// 从跳表中移除一个节点。 - /// - /// 节点的主排序键。 - /// 节点的副排序键。 - /// 节点的唯一键。 - /// 被移除的节点的值。 - /// 如果成功移除节点,则为 true;否则为 false。 - public override bool Remove(long sortKey, long viceKey, long key, out TValue value) - { - value = default; - var seen = false; - var cur = TopHeader; - - for (var layer = MaxLayer; layer >= 1; --layer) - { - // 先按照主键查找 再 按副键查找 - while (cur.Right != null && cur.Right.SortKey < sortKey && cur.Right.Key != key) cur = cur.Right; - while (cur.Right != null && (cur.Right.SortKey == sortKey && cur.Right.ViceKey <= viceKey) && - cur.Right.Key != key) cur = cur.Right; - - var isFind = false; - var currentCur = cur; - SkipTableNode removeCur = null; - // 如果当前不是要删除的节点、但主键和副键都一样、需要特殊处理下。 - if (cur.Right != null && cur.Right.Key == key) - { - isFind = true; - removeCur = cur.Right; - currentCur = cur; - } - else - { - // 先向左查找下 - var currentNode = cur.Left; - while (currentNode != null && currentNode.SortKey == sortKey && currentNode.ViceKey == viceKey) - { - if (currentNode.Key == key) - { - isFind = true; - removeCur = currentNode; - currentCur = currentNode.Left; - break; - } - - currentNode = currentNode.Left; - } - - // 再向右查找下 - if (!isFind) - { - currentNode = cur.Right; - while (currentNode != null && currentNode.SortKey == sortKey && currentNode.ViceKey == viceKey) - { - if (currentNode.Key == key) - { - isFind = true; - removeCur = currentNode; - currentCur = currentNode.Left; - break; - } - - currentNode = currentNode.Right; - } - } - } - - if (isFind && currentCur != null) - { - value = removeCur.Value; - currentCur.Right = removeCur.Right; - - if (removeCur.Right != null) - { - removeCur.Right.Left = currentCur; - removeCur.Right = null; - } - - removeCur.Left = null; - removeCur.Down = null; - removeCur.Value = default; - - if (layer == 1) - { - var tempCur = currentCur.Right; - while (tempCur != null) - { - tempCur.Index--; - tempCur = tempCur.Right; - } - - Node.Remove(removeCur.Key); - } - - seen = true; - } - - cur = cur.Down; - } - - return seen; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTableBase.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTableBase.cs deleted file mode 100644 index 82783e8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTableBase.cs +++ /dev/null @@ -1,282 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using Fantasy.DataStructure.Collection; - -#pragma warning disable CS8601 -#pragma warning disable CS8603 -#pragma warning disable CS8625 -#pragma warning disable CS8604 - -namespace Fantasy.DataStructure.SkipTable -{ - /// - /// 抽象的跳表基类,提供跳表的基本功能和操作。 - /// - /// 跳表中存储的值的类型。 - public abstract class SkipTableBase : IEnumerable> - { - /// - /// 跳表的最大层数 - /// - public readonly int MaxLayer; - /// - /// 跳表的顶部头节点 - /// - public readonly SkipTableNode TopHeader; - /// - /// 跳表的底部头节点 - /// - public SkipTableNode BottomHeader; - /// - /// 跳表中节点的数量,使用了 Node 字典的计数 - /// - public int Count => Node.Count; - /// - /// 用于生成随机数的随机数生成器 - /// - protected readonly Random Random = new Random(); - /// - /// 存储跳表节点的字典 - /// - protected readonly Dictionary> Node = new(); - /// - /// 用于辅助反向查找的栈 - /// - protected readonly Stack> AntiFindStack = new Stack>(); - - /// - /// 初始化一个新的跳表实例。 - /// - /// 跳表的最大层数,默认为 8。 - protected SkipTableBase(int maxLayer = 8) - { - MaxLayer = maxLayer; - var cur = TopHeader = new SkipTableNode(long.MinValue, 0, 0, default, 0, null, null, null); - - for (var layer = MaxLayer - 1; layer >= 1; --layer) - { - cur.Down = new SkipTableNode(long.MinValue, 0, 0, default, 0, null, null, null); - cur = cur.Down; - } - - BottomHeader = cur; - } - - /// - /// 获取指定键的节点的值,若不存在则返回默认值。 - /// - /// 要查找的键。 - public TValue this[long key] => !TryGetValueByKey(key, out TValue value) ? default : value; - - /// - /// 获取指定键的节点在跳表中的排名。 - /// - /// 要查找的键。 - /// 节点的排名。 - public int GetRanking(long key) - { - if (!Node.TryGetValue(key, out var node)) - { - return 0; - } - - return node.Index; - } - - /// - /// 获取指定键的反向排名,即在比该键更大的节点中的排名。 - /// - /// 要查找的键。 - /// 反向排名。 - public int GetAntiRanking(long key) - { - var ranking = GetRanking(key); - - if (ranking == 0) - { - return 0; - } - - return Count + 1 - ranking; - } - - /// - /// 尝试通过键获取节点的值。 - /// - /// 要查找的键。 - /// 获取到的节点的值,如果键不存在则为默认值。 - /// 是否成功获取节点的值。 - public bool TryGetValueByKey(long key, out TValue value) - { - if (!Node.TryGetValue(key, out var node)) - { - value = default; - return false; - } - - value = node.Value; - return true; - } - - /// - /// 尝试通过键获取节点。 - /// - /// 要查找的键。 - /// 获取到的节点,如果键不存在则为 null。 - /// 是否成功获取节点。 - public bool TryGetNodeByKey(long key, out SkipTableNode node) - { - if (Node.TryGetValue(key, out node)) - { - return true; - } - - return false; - } - - /// - /// 在跳表中查找节点,返回从起始位置到结束位置的节点列表。 - /// - /// 起始位置的排名。 - /// 结束位置的排名。 - /// 用于存储节点列表的 实例。 - public void Find(int start, int end, ListPool> list) - { - var cur = BottomHeader; - var count = end - start; - - for (var i = 0; i < start; i++) - { - cur = cur.Right; - } - - for (var i = 0; i <= count; i++) - { - if (cur == null) - { - break; - } - - list.Add(cur); - cur = cur.Right; - } - } - - /// - /// 在跳表中进行反向查找节点,返回从结束位置到起始位置的节点列表。 - /// - /// 结束位置的排名。 - /// 起始位置的排名。 - /// 用于存储节点列表的 实例。 - public void AntiFind(int start, int end, ListPool> list) - { - var cur = BottomHeader; - start = Count + 1 - start; - end = start - end; - - for (var i = 0; i < start; i++) - { - cur = cur.Right; - - if (cur == null) - { - break; - } - - if (i < end) - { - continue; - } - - AntiFindStack.Push(cur); - } - - while (AntiFindStack.TryPop(out var node)) - { - list.Add(node); - } - } - - /// - /// 获取跳表中最后一个节点的值。 - /// - /// 最后一个节点的值。 - public TValue GetLastValue() - { - var cur = TopHeader; - - while (cur.Right != null || cur.Down != null) - { - while (cur.Right != null) - { - cur = cur.Right; - } - - if (cur.Down != null) - { - cur = cur.Down; - } - } - - return cur.Value; - } - - /// - /// 移除跳表中指定键的节点。 - /// - /// 要移除的节点的键。 - /// 移除是否成功。 - public bool Remove(long key) - { - if (!Node.TryGetValue(key, out var node)) - { - return false; - } - - return Remove(node.SortKey, node.ViceKey, key, out _); - } - - /// - /// 向跳表中添加节点。 - /// - /// 节点的排序键。 - /// 节点的副键。 - /// 节点的键。 - /// 节点的值。 - public abstract void Add(long sortKey, long viceKey, long key, TValue value); - - /// - /// 从跳表中移除指定键的节点。 - /// - /// 节点的排序键。 - /// 节点的副键。 - /// 节点的键。 - /// 被移除的节点的值。 - /// 移除是否成功。 - public abstract bool Remove(long sortKey, long viceKey, long key, out TValue value); - - /// - /// 返回一个枚举器,用于遍历跳表中的节点。 - /// - /// 一个可用于遍历跳表节点的枚举器。 - public IEnumerator> GetEnumerator() - { - var cur = BottomHeader.Right; - while (cur != null) - { - yield return cur; - cur = cur.Right; - } - } - - /// - /// 返回一个非泛型枚举器,用于遍历跳表中的节点。 - /// - /// 一个非泛型枚举器,可用于遍历跳表节点。 - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTableDesc.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTableDesc.cs deleted file mode 100644 index 63daa16..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTableDesc.cs +++ /dev/null @@ -1,188 +0,0 @@ - -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8601 // Possible null reference assignment. -namespace Fantasy.DataStructure.SkipTable -{ - /// - /// 跳表降序版,用于存储降序排列的数据。 - /// - /// 存储的值的类型。 - public class SkipTableDesc : SkipTableBase - { - /// - /// 初始化跳表降序版的新实例。 - /// - /// 跳表的最大层数,默认为 8。 - public SkipTableDesc(int maxLayer = 8) : base(maxLayer) { } - - /// - /// 向跳表中添加一个节点,根据降序规则进行插入。 - /// - /// 排序主键。 - /// 副键。 - /// 键。 - /// 值。 - public override void Add(long sortKey, long viceKey, long key, TValue value) - { - var rLevel = 1; - - while (rLevel <= MaxLayer && Random.Next(3) == 0) - { - ++rLevel; - } - - SkipTableNode cur = TopHeader, last = null; - - for (var layer = MaxLayer; layer >= 1; --layer) - { - // 节点有next节点,且 (next主键 > 插入主键) 或 (next主键 == 插入主键 且 next副键 > 插入副键) - while (cur.Right != null && ((cur.Right.SortKey > sortKey) || - (cur.Right.SortKey == sortKey && cur.Right.ViceKey > viceKey))) - { - cur = cur.Right; - } - - if (layer <= rLevel) - { - var currentRight = cur.Right; - cur.Right = new SkipTableNode(sortKey, viceKey, key, value, - layer == 1 ? cur.Index + 1 : 0, cur, cur.Right, null); - - if (currentRight != null) - { - currentRight.Left = cur.Right; - } - - if (last != null) - { - last.Down = cur.Right; - } - - if (layer == 1) - { - cur.Right.Index = cur.Index + 1; - Node.Add(key, cur.Right); - - SkipTableNode v = cur.Right.Right; - - while (v != null) - { - v.Index++; - v = v.Right; - } - } - - last = cur.Right; - } - - cur = cur.Down; - } - } - - /// - /// 从跳表中移除一个节点,根据降序规则进行移除。 - /// - /// 排序主键。 - /// 副键。 - /// 键。 - /// 移除的节点值。 - /// 如果成功移除节点,则返回 true,否则返回 false。 - public override bool Remove(long sortKey, long viceKey, long key, out TValue value) - { - value = default; - var seen = false; - var cur = TopHeader; - - for (var layer = MaxLayer; layer >= 1; --layer) - { - // 先按照主键查找 再 按副键查找 - while (cur.Right != null && cur.Right.SortKey > sortKey && cur.Right.Key != key) cur = cur.Right; - while (cur.Right != null && (cur.Right.SortKey == sortKey && cur.Right.ViceKey >= viceKey) && - cur.Right.Key != key) cur = cur.Right; - - var isFind = false; - var currentCur = cur; - SkipTableNode removeCur = null; - // 如果当前不是要删除的节点、但主键和副键都一样、需要特殊处理下。 - if (cur.Right != null && cur.Right.Key == key) - { - isFind = true; - removeCur = cur.Right; - currentCur = cur; - } - else - { - // 先向左查找下 - var currentNode = cur.Left; - while (currentNode != null && currentNode.SortKey == sortKey && currentNode.ViceKey == viceKey) - { - if (currentNode.Key == key) - { - isFind = true; - removeCur = currentNode; - currentCur = currentNode.Left; - break; - } - - currentNode = currentNode.Left; - } - - // 再向右查找下 - if (!isFind) - { - currentNode = cur.Right; - while (currentNode != null && currentNode.SortKey == sortKey && currentNode.ViceKey == viceKey) - { - if (currentNode.Key == key) - { - isFind = true; - removeCur = currentNode; - currentCur = currentNode.Left; - break; - } - - currentNode = currentNode.Right; - } - } - } - - if (isFind && currentCur != null) - { - value = removeCur.Value; - currentCur.Right = removeCur.Right; - - if (removeCur.Right != null) - { - removeCur.Right.Left = currentCur; - removeCur.Right = null; - } - - removeCur.Left = null; - removeCur.Down = null; - removeCur.Value = default; - - if (layer == 1) - { - var tempCur = currentCur.Right; - while (tempCur != null) - { - tempCur.Index--; - tempCur = tempCur.Right; - } - - Node.Remove(removeCur.Key); - } - - seen = true; - } - - cur = cur.Down; - } - - return seen; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTableNode.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTableNode.cs deleted file mode 100644 index 8a1a144..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataStructure/SkipTable/SkipTableNode.cs +++ /dev/null @@ -1,68 +0,0 @@ -namespace Fantasy.DataStructure.SkipTable -{ - /// - /// 跳跃表节点。 - /// - /// 节点的值的类型。 - public class SkipTableNode - { - /// - /// 节点在跳跃表中的索引。 - /// - public int Index; - /// - /// 节点的主键。 - /// - public long Key; - /// - /// 节点的排序键。 - /// - public long SortKey; - /// - /// 节点的副键。 - /// - public long ViceKey; - /// - /// 节点存储的值。 - /// - public TValue Value; - /// - /// 指向左侧节点的引用。 - /// - public SkipTableNode Left; - /// - /// 指向右侧节点的引用。 - /// - public SkipTableNode Right; - /// - /// 指向下一层节点的引用。 - /// - public SkipTableNode Down; - - /// - /// 初始化跳跃表节点的新实例。 - /// - /// 节点的排序键。 - /// 节点的副键。 - /// 节点的主键。 - /// 节点存储的值。 - /// 节点在跳跃表中的索引。 - /// 指向左侧节点的引用。 - /// 指向右侧节点的引用。 - /// 指向下一层节点的引用。 - public SkipTableNode(long sortKey, long viceKey, long key, TValue value, int index, - SkipTableNode l, - SkipTableNode r, - SkipTableNode d) - { - Left = l; - Right = r; - Down = d; - Value = value; - Key = key; - Index = index; - SortKey = sortKey; - ViceKey = viceKey; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLock.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLock.cs deleted file mode 100644 index a95d8f3..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLock.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -namespace Fantasy.Async -{ - /// - /// 协程锁专用的对象池 - /// - public sealed class CoroutineLockPool : PoolCore - { - /// - /// 协程锁专用的对象池的构造函数 - /// - public CoroutineLockPool() : base(2000) { } - } - - /// - /// 协程锁 - /// - public sealed class CoroutineLock : IPool, IDisposable - { - private Scene _scene; - private CoroutineLockComponent _coroutineLockComponent; - private readonly Dictionary _queue = new Dictionary(); - /// - /// 表示是否是对象池中创建的 - /// - private bool _isPool; - /// - /// 协程锁的类型 - /// - public long CoroutineLockType { get; private set; } - - internal void Initialize(CoroutineLockComponent coroutineLockComponent, ref long coroutineLockType) - { - _scene = coroutineLockComponent.Scene; - CoroutineLockType = coroutineLockType; - _coroutineLockComponent = coroutineLockComponent; - } - /// - /// 销毁协程锁,如果调用了该方法,所有使用当前协程锁等待的逻辑会按照顺序释放锁。 - /// - public void Dispose() - { - foreach (var (_, coroutineLockQueue) in _queue) - { - while (TryCoroutineLockQueueDequeue(coroutineLockQueue)) { } - } - - _queue.Clear(); - _scene = null; - CoroutineLockType = 0; - _coroutineLockComponent = null; - } - /// - /// 等待上一个任务完成 - /// - /// 需要等待的Id - /// 用于查询协程锁的标记,可不传入,只有在超时的时候排查是哪个锁超时时使用 - /// 等待多久会超时,当到达设定的时候会把当前锁给按照超时处理 - /// - public async FTask Wait(long coroutineLockQueueKey, string tag = null, int timeOut = 30000) - { - var waitCoroutineLock = _coroutineLockComponent.WaitCoroutineLockPool.Rent(this, ref coroutineLockQueueKey, tag, timeOut); - - if (!_queue.TryGetValue(coroutineLockQueueKey, out var queue)) - { - queue = _coroutineLockComponent.CoroutineLockQueuePool.Rent(); - _queue.Add(coroutineLockQueueKey, queue); - return waitCoroutineLock; - } - - queue.Enqueue(waitCoroutineLock); - return await waitCoroutineLock.Tcs; - } - /// - /// 按照先入先出的顺序,释放最早的一个协程锁 - /// - /// - public void Release(long coroutineLockQueueKey) - { - if (!_queue.TryGetValue(coroutineLockQueueKey, out var coroutineLockQueue)) - { - return; - } - - if (!TryCoroutineLockQueueDequeue(coroutineLockQueue)) - { - _queue.Remove(coroutineLockQueueKey); - } - } - - private bool TryCoroutineLockQueueDequeue(CoroutineLockQueue coroutineLockQueue) - { - if (!coroutineLockQueue.TryDequeue(out var waitCoroutineLock)) - { - _coroutineLockComponent.CoroutineLockQueuePool.Return(coroutineLockQueue); - return false; - } - - if (waitCoroutineLock.TimerId != 0) - { - _scene.TimerComponent.Net.Remove(waitCoroutineLock.TimerId); - } - - try - { - // 放到下一帧执行,如果不这样会导致逻辑的顺序不正常。 - _scene.ThreadSynchronizationContext.Post(waitCoroutineLock.SetResult); - } - catch (Exception e) - { - Log.Error($"Error in disposing CoroutineLock: {e}"); - } - - return true; - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockComponent.cs deleted file mode 100644 index fe03298..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockComponent.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Collections.Generic; -using Fantasy.Entitas; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Async -{ - /// - /// 协程锁组件 - /// - public class CoroutineLockComponent : Entity - { - private long _lockId; - private CoroutineLockPool _coroutineLockPool; - internal WaitCoroutineLockPool WaitCoroutineLockPool { get; private set; } - internal CoroutineLockQueuePool CoroutineLockQueuePool { get; private set; } - private readonly Dictionary _coroutineLocks = new Dictionary(); - internal CoroutineLockComponent Initialize() - { - _coroutineLockPool = new CoroutineLockPool(); - CoroutineLockQueuePool = new CoroutineLockQueuePool(); - WaitCoroutineLockPool = new WaitCoroutineLockPool(this); - return this; - } - - internal long LockId => ++_lockId; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - public override void Dispose() -#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member - { - if (IsDisposed) - { - return; - } - - _lockId = 0; - base.Dispose(); - } - - /// - /// 创建一个新的协程锁 - /// 使用这个方法创建的协程锁,需要手动释放管理CoroutineLock。 - /// 不会再CoroutineLockComponent理进行管理。 - /// - /// - /// - public CoroutineLock Create(long coroutineLockType) - { - var coroutineLock = _coroutineLockPool.Rent(); - coroutineLock.Initialize(this, ref coroutineLockType); - return coroutineLock; - } - - /// - /// 请求一个协程锁。 - /// 使用这个方法创建的协程锁,会自动释放CoroutineLockQueueType。 - /// - /// 锁类型 - /// 锁队列Id - /// 当某些锁超时,需要一个标记来方便排查问题,正常的情况下这个默认为null就可以。 - /// 设置锁的超时时间,让超过设置的时间会触发超时,保证锁不会因为某一个锁一直不解锁导致卡住的问题。 - /// - /// 返回的WaitCoroutineLock通过Dispose来解除这个锁、建议用using来保住这个锁。 - /// 也可以返回的WaitCoroutineLock通过CoroutineLockComponent.UnLock来解除这个锁。 - /// - public FTask Wait(long coroutineLockType, long coroutineLockQueueKey, string tag = null, int time = 30000) - { - if (!_coroutineLocks.TryGetValue(coroutineLockType, out var coroutineLock)) - { - coroutineLock = _coroutineLockPool.Rent(); - coroutineLock.Initialize(this, ref coroutineLockType); - _coroutineLocks.Add(coroutineLockType, coroutineLock); - } - - return coroutineLock.Wait(coroutineLockQueueKey, tag, time); - } - - /// - /// 解除一个协程锁。 - /// - /// - /// - public void Release(long coroutineLockType, long coroutineLockQueueKey) - { - if (IsDisposed) - { - return; - } - - if (!_coroutineLocks.TryGetValue(coroutineLockType, out var coroutineLock)) - { - return; - } - - coroutineLock.Release(coroutineLockQueueKey); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockQueue.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockQueue.cs deleted file mode 100644 index 2948aca..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockQueue.cs +++ /dev/null @@ -1,35 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -namespace Fantasy.Async -{ - internal sealed class CoroutineLockQueuePool : PoolCore - { - public CoroutineLockQueuePool() : base(2000) { } - } - - internal sealed class CoroutineLockQueue : Queue, IPool - { - private bool _isPool; - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/WaitCoroutineLock.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/WaitCoroutineLock.cs deleted file mode 100644 index 28d04d4..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/CoroutineLock/WaitCoroutineLock.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System; -using Fantasy.Event; -using Fantasy.Pool; - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Async -{ - internal sealed class WaitCoroutineLockPool : PoolCore - { - private readonly Scene _scene; - private readonly CoroutineLockComponent _coroutineLockComponent; - - public WaitCoroutineLockPool(CoroutineLockComponent coroutineLockComponent) : base(2000) - { - _scene = coroutineLockComponent.Scene; - _coroutineLockComponent = coroutineLockComponent; - } - - public WaitCoroutineLock Rent(CoroutineLock coroutineLock, ref long coroutineLockQueueKey, string tag = null, int timeOut = 30000) - { - var timerId = 0L; - var lockId = _coroutineLockComponent.LockId; - var waitCoroutineLock = _coroutineLockComponent.WaitCoroutineLockPool.Rent(); - - if (timeOut > 0) - { - timerId = _scene.TimerComponent.Net.OnceTimer(timeOut, new CoroutineLockTimeout(ref lockId, waitCoroutineLock)); - } - - waitCoroutineLock.Initialize(coroutineLock, this, ref coroutineLockQueueKey, ref timerId, ref lockId, tag); - return waitCoroutineLock; - } - } - - internal struct CoroutineLockTimeout - { - public readonly long LockId; - public readonly WaitCoroutineLock WaitCoroutineLock; - - public CoroutineLockTimeout(ref long lockId, WaitCoroutineLock waitCoroutineLock) - { - LockId = lockId; - WaitCoroutineLock = waitCoroutineLock; - } - } - - internal sealed class OnCoroutineLockTimeout : EventSystem - { - protected override void Handler(CoroutineLockTimeout self) - { - var selfWaitCoroutineLock = self.WaitCoroutineLock; - - if (self.LockId != selfWaitCoroutineLock.LockId) - { - return; - } - - Log.Error($"coroutine lock timeout CoroutineLockQueueType:{selfWaitCoroutineLock.CoroutineLock.CoroutineLockType} Key:{selfWaitCoroutineLock.CoroutineLockQueueKey} Tag:{selfWaitCoroutineLock.Tag}"); - } - } - - /// - /// 一个协程锁的实例,用户可以用过这个手动释放锁 - /// - public sealed class WaitCoroutineLock : IPool, IDisposable - { - private bool _isPool; - internal string Tag { get; private set; } - internal long LockId { get; private set; } - internal long TimerId { get; private set; } - internal long CoroutineLockQueueKey { get; private set; } - internal CoroutineLock CoroutineLock { get; private set; } - - private bool _isSetResult; - private FTask _tcs; - private WaitCoroutineLockPool _waitCoroutineLockPool; - internal void Initialize(CoroutineLock coroutineLock, WaitCoroutineLockPool waitCoroutineLockPool, ref long coroutineLockQueueKey, ref long timerId, ref long lockId, string tag) - { - Tag = tag; - LockId = lockId; - TimerId = timerId; - CoroutineLock = coroutineLock; - CoroutineLockQueueKey = coroutineLockQueueKey; - _waitCoroutineLockPool = waitCoroutineLockPool; - } - /// - /// 释放协程锁 - /// - public void Dispose() - { - if (LockId == 0) - { - Log.Error("WaitCoroutineLock is already disposed"); - return; - } - - CoroutineLock.Release(CoroutineLockQueueKey); - - _tcs = null; - Tag = null; - LockId = 0; - TimerId = 0; - _isSetResult = false; - CoroutineLockQueueKey = 0; - _waitCoroutineLockPool.Return(this); - CoroutineLock = null; - _waitCoroutineLockPool = null; - } - - internal FTask Tcs - { - get { return _tcs ??= FTask.Create(); } - } - - internal void SetResult() - { - if (_isSetResult) - { - Log.Error("WaitCoroutineLock is already SetResult"); - return; - } - - _isSetResult = true; - Tcs.SetResult(this); - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EntityComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EntityComponent.cs deleted file mode 100644 index 67dc9ef..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EntityComponent.cs +++ /dev/null @@ -1,523 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8765 // Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes). - -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Entitas -{ - internal sealed class UpdateQueueInfo - { - public bool IsStop; - public readonly Type Type; - public readonly long RunTimeId; - - public UpdateQueueInfo(Type type, long runTimeId) - { - Type = type; - IsStop = false; - RunTimeId = runTimeId; - } - } - - internal sealed class FrameUpdateQueueInfo - { - public readonly Type Type; - public readonly long RunTimeId; - - public FrameUpdateQueueInfo(Type type, long runTimeId) - { - Type = type; - RunTimeId = runTimeId; - } - } - - internal struct CustomEntitiesSystemKey : IEquatable - { - public int CustomEventType { get; } - public Type EntitiesType { get; } - public CustomEntitiesSystemKey(int customEventType, Type entitiesType) - { - CustomEventType = customEventType; - EntitiesType = entitiesType; - } - public bool Equals(CustomEntitiesSystemKey other) - { - return CustomEventType == other.CustomEventType && EntitiesType == other.EntitiesType; - } - - public override bool Equals(object obj) - { - return obj is CustomEntitiesSystemKey other && Equals(other); - } - - public override int GetHashCode() - { - return HashCode.Combine(CustomEventType, EntitiesType); - } - } - - /// - /// Entity管理组件 - /// -#if FANTASY_UNITY - public sealed class EntityComponent : Entity, ISceneUpdate, ISceneLateUpdate, IAssembly -#else - public sealed class EntityComponent : Entity, ISceneUpdate, IAssembly -#endif - { - private readonly OneToManyList _assemblyList = new(); - private readonly OneToManyList _assemblyHashCodes = new(); - - private readonly Dictionary _awakeSystems = new(); - private readonly Dictionary _updateSystems = new(); - private readonly Dictionary _destroySystems = new(); - private readonly Dictionary _deserializeSystems = new(); - - private readonly OneToManyList _assemblyCustomSystemList = new(); - private readonly Dictionary _customEntitiesSystems = new Dictionary(); - - private readonly Dictionary _hashCodes = new Dictionary(); - private readonly Queue _updateQueue = new Queue(); - - private readonly Dictionary _updateQueueDic = new Dictionary(); -#if FANTASY_UNITY - private readonly Dictionary _lateUpdateSystems = new(); - private readonly Queue _lateUpdateQueue = new Queue(); - private readonly Dictionary _lateUpdateQueueDic = new Dictionary(); -#endif - - internal async FTask Initialize() - { - await AssemblySystem.Register(this); - return this; - } - - #region Assembly - - public FTask Load(long assemblyIdentity) - { - var task = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - LoadInner(assemblyIdentity); - task.SetResult(); - }); - return task; - } - - public FTask ReLoad(long assemblyIdentity) - { - var task = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - LoadInner(assemblyIdentity); - task.SetResult(); - }); - - return task; - } - - public FTask OnUnLoad(long assemblyIdentity) - { - var task = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - task.SetResult(); - }); - return task; - } - - private void LoadInner(long assemblyIdentity) - { - foreach (var entityType in AssemblySystem.ForEach(assemblyIdentity, typeof(IEntity))) - { - _hashCodes.Add(entityType, HashCodeHelper.ComputeHash64(entityType.FullName)); - _assemblyHashCodes.Add(assemblyIdentity, entityType); - } - - foreach (var entitiesSystemType in AssemblySystem.ForEach(assemblyIdentity, typeof(IEntitiesSystem))) - { - Type entitiesType = null; - var entity = Activator.CreateInstance(entitiesSystemType); - - switch (entity) - { - case IAwakeSystem iAwakeSystem: - { - entitiesType = iAwakeSystem.EntitiesType(); - _awakeSystems.Add(entitiesType, iAwakeSystem); - break; - } - case IDestroySystem iDestroySystem: - { - entitiesType = iDestroySystem.EntitiesType(); - _destroySystems.Add(entitiesType, iDestroySystem); - break; - } - case IDeserializeSystem iDeserializeSystem: - { - entitiesType = iDeserializeSystem.EntitiesType(); - _deserializeSystems.Add(entitiesType, iDeserializeSystem); - break; - } - case IUpdateSystem iUpdateSystem: - { - entitiesType = iUpdateSystem.EntitiesType(); - _updateSystems.Add(entitiesType, iUpdateSystem); - break; - } -#if FANTASY_UNITY - case ILateUpdateSystem iLateUpdateSystem: - { - entitiesType = iLateUpdateSystem.EntitiesType(); - _lateUpdateSystems.Add(entitiesType, iLateUpdateSystem); - break; - } -#endif - default: - { - Log.Error($"IEntitiesSystem not support type {entitiesSystemType}"); - return; - } - } - - _assemblyList.Add(assemblyIdentity, entitiesType); - } - - foreach (var customEntitiesSystemType in AssemblySystem.ForEach(assemblyIdentity, typeof(ICustomEntitiesSystem))) - { - var entity = (ICustomEntitiesSystem)Activator.CreateInstance(customEntitiesSystemType); - var customEntitiesSystemKey = new CustomEntitiesSystemKey(entity.CustomEventType, entity.EntitiesType()); - _customEntitiesSystems.Add(customEntitiesSystemKey, entity); - _assemblyCustomSystemList.Add(assemblyIdentity, customEntitiesSystemKey); - } - } - - private void OnUnLoadInner(long assemblyIdentity) - { - if (_assemblyHashCodes.TryGetValue(assemblyIdentity, out var entityType)) - { - foreach (var type in entityType) - { - _hashCodes.Remove(type); - } - - _assemblyHashCodes.RemoveByKey(assemblyIdentity); - } - - if (_assemblyList.TryGetValue(assemblyIdentity, out var assembly)) - { - foreach (var type in assembly) - { - _awakeSystems.Remove(type); - _updateSystems.Remove(type); - _destroySystems.Remove(type); -#if FANTASY_UNITY - _lateUpdateSystems.Remove(type); -#endif - _deserializeSystems.Remove(type); - } - - _assemblyList.RemoveByKey(assemblyIdentity); - } - - if (_assemblyCustomSystemList.TryGetValue(assemblyIdentity, out var customSystemAssembly)) - { - foreach (var customEntitiesSystemKey in customSystemAssembly) - { - _customEntitiesSystems.Remove(customEntitiesSystemKey); - } - - _assemblyCustomSystemList.RemoveByKey(assemblyIdentity); - } - } - - #endregion - - #region Event - - /// - /// 触发实体的唤醒方法 - /// - /// 实体对象 - public void Awake(Entity entity) - { - if (!_awakeSystems.TryGetValue(entity.Type, out var awakeSystem)) - { - return; - } - - try - { - awakeSystem.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{entity.Type.FullName} Error {e}"); - } - } - - /// - /// 触发实体的销毁方法 - /// - /// 实体对象 - public void Destroy(Entity entity) - { - if (!_destroySystems.TryGetValue(entity.Type, out var system)) - { - return; - } - - try - { - system.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{entity.Type.FullName} Destroy Error {e}"); - } - } - - /// - /// 触发实体的反序列化方法 - /// - /// 实体对象 - public void Deserialize(Entity entity) - { - if (!_deserializeSystems.TryGetValue(entity.Type, out var system)) - { - return; - } - - try - { - system.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{entity.Type.FullName} Deserialize Error {e}"); - } - } - - #endregion - - #region CustomEvent - - public void CustomSystem(Entity entity, int customEventType) - { - var customEntitiesSystemKey = new CustomEntitiesSystemKey(customEventType, entity.Type); - - if (!_customEntitiesSystems.TryGetValue(customEntitiesSystemKey, out var system)) - { - return; - } - - try - { - system.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{entity.Type.FullName} CustomSystem Error {e}"); - } - } - - #endregion - - #region Update - - /// - /// 将实体加入Update队列,准备进行Update - /// - /// 实体对象 - public void StartUpdate(Entity entity) - { - var type = entity.Type; - var entityRuntimeId = entity.RuntimeId; - - if (!_updateSystems.ContainsKey(type)) - { - return; - } - - var updateQueueInfo = new UpdateQueueInfo(type, entityRuntimeId); - _updateQueue.Enqueue(updateQueueInfo); - _updateQueueDic.Add(entityRuntimeId, updateQueueInfo); - } - - /// - /// 停止实体Update - /// - /// 实体对象 - public void StopUpdate(Entity entity) - { - if (!_updateQueueDic.Remove(entity.RuntimeId, out var updateQueueInfo)) - { - return; - } - - updateQueueInfo.IsStop = true; - } - - /// - /// 执行实体系统的Update - /// - public void Update() - { - var updateQueueCount = _updateQueue.Count; - - while (updateQueueCount-- > 0) - { - var updateQueueStruct = _updateQueue.Dequeue(); - - if (updateQueueStruct.IsStop) - { - continue; - } - - if (!_updateSystems.TryGetValue(updateQueueStruct.Type, out var updateSystem)) - { - continue; - } - - var entity = Scene.GetEntity(updateQueueStruct.RunTimeId); - - if (entity == null || entity.IsDisposed) - { - _updateQueueDic.Remove(updateQueueStruct.RunTimeId); - continue; - } - - _updateQueue.Enqueue(updateQueueStruct); - - try - { - updateSystem.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{updateQueueStruct.Type.FullName} Update Error {e}"); - } - } - } - - #endregion - -#if FANTASY_UNITY - #region LateUpdate - - /// - /// 将实体加入LateUpdate队列,准备进行LateUpdate - /// - /// 实体对象 - public void StartLateUpdate(Entity entity) - { - var type = entity.Type; - var entityRuntimeId = entity.RuntimeId; - - if (!_lateUpdateSystems.ContainsKey(type)) - { - return; - } - - var updateQueueInfo = new UpdateQueueInfo(type, entityRuntimeId); - _lateUpdateQueue.Enqueue(updateQueueInfo); - _lateUpdateQueueDic.Add(entityRuntimeId, updateQueueInfo); - } - - /// - /// 停止实体进行LateUpdate - /// - /// 实体对象 - public void StopLateUpdate(Entity entity) - { - if (!_lateUpdateQueueDic.Remove(entity.RuntimeId, out var updateQueueInfo)) - { - return; - } - - updateQueueInfo.IsStop = true; - } - - public void LateUpdate() - { - var lateUpdateQueue = _lateUpdateQueue.Count; - - while (lateUpdateQueue-- > 0) - { - var lateUpdateQueueStruct = _lateUpdateQueue.Dequeue(); - - if (lateUpdateQueueStruct.IsStop) - { - continue; - } - - if (!_lateUpdateSystems.TryGetValue(lateUpdateQueueStruct.Type, out var lateUpdateSystem)) - { - continue; - } - - var entity = Scene.GetEntity(lateUpdateQueueStruct.RunTimeId); - - if (entity == null || entity.IsDisposed) - { - _lateUpdateQueueDic.Remove(lateUpdateQueueStruct.RunTimeId); - continue; - } - - _lateUpdateQueue.Enqueue(lateUpdateQueueStruct); - - try - { - lateUpdateSystem.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{lateUpdateQueueStruct.Type.FullName} Update Error {e}"); - } - } - } - #endregion -#endif - public long GetHashCode(Type type) - { - return _hashCodes[type]; - } - - /// - /// 释放实体系统管理器资源 - /// - public override void Dispose() - { - _updateQueue.Clear(); - _updateQueueDic.Clear(); -#if FANTASY_UNITY - _lateUpdateQueue.Clear(); - _lateUpdateQueueDic.Clear(); - _lateUpdateSystems.Clear(); -#endif - _assemblyList.Clear(); - _awakeSystems.Clear(); - _updateSystems.Clear(); - _destroySystems.Clear(); - _deserializeSystems.Clear(); - - AssemblySystem.UnRegister(this); - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EventComponent/EventComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EventComponent/EventComponent.cs deleted file mode 100644 index 30ca61e..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EventComponent/EventComponent.cs +++ /dev/null @@ -1,252 +0,0 @@ -using System; -using System.Reflection; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; - -// ReSharper disable PossibleMultipleEnumeration -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -// ReSharper disable MethodOverloadWithOptionalParameter - -namespace Fantasy.Event -{ - internal sealed class EventCache - { - public readonly Type EnventType; - public readonly object Obj; - public EventCache(Type enventType, object obj) - { - EnventType = enventType; - Obj = obj; - } - } - - public sealed class EventComponent : Entity, IAssembly - { - private readonly OneToManyList _events = new(); - private readonly OneToManyList _asyncEvents = new(); - private readonly OneToManyList _assemblyEvents = new(); - private readonly OneToManyList _assemblyAsyncEvents = new(); - - internal async FTask Initialize() - { - await AssemblySystem.Register(this); - return this; - } - - #region Assembly - - public async FTask Load(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask ReLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask OnUnLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - private void LoadInner(long assemblyIdentity) - { - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IEvent))) - { - var @event = (IEvent)Activator.CreateInstance(type); - - if (@event == null) - { - continue; - } - - var eventType = @event.EventType(); - _events.Add(eventType, @event); - _assemblyEvents.Add(assemblyIdentity, new EventCache(eventType, @event)); - } - - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IAsyncEvent))) - { - var @event = (IAsyncEvent)Activator.CreateInstance(type); - - if (@event == null) - { - continue; - } - - var eventType = @event.EventType(); - _asyncEvents.Add(eventType, @event); - _assemblyAsyncEvents.Add(assemblyIdentity, new EventCache(eventType, @event)); - } - } - - private void OnUnLoadInner(long assemblyIdentity) - { - if (_assemblyEvents.TryGetValue(assemblyIdentity, out var events)) - { - foreach (var @event in events) - { - _events.RemoveValue(@event.EnventType, (IEvent)@event.Obj); - } - - _assemblyEvents.RemoveByKey(assemblyIdentity); - } - - if (_assemblyAsyncEvents.TryGetValue(assemblyIdentity, out var asyncEvents)) - { - foreach (var @event in asyncEvents) - { - _asyncEvents.RemoveValue(@event.EnventType, (IAsyncEvent)@event.Obj); - } - - _assemblyAsyncEvents.RemoveByKey(assemblyIdentity); - } - } - - #endregion - - #region Publish - - /// - /// 发布一个值类型的事件数据。 - /// - /// 事件数据类型(值类型)。 - /// 事件数据实例。 - public void Publish(TEventData eventData) where TEventData : struct - { - if (!_events.TryGetValue(typeof(TEventData), out var list)) - { - return; - } - - foreach (var @event in list) - { - try - { - @event.Invoke(eventData); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - /// - /// 发布一个继承自 Entity 的事件数据。 - /// - /// 事件数据类型(继承自 Entity)。 - /// 事件数据实例。 - /// 是否释放事件数据。 - public void Publish(TEventData eventData, bool isDisposed = true) where TEventData : Entity - { - if (!_events.TryGetValue(typeof(TEventData), out var list)) - { - return; - } - - foreach (var @event in list) - { - try - { - @event.Invoke(eventData); - } - catch (Exception e) - { - Log.Error(e); - } - } - - if (isDisposed) - { - eventData.Dispose(); - } - } - - /// - /// 异步发布一个值类型的事件数据。 - /// - /// 事件数据类型(值类型)。 - /// 事件数据实例。 - /// 表示异步操作的任务。 - public async FTask PublishAsync(TEventData eventData) where TEventData : struct - { - if (!_asyncEvents.TryGetValue(typeof(TEventData), out var list)) - { - return; - } - - using var tasks = ListPool.Create(); - - foreach (var @event in list) - { - tasks.Add(@event.InvokeAsync(eventData)); - } - - await FTask.WaitAll(tasks); - } - - /// - /// 异步发布一个继承自 Entity 的事件数据。 - /// - /// 事件数据类型(继承自 Entity)。 - /// 事件数据实例。 - /// 是否释放事件数据。 - /// 表示异步操作的任务。 - public async FTask PublishAsync(TEventData eventData, bool isDisposed = true) where TEventData : Entity - { - if (!_asyncEvents.TryGetValue(eventData.GetType(), out var list)) - { - return; - } - - using var tasks = ListPool.Create(); - - foreach (var @event in list) - { - tasks.Add(@event.InvokeAsync(eventData)); - } - - await FTask.WaitAll(tasks); - - if (isDisposed) - { - eventData.Dispose(); - } - } - - #endregion - - public override void Dispose() - { - _events.Clear(); - _asyncEvents.Clear(); - _assemblyEvents.Clear(); - _assemblyAsyncEvents.Clear(); - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EventComponent/Interface/IEvent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EventComponent/Interface/IEvent.cs deleted file mode 100644 index 5314995..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EventComponent/Interface/IEvent.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Event -{ - /// - /// 事件的接口 - /// - public interface IEvent - { - /// - /// 用于指定事件的Type - /// - /// - Type EventType(); - /// - /// 时间内部使用的入口 - /// - /// - void Invoke(object self); - } - - /// - /// 异步事件的接口 - /// - public interface IAsyncEvent - { - /// - /// - /// - /// - Type EventType(); - /// - /// - /// - /// - FTask InvokeAsync(object self); - } - - /// - /// 事件的抽象类,要使用事件必须要继承这个抽象接口。 - /// - /// 要监听的事件泛型类型 - public abstract class EventSystem : IEvent - { - private readonly Type _selfType = typeof(T); - /// - /// - /// - /// - public Type EventType() - { - return _selfType; - } - /// - /// 事件调用的方法,要在这个方法里编写事件发生的逻辑 - /// - /// - protected abstract void Handler(T self); - /// - /// - /// - /// - public void Invoke(object self) - { - try - { - Handler((T) self); - } - catch (Exception e) - { - Log.Error($"{_selfType.Name} Error {e}"); - } - } - } - /// - /// 异步事件的抽象类,要使用事件必须要继承这个抽象接口。 - /// - /// 要监听的事件泛型类型 - public abstract class AsyncEventSystem : IAsyncEvent - { - private readonly Type _selfType = typeof(T); - /// - /// - /// - /// - public Type EventType() - { - return _selfType; - } - /// - /// 事件调用的方法,要在这个方法里编写事件发生的逻辑 - /// - /// - protected abstract FTask Handler(T self); - /// - /// - /// - /// - public async FTask InvokeAsync(object self) - { - try - { - await Handler((T) self); - } - catch (Exception e) - { - Log.Error($"{_selfType.Name} Error {e}"); - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/MessagePoolComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/MessagePoolComponent.cs deleted file mode 100644 index f1ddb23..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/MessagePoolComponent.cs +++ /dev/null @@ -1,139 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; -using Fantasy.Pool; -using Fantasy.Serialize; - -namespace Fantasy.Entitas -{ - /// - /// 消息的对象池组件 - /// - public sealed class MessagePoolComponent : Entity - { - private int _poolCount; - private const int MaxCapacity = ushort.MaxValue; - private readonly OneToManyQueue _poolQueue = new OneToManyQueue(); - private readonly Dictionary> _typeCheckCache = new Dictionary>(); - /// - /// 销毁组件 - /// - public override void Dispose() - { - _poolCount = 0; - _poolQueue.Clear(); - _typeCheckCache.Clear(); - base.Dispose(); - } - /// - /// 从对象池里获取一个消息,如果没有就创建一个新的 - /// - /// 消息的泛型类型 - /// - public T Rent() where T : AMessage, new() - { - if (!_poolQueue.TryDequeue(typeof(T), out var queue)) - { - var instance = new T(); - instance.SetScene(Scene); - instance.SetIsPool(true); - return instance; - } - - queue.SetIsPool(true); - _poolCount--; - return (T)queue; - } - - /// - /// - /// - /// 消息的类型 - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public AMessage Rent(Type type) - { - if (!_poolQueue.TryDequeue(type, out var queue)) - { - if (!_typeCheckCache.TryGetValue(type, out var createInstance)) - { - if (!typeof(AMessage).IsAssignableFrom(type)) - { - throw new NotSupportedException($"{this.GetType().FullName} Type:{type.FullName} must inherit from IPool"); - } - else - { - createInstance = CreateInstance.CreateMessage(type); - _typeCheckCache[type] = createInstance; - } - } - - var instance = createInstance(); - instance.SetScene(Scene); - instance.SetIsPool(true); - return instance; - } - - queue.SetIsPool(true); - _poolCount--; - return queue; - } - /// - /// 返还一个消息到对象池中 - /// - /// - public void Return(AMessage obj) - { - if (obj == null) - { - return; - } - - if (!obj.IsPool()) - { - return; - } - - if (_poolCount >= MaxCapacity) - { - return; - } - - _poolCount++; - obj.SetIsPool(false); - _poolQueue.Enqueue(obj.GetType(), obj); - } - - /// - /// - /// - /// 返还的消息 - /// 返还的消息泛型类型 - public void Return(T obj) where T : AMessage - { - if (obj == null) - { - return; - } - - if (!obj.IsPool()) - { - return; - } - - if (_poolCount >= MaxCapacity) - { - return; - } - - _poolCount++; - obj.SetIsPool(false); - _poolQueue.Enqueue(typeof(T), obj); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/SingleCollectionComponent/SingleCollectionComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/SingleCollectionComponent/SingleCollectionComponent.cs deleted file mode 100644 index 5c0969d..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/SingleCollectionComponent/SingleCollectionComponent.cs +++ /dev/null @@ -1,167 +0,0 @@ -// ReSharper disable SuspiciousTypeConversion.Global - -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#if FANTASY_NET -namespace Fantasy.SingleCollection -{ - /// - /// 用于处理Entity下的实体进行数据库分表存储的组件 - /// - public sealed class SingleCollectionComponent : Entity, IAssembly - { - private CoroutineLock _coroutineLock; - private readonly OneToManyHashSet _collection = new OneToManyHashSet(); - - private readonly OneToManyList _assemblyCollections = - new OneToManyList(); - - private sealed class SingleCollectionInfo(Type rootType, string collectionName) - { - public readonly Type RootType = rootType; - public readonly string CollectionName = collectionName; - } - - internal async FTask Initialize() - { - var coroutineLockType = HashCodeHelper.ComputeHash64(GetType().FullName); - _coroutineLock = Scene.CoroutineLockComponent.Create(coroutineLockType); - await AssemblySystem.Register(this); - return this; - } - - #region Assembly - - public async FTask Load(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask ReLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask OnUnLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - private void LoadInner(long assemblyIdentity) - { - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(ISupportedSingleCollection))) - { - var customAttributes = type.GetCustomAttributes(typeof(SingleCollectionAttribute), false); - if (customAttributes.Length == 0) - { - Log.Error( - $"type {type.FullName} Implemented the interface of ISingleCollection, requiring the implementation of SingleCollectionAttribute"); - continue; - } - - var singleCollectionAttribute = (SingleCollectionAttribute)customAttributes[0]; - var rootType = singleCollectionAttribute.RootType; - var collectionName = singleCollectionAttribute.CollectionName; - _collection.Add(rootType, collectionName); - _assemblyCollections.Add(assemblyIdentity, new SingleCollectionInfo(rootType, collectionName)); - } - } - - private void OnUnLoadInner(long assemblyIdentity) - { - if (!_assemblyCollections.TryGetValue(assemblyIdentity, out var types)) - { - return; - } - - foreach (var singleCollectionInfo in types) - { - _collection.RemoveValue(singleCollectionInfo.RootType, singleCollectionInfo.CollectionName); - } - - _assemblyCollections.RemoveByKey(assemblyIdentity); - } - - #endregion - - #region Collections - - /// - /// 通过数据库获取某一个实体类型下所有的分表数据到当前实体下,并且会自动建立父子关系。 - /// - /// 实体实例 - /// 实体泛型类型 - public async FTask GetCollections(T entity) where T : Entity, ISingleCollectionRoot - { - if (!_collection.TryGetValue(typeof(T), out var collections)) - { - return; - } - - var worldDateBase = Scene.World.DataBase; - - using (await _coroutineLock.Wait(entity.Id)) - { - foreach (var collectionName in collections) - { - var singleCollection = await worldDateBase.QueryNotLock(entity.Id, true, collectionName); - entity.AddComponent(singleCollection); - } - } - } - - /// - /// 存储当前实体下支持分表的组件到数据中,包括存储实体本身。 - /// - /// 实体实例 - /// 实体泛型类型 - public async FTask SaveCollections(T entity) where T : Entity, ISingleCollectionRoot - { - using var collections = ListPool.Create(); - - foreach (var treeEntity in entity.ForEachSingleCollection) - { - if (treeEntity is not ISupportedSingleCollection) - { - continue; - } - - collections.Add(treeEntity); - } - - collections.Add(entity); - await entity.Scene.World.DataBase.Save(entity.Id, collections); - } - - #endregion - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/Interface/TimerHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/Interface/TimerHandler.cs deleted file mode 100644 index 9e1f4c9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/Interface/TimerHandler.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Fantasy.Event; - -namespace Fantasy.Timer -{ - /// - /// 计时器抽象类,提供了一个基础框架,用于创建处理计时器事件的具体类。 - /// - /// 事件的类型参数 - public abstract class TimerHandler : EventSystem { } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/ScheduledTask.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/ScheduledTask.cs deleted file mode 100644 index d644386..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/ScheduledTask.cs +++ /dev/null @@ -1,49 +0,0 @@ -// #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// namespace Fantasy -// { -// public sealed class ScheduledTaskPool : PoolCore -// { -// public ScheduledTaskPool() : base(2000) { } -// -// public ScheduledTask Rent(Action action, ref int rounds, ref int finalSlot) -// { -// var scheduledTask = Rent(); -// scheduledTask.Rounds = rounds; -// scheduledTask.Action = action; -// scheduledTask.FinalSlot = finalSlot; -// return scheduledTask; -// } -// -// public override void Return(ScheduledTask item) -// { -// base.Return(item); -// item.Dispose(); -// } -// } -// -// public sealed class ScheduledTask : IPool, IDisposable -// { -// public int Rounds; -// public int FinalSlot; -// public Action Action; -// public LinkedListNode Node; -// -// public bool IsPool { get; set; } -// public ScheduledTask() { } -// public ScheduledTask(Action action, ref int rounds, ref int finalSlot) -// { -// Action = action; -// Rounds = rounds; -// FinalSlot = finalSlot; -// } -// -// public void Dispose() -// { -// Rounds = 0; -// FinalSlot = 0; -// Action = null; -// Node = null; -// } -// } -// } \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/TimeWheel.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/TimeWheel.cs deleted file mode 100644 index 58916b1..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/TimeWheel.cs +++ /dev/null @@ -1,134 +0,0 @@ -// using System.Runtime.CompilerServices; -// // ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// -// namespace Fantasy -// { -// public sealed class TimeWheel -// { -// private int _currentIndex; -// private ScheduledTaskPool _scheduledTaskPool; -// -// private readonly Scene _scene; -// private readonly int _wheelSize; -// private readonly int _tickDuration; -// private readonly TimeWheel _upperLevelWheel; -// private readonly LinkedList[] _wheel; -// private readonly Queue _tasksToReschedule = new Queue(); -// private readonly Dictionary _taskDictionary = new Dictionary(); -// -// public TimeWheel(TimerComponent timerComponent, int wheelSize, int tickDuration, TimeWheel upperLevelWheel = null) -// { -// _scene = timerComponent.Scene; -// _wheelSize = wheelSize; -// _tickDuration = tickDuration; -// _upperLevelWheel = upperLevelWheel; -// _scheduledTaskPool = timerComponent.ScheduledTaskPool; -// _wheel = new LinkedList[_wheelSize]; -// for (var i = 0; i < wheelSize; i++) -// { -// _wheel[i] = new LinkedList(); -// } -// } -// -// public long Schedule(Action action, int delay) -// { -// var ticks = delay / _tickDuration; -// var futureIndex = ticks + _currentIndex; -// var rounds = futureIndex / _wheelSize; -// var slot = futureIndex % _wheelSize; -// -// if (slot == 0) -// { -// slot = _wheelSize - 1; -// rounds--; -// } -// else -// { -// slot--; -// } -// -// var taskId = _scene.RuntimeIdFactory.Create; -// var task = _scheduledTaskPool.Rent(action, ref rounds, ref slot); -// task.Node = _wheel[slot].AddLast(task); -// _taskDictionary.Add(taskId, task); -// Console.WriteLine($"Schedule rounds:{rounds} slot:{slot} _currentIndex:{_currentIndex}"); -// return taskId; -// } -// -// public bool Remove(int taskId) -// { -// if (!_taskDictionary.TryGetValue(taskId, out var task)) -// { -// return false; -// } -// -// _taskDictionary.Remove(taskId); -// _wheel[task.FinalSlot].Remove(task.Node); -// _scheduledTaskPool.Return(task); -// Console.WriteLine("找到已经删除了任务"); -// return true; -// } -// -// public void Tick(object? state) -// { -// var currentWheel = _wheel[_currentIndex]; -// -// if (currentWheel.Count == 0) -// { -// AdvanceIndex(); -// return; -// } -// -// var currentNode = currentWheel.First; -// -// while (currentNode != null) -// { -// var nextNode = currentNode.Next; -// var task = currentNode.Value; -// -// if (task.Rounds <= 0 && task.FinalSlot == _currentIndex) -// { -// try -// { -// task.Action.Invoke(); -// } -// catch (Exception ex) -// { -// Log.Error($"Exception during task execution: {ex.Message}"); -// } -// } -// else -// { -// task.Rounds--; -// _tasksToReschedule.Enqueue(task); -// } -// -// currentWheel.Remove(currentNode); -// currentNode = nextNode; -// } -// -// RescheduleTasks(); -// AdvanceIndex(); -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private void AdvanceIndex() -// { -// _currentIndex = (_currentIndex + 1) % _wheelSize; -// if (_currentIndex == 0 && _upperLevelWheel != null) -// { -// _upperLevelWheel.Tick(null); -// } -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private void RescheduleTasks() -// { -// while (_tasksToReschedule.TryDequeue(out var task)) -// { -// _wheel[task.FinalSlot].AddLast(task); -// } -// } -// } -// } \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerAction.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerAction.cs deleted file mode 100644 index 2a836ab..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerAction.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8625 -#pragma warning disable CS8618 - -namespace Fantasy.Timer -{ - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct TimerAction - { - public long TimerId; - public long StartTime; - public long TriggerTime; - public readonly object Callback; - public readonly TimerType TimerType; - public TimerAction(long timerId, TimerType timerType, long startTime, long triggerTime, object callback) - { - TimerId = timerId; - Callback = callback; - TimerType = timerType; - StartTime = startTime; - TriggerTime = triggerTime; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerComponent.cs deleted file mode 100644 index ffa7864..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerComponent.cs +++ /dev/null @@ -1,52 +0,0 @@ -// ReSharper disable ForCanBeConvertedToForeach - -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#if FANTASY_UNITY -using UnityEngine; -#endif -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Timer -{ - public sealed class TimerComponentUpdateSystem : UpdateSystem - { - protected override void Update(TimerComponent self) - { - self.Update(); - } - } - - /// - /// 时间调度组件 - /// - public sealed class TimerComponent : Entity - { - /// - /// 使用系统时间创建的计时器核心。 - /// - public TimerSchedulerNet Net { get; private set; } -#if FANTASY_UNITY - /// - /// 使用 Unity 时间创建的计时器核心。 - /// - public TimerSchedulerNetUnity Unity { get; private set; } -#endif - internal TimerComponent Initialize() - { - Net = new TimerSchedulerNet(Scene); -#if FANTASY_UNITY - Unity = new TimerSchedulerNetUnity(Scene); -#endif - return this; - } - public void Update() - { - Net.Update(); -#if FANTASY_UNITY - Unity.Update(); -#endif - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNet.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNet.cs deleted file mode 100644 index 26581f8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNet.cs +++ /dev/null @@ -1,390 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Helper; -// ReSharper disable UnusedParameter.Global - -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Timer -{ - /// - /// 基于系统事件的任务调度系统 - /// - public sealed class TimerSchedulerNet - { - private readonly Scene _scene; - private long _idGenerator; - private long _minTime; // 最小时间 - private readonly Queue _timeOutTime = new Queue(); - private readonly Queue _timeOutTimerIds = new Queue(); - private readonly Dictionary _timerActions = new Dictionary(); - private readonly SortedOneToManyList _timeId = new(); // 时间与计时器ID的有序一对多列表 - private long GetId => ++_idGenerator; - /// - /// 构造函数 - /// - /// 当前的Scene - public TimerSchedulerNet(Scene scene) - { - _scene = scene; - } - - private long Now() - { - return TimeHelper.Now; - } - - /// - /// 驱动方法,只有调用这个方法任务系统才会正常运转。 - /// - public void Update() - { - if (_timeId.Count == 0) - { - return; - } - - var currentTime = Now(); - - if (currentTime < _minTime) - { - return; - } - - // 遍历时间ID列表,查找超时的计时器任务 - foreach (var (key, _) in _timeId) - { - if (key > currentTime) - { - _minTime = key; - break; - } - - _timeOutTime.Enqueue(key); - } - - // 处理超时的计时器任务 - while (_timeOutTime.TryDequeue(out var time)) - { - var timerIds = _timeId[time]; - for (var i = 0; i < timerIds.Count; ++i) - { - _timeOutTimerIds.Enqueue(timerIds[i]); - } - - _timeId.Remove(time); - // _timeId.RemoveKey(time); - } - - if (_timeId.Count == 0) - { - _minTime = long.MaxValue; - } - - // 执行超时的计时器任务的回调操作 - while (_timeOutTimerIds.TryDequeue(out var timerId)) - { - if (!_timerActions.Remove(timerId, out var timerAction)) - { - continue; - } - - // 根据计时器类型执行不同的操作 - switch (timerAction.TimerType) - { - case TimerType.OnceWaitTimer: - { - var tcs = (FTask)timerAction.Callback; - tcs.SetResult(true); - break; - } - case TimerType.OnceTimer: - { - if (timerAction.Callback is not Action action) - { - Log.Error($"timerAction {timerAction.ToJson()}"); - break; - } - - action(); - break; - } - case TimerType.RepeatedTimer: - { - if (timerAction.Callback is not Action action) - { - Log.Error($"timerAction {timerAction.ToJson()}"); - break; - } - - timerAction.StartTime = Now(); - AddTimer(ref timerAction); - action(); - break; - } - } - } - } - - private void AddTimer(ref TimerAction timer) - { - var tillTime = timer.StartTime + timer.TriggerTime; - _timeId.Add(tillTime, timer.TimerId); - _timerActions.Add(timer.TimerId, timer); - - if (tillTime < _minTime) - { - _minTime = tillTime; - } - } - - /// - /// 异步等待指定时间。 - /// - /// 等待的时间长度。 - /// 取消令牌。 - /// 等待是否成功。 - public async FTask WaitAsync(long time, FCancellationToken cancellationToken = null) - { - if (time <= 0) - { - return true; - } - - var now = Now(); - var timerId = GetId; - var tcs = FTask.Create(); - var timerAction = new TimerAction(timerId, TimerType.OnceWaitTimer, now, time, tcs); - - void CancelActionVoid() - { - if (Remove(timerId)) - { - tcs.SetResult(false); - } - } - - bool result; - - try - { - cancellationToken?.Add(CancelActionVoid); - AddTimer(ref timerAction); - result = await tcs; - } - finally - { - cancellationToken?.Remove(CancelActionVoid); - } - - return result; - } - - /// - /// 异步等待直到指定时间。 - /// - /// 等待的目标时间。 - /// 取消令牌。 - /// 等待是否成功。 - public async FTask WaitTillAsync(long tillTime, FCancellationToken cancellationToken = null) - { - var now = Now(); - - if (now >= tillTime) - { - return true; - } - - var timerId = GetId; - var tcs = FTask.Create(); - var timerAction = new TimerAction(timerId, TimerType.OnceWaitTimer, now, tillTime - now, tcs); - - void CancelActionVoid() - { - if (Remove(timerId)) - { - tcs.SetResult(false); - } - } - - bool result; - - try - { - cancellationToken?.Add(CancelActionVoid); - AddTimer(ref timerAction); - result = await tcs; - } - finally - { - cancellationToken?.Remove(CancelActionVoid); - } - - return result; - } - - /// - /// 异步等待一帧时间。 - /// - /// 等待是否成功。 - public async FTask WaitFrameAsync() - { -#if FANTASY_NET - await WaitAsync(100); -#else - await WaitAsync(1); -#endif - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间 - /// - /// 计时器执行的目标时间。 - /// 计时器回调方法。 - /// - public long OnceTimer(long time, Action action) - { - var now = Now(); - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.OnceTimer, now, time, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。 - /// - /// 计时器执行的目标时间。 - /// 计时器回调方法。 - /// 计时器的 ID。 - public long OnceTillTimer(long tillTime, Action action) - { - var now = Now(); - - if (tillTime < now) - { - Log.Error($"new once time too small tillTime:{tillTime} Now:{now}"); - } - - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.OnceTimer, now, tillTime - now, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 创建一个只执行一次的计时器,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器执行的延迟时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long OnceTimer(long time, T timerHandlerType) where T : struct - { - void OnceTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return OnceTimer(time, OnceTimerVoid); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器执行的目标时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long OnceTillTimer(long tillTime, T timerHandlerType) where T : struct - { - void OnceTillTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return OnceTillTimer(tillTime, OnceTillTimerVoid); - } - - /// - /// 创建一个帧任务 - /// - /// - /// - public long FrameTimer(Action action) - { -#if FANTASY_NET - return RepeatedTimerInner(100, action); -#else - return RepeatedTimerInner(0, action); -#endif - } - - /// - /// 创建一个重复执行的计时器。 - /// - /// 计时器重复间隔的时间。 - /// 计时器回调方法。 - /// 计时器的 ID。 - public long RepeatedTimer(long time, Action action) - { - if (time < 0) - { - Log.Error($"time too small: {time}"); - return 0; - } - - return RepeatedTimerInner(time, action); - } - - /// - /// 创建一个重复执行的计时器,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器重复间隔的时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long RepeatedTimer(long time, T timerHandlerType) where T : struct - { - void RepeatedTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return RepeatedTimer(time, RepeatedTimerVoid); - } - - private long RepeatedTimerInner(long time, Action action) - { - var now = Now(); - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.RepeatedTimer, now, time, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// - /// - public bool Remove(ref long timerId) - { - var id = timerId; - timerId = 0; - return Remove(id); - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// 计时器的 ID。 - public bool Remove(long timerId) - { - return timerId != 0 && _timerActions.Remove(timerId, out _); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNetUnity.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNetUnity.cs deleted file mode 100644 index f00bfe4..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNetUnity.cs +++ /dev/null @@ -1,372 +0,0 @@ -#if FANTASY_UNITY -using System; -using System.Collections.Generic; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Helper; -using UnityEngine; -namespace Fantasy.Timer -{ - public sealed class TimerSchedulerNetUnity - { - private readonly Scene _scene; - private long _idGenerator; - private long _minTime; // 最小时间 - private readonly Queue _timeOutTime = new Queue(); - private readonly Queue _timeOutTimerIds = new Queue(); - private readonly Dictionary _timerActions = new Dictionary(); - private readonly SortedOneToManyList _timeId = new(); // 时间与计时器ID的有序一对多列表 - private long GetId => ++_idGenerator; - public TimerSchedulerNetUnity(Scene scene) - { - _scene = scene; - } - - private long Now() - { - return (long)(Time.time * 1000); - } - - public void Update() - { - if (_timeId.Count == 0) - { - return; - } - - var currentTime = Now(); - - if (currentTime < _minTime) - { - return; - } - - // 遍历时间ID列表,查找超时的计时器任务 - foreach (var (key, _) in _timeId) - { - if (key > currentTime) - { - _minTime = key; - break; - } - - _timeOutTime.Enqueue(key); - } - - // 处理超时的计时器任务 - while (_timeOutTime.TryDequeue(out var time)) - { - var timerIds = _timeId[time]; - for (var i = 0; i < timerIds.Count; ++i) - { - _timeOutTimerIds.Enqueue(timerIds[i]); - } - - _timeId.Remove(time); - // _timeId.RemoveKey(time); - } - - if (_timeId.Count == 0) - { - _minTime = long.MaxValue; - } - - // 执行超时的计时器任务的回调操作 - while (_timeOutTimerIds.TryDequeue(out var timerId)) - { - if (!_timerActions.Remove(timerId, out var timerAction)) - { - continue; - } - - // 根据计时器类型执行不同的操作 - switch (timerAction.TimerType) - { - case TimerType.OnceWaitTimer: - { - var tcs = (FTask)timerAction.Callback; - tcs.SetResult(true); - break; - } - case TimerType.OnceTimer: - { - if (timerAction.Callback is not Action action) - { - Log.Error($"timerAction {timerAction.ToJson()}"); - break; - } - - action(); - break; - } - case TimerType.RepeatedTimer: - { - if (timerAction.Callback is not Action action) - { - Log.Error($"timerAction {timerAction.ToJson()}"); - break; - } - - timerAction.StartTime = Now(); - AddTimer(ref timerAction); - action(); - break; - } - } - } - } - - private void AddTimer(ref TimerAction timer) - { - var tillTime = timer.StartTime + timer.TriggerTime; - _timeId.Add(tillTime, timer.TimerId); - _timerActions.Add(timer.TimerId, timer); - - if (tillTime < _minTime) - { - _minTime = tillTime; - } - } - - /// - /// 异步等待指定时间。 - /// - /// 等待的时间长度。 - /// 可选的取消令牌。 - /// 等待是否成功。 - public async FTask WaitAsync(long time, FCancellationToken cancellationToken = null) - { - if (time <= 0) - { - return true; - } - - var now = Now(); - var timerId = GetId; - var tcs = FTask.Create(); - var timerAction = new TimerAction(timerId, TimerType.OnceWaitTimer, now, time, tcs); - - - void CancelActionVoid() - { - if (Remove(timerId)) - { - tcs.SetResult(false); - } - } - - bool result; - - try - { - cancellationToken?.Add(CancelActionVoid); - AddTimer(ref timerAction); - result =await tcs; - } - finally - { - cancellationToken?.Remove(CancelActionVoid); - } - - return result; - } - - /// - /// 异步等待直到指定时间。 - /// - /// 等待的目标时间。 - /// 可选的取消令牌。 - /// 等待是否成功。 - public async FTask WaitTillAsync(long tillTime, FCancellationToken cancellationToken = null) - { - var now = Now(); - - if (now >= tillTime) - { - return true; - } - - var timerId = GetId; - var tcs = FTask.Create(); - var timerAction = new TimerAction(timerId, TimerType.OnceWaitTimer, now, tillTime - now, tcs); - - void CancelActionVoid() - { - if (Remove(timerId)) - { - tcs.SetResult(false); - } - } - - bool result; - - try - { - cancellationToken?.Add(CancelActionVoid); - AddTimer(ref timerAction); - result = await tcs; - } - finally - { - cancellationToken?.Remove(CancelActionVoid); - } - - return result; - } - - /// - /// 异步等待一帧时间。 - /// - /// 等待是否成功。 - public async FTask WaitFrameAsync(FCancellationToken cancellationToken = null) - { - await WaitAsync(1, cancellationToken); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间 - /// - /// 计时器执行的目标时间。 - /// 计时器回调方法。 - /// - public long OnceTimer(long time, Action action) - { - var now = Now(); - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.OnceTimer, now, time, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。 - /// - /// 计时器执行的目标时间。 - /// 计时器回调方法。 - /// 计时器的 ID。 - public long OnceTillTimer(long tillTime, Action action) - { - var now = Now(); - - if (tillTime < now) - { - Log.Error($"new once time too small tillTime:{tillTime} Now:{now}"); - } - - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.OnceTimer, now, tillTime - now, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 创建一个只执行一次的计时器,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器执行的延迟时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long OnceTimer(long time, T timerHandlerType) where T : struct - { - void OnceTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return OnceTimer(time, OnceTimerVoid); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器执行的目标时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long OnceTillTimer(long tillTime, T timerHandlerType) where T : struct - { - void OnceTillTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return OnceTillTimer(tillTime, OnceTillTimerVoid); - } - - /// - /// 创建一个帧任务 - /// - /// - /// - public long FrameTimer(Action action) - { - return RepeatedTimerInner(1, action); - } - - /// - /// 创建一个重复执行的计时器。 - /// - /// 计时器重复间隔的时间。 - /// 计时器回调方法。 - /// 计时器的 ID。 - public long RepeatedTimer(long time, Action action) - { - if (time < 0) - { - Log.Error($"time too small: {time}"); - return 0; - } - - return RepeatedTimerInner(time, action); - } - - /// - /// 创建一个重复执行的计时器,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器重复间隔的时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long RepeatedTimer(long time, T timerHandlerType) where T : struct - { - void RepeatedTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return RepeatedTimer(time, RepeatedTimerVoid); - } - - private long RepeatedTimerInner(long time, Action action) - { - var now = Now(); - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.RepeatedTimer, now, time, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// - /// - public bool Remove(ref long timerId) - { - var id = timerId; - timerId = 0; - return Remove(id); - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// 计时器的 ID。 - public bool Remove(long timerId) - { - return timerId != 0 && _timerActions.Remove(timerId, out _); - } - } -} -#endif - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerType.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerType.cs deleted file mode 100644 index 6f16f80..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/TimerComponent/TimerType.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Fantasy.Timer -{ - /// - /// 枚举对象TimerType - /// - public enum TimerType - { - /// - /// None - /// - None, - /// - /// 一次等待定时器 - /// - OnceWaitTimer, - /// - /// 一次性定时器 - /// - OnceTimer, - /// - /// 重复定时器 - /// - RepeatedTimer - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Entity.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Entity.cs deleted file mode 100644 index 99faad7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Entity.cs +++ /dev/null @@ -1,1066 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using Fantasy.Entitas.Interface; -using Fantasy.Pool; -using MongoDB.Bson.Serialization.Attributes; -using Newtonsoft.Json; -using ProtoBuf; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable MergeIntoPattern -// ReSharper disable SuspiciousTypeConversion.Global -// ReSharper disable NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract -// ReSharper disable CheckNamespace -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Entitas -{ - /// - /// 用来表示一个Entity - /// - public interface IEntity : IDisposable, IPool { } - - /// - /// Entity的抽象类,任何Entity必须继承这个接口才可以使用 - /// - public abstract partial class Entity : IEntity - { - #region Members - - /// - /// 获取一个值,表示实体是否支持对象池。 - /// - [BsonIgnore] - [JsonIgnore] - [ProtoIgnore] - [IgnoreDataMember] - private bool _isPool; - /// - /// 实体的Id - /// - [BsonId] - [BsonElement] - [BsonIgnoreIfDefault] - [BsonDefaultValue(0L)] - public long Id { get; protected set; } - /// - /// 实体的RunTimeId,其他系统可以通过这个Id发送Route消息,这个Id也可以理解为RouteId - /// - [BsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public long RuntimeId { get; protected set; } - /// - /// 当前实体是否已经被销毁 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public bool IsDisposed => RuntimeId == 0; - /// - /// 当前实体所归属的Scene - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public Scene Scene { get; protected set; } - /// - /// 实体的父实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public Entity Parent { get; protected set; } - /// - /// 实体的真实Type - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public Type Type { get; protected set; } -#if FANTASY_NET - [BsonElement("t")] [BsonIgnoreIfNull] private EntityList _treeDb; - [BsonElement("m")] [BsonIgnoreIfNull] private EntityList _multiDb; -#endif - [BsonIgnore] [IgnoreDataMember] [ProtoIgnore] private EntitySortedDictionary _tree; - [BsonIgnore] [IgnoreDataMember] [ProtoIgnore] private EntitySortedDictionary _multi; - - /// - /// 获得父Entity - /// - /// 父实体的泛型类型 - /// - public T GetParent() where T : Entity, new() - { - return Parent as T; - } - - /// - /// 获取当前实体的RouteId。 - /// - public long RouteId => RuntimeId; - - #endregion - - #region Create - - /// - /// 创建一个实体 - /// - /// 所属的Scene - /// 实体的Type - /// 是否从对象池创建,如果选择的是,销毁的时候同样会进入对象池 - /// 是否执行实体事件 - /// - public static Entity Create(Scene scene, Type type, bool isPool, bool isRunEvent) - { - return Create(scene, type, scene.EntityIdFactory.Create, isPool, isRunEvent); - } - - /// - /// 创建一个实体 - /// - /// 所属的Scene - /// 实体的Type - /// 指定实体的Id - /// 是否从对象池创建,如果选择的是,销毁的时候同样会进入对象池 - /// 是否执行实体事件 - /// - public static Entity Create(Scene scene, Type type, long id, bool isPool, bool isRunEvent) - { - if (!typeof(Entity).IsAssignableFrom(type)) - { - throw new NotSupportedException($"{type.FullName} Type:{type.FullName} must inherit from Entity"); - } - - Entity entity = null; - - if (isPool) - { - entity = (Entity)scene.EntityPool.Rent(type); - } - else - { - if (!scene.TypeInstance.TryGetValue(type, out var createInstance)) - { - createInstance = CreateInstance.CreateIPool(type); - scene.TypeInstance[type] = createInstance; - } - - entity = (Entity)createInstance(); - } - - entity.Scene = scene; - entity.Type = type; - entity.SetIsPool(isPool); - entity.Id = id; - entity.RuntimeId = scene.RuntimeIdFactory.Create; - scene.AddEntity(entity); - - if (isRunEvent) - { - scene.EntityComponent.Awake(entity); - scene.EntityComponent.StartUpdate(entity); -#if FANTASY_UNITY - scene.EntityComponent.StartLateUpdate(entity); -#endif - } - - return entity; - } - - /// - /// 创建一个实体 - /// - /// 所属的Scene - /// 是否从对象池创建,如果选择的是,销毁的时候同样会进入对象池 - /// 是否执行实体事件 - /// 要创建的实体泛型类型 - /// - public static T Create(Scene scene, bool isPool, bool isRunEvent) where T : Entity, new() - { - return Create(scene, scene.EntityIdFactory.Create, isPool, isRunEvent); - } - - /// - /// 创建一个实体 - /// - /// 所属的Scene - /// 指定实体的Id - /// 是否从对象池创建,如果选择的是,销毁的时候同样会进入对象池 - /// 是否执行实体事件 - /// 要创建的实体泛型类型 - /// - public static T Create(Scene scene, long id, bool isPool, bool isRunEvent) where T : Entity, new() - { - var entity = isPool ? scene.EntityPool.Rent() : new T(); - entity.Scene = scene; - entity.Type = typeof(T); - entity.SetIsPool(isPool); - entity.Id = id; - entity.RuntimeId = scene.RuntimeIdFactory.Create; - scene.AddEntity(entity); - - if (isRunEvent) - { - scene.EntityComponent.Awake(entity); - scene.EntityComponent.StartUpdate(entity); -#if FANTASY_UNITY - scene.EntityComponent.StartLateUpdate(entity); -#endif - } - - return entity; - } - - #endregion - - #region AddComponent - - /// - /// 添加一个组件到当前实体上 - /// - /// 是否从对象池里创建 - /// 要添加组件的泛型类型 - /// 返回添加到实体上组件的实例 - public T AddComponent(bool isPool = true) where T : Entity, new() - { - var id = SupportedMultiEntityChecker.IsSupported ? Scene.EntityIdFactory.Create : Id; - var entity = Create(Scene, id, isPool, false); - AddComponent(entity); - Scene.EntityComponent.Awake(entity); - Scene.EntityComponent.StartUpdate(entity); -#if FANTASY_UNITY - Scene.EntityComponent.StartLateUpdate(entity); -#endif - return entity; - } - - /// - /// 添加一个组件到当前实体上 - /// - /// 要添加组件的Id - /// 是否从对象池里创建 - /// 要添加组件的泛型类型 - /// 返回添加到实体上组件的实例 - public T AddComponent(long id, bool isPool = true) where T : Entity, new() - { - var entity = Create(Scene, id, isPool, false); - AddComponent(entity); - Scene.EntityComponent.Awake(entity); - Scene.EntityComponent.StartUpdate(entity); -#if FANTASY_UNITY - Scene.EntityComponent.StartLateUpdate(entity); -#endif - return entity; - } - - /// - /// 添加一个组件到当前实体上 - /// - /// 要添加的实体实例 - public void AddComponent(Entity component) - { - if (this == component) - { - Log.Error("Cannot add oneself to one's own components"); - return; - } - - if (component.IsDisposed) - { - Log.Error($"component is Disposed {component.Type.FullName}"); - return; - } - - var type = component.Type; - component.Parent?.RemoveComponent(component, false); - - if (component is ISupportedMultiEntity) - { - _multi ??= Scene.EntitySortedDictionaryPool.Rent(); - _multi.Add(component.Id, component); -#if FANTASY_NET - if (component is ISupportedDataBase) - { - _multiDb ??= Scene.EntityListPool.Rent(); - _multiDb.Add(component); - } -#endif - } - else - { -#if FANTASY_NET - if (component is ISupportedSingleCollection && component.Id != Id) - { - Log.Error($"component type :{type.FullName} for implementing ISupportedSingleCollection, it is required that the Id must be the same as the parent"); - } -#endif - var typeHashCode = Scene.EntityComponent.GetHashCode(type);; - - if (_tree == null) - { - _tree = Scene.EntitySortedDictionaryPool.Rent(); - } - else if (_tree.ContainsKey(typeHashCode)) - { - Log.Error($"type:{type.FullName} If you want to add multiple components of the same type, please implement IMultiEntity"); - return; - } - - _tree.Add(typeHashCode, component); -#if FANTASY_NET - if (component is ISupportedDataBase) - { - _treeDb ??= Scene.EntityListPool.Rent(); - _treeDb.Add(component); - } -#endif - } - - component.Parent = this; - component.Scene = Scene; - } - - /// - /// 添加一个组件到当前实体上 - /// - /// 要添加的实体实例 - /// 要添加组件的泛型类型 - public void AddComponent(T component) where T : Entity - { - var type = typeof(T); - - if (type == typeof(Entity)) - { - Log.Error("Cannot add a generic Entity type as a component. Specify a more specific type."); - return; - } - - if (this == component) - { - Log.Error("Cannot add oneself to one's own components"); - return; - } - - if (component.IsDisposed) - { - Log.Error($"component is Disposed {type.FullName}"); - return; - } - - component.Parent?.RemoveComponent(component, false); - - if (SupportedMultiEntityChecker.IsSupported) - { - _multi ??= Scene.EntitySortedDictionaryPool.Rent(); - _multi.Add(component.Id, component); -#if FANTASY_NET - if (SupportedDataBaseChecker.IsSupported) - { - _multiDb ??= Scene.EntityListPool.Rent(); - _multiDb.Add(component); - } -#endif - } - else - { -#if FANTASY_NET - if (SupportedSingleCollectionChecker.IsSupported && component.Id != Id) - { - Log.Error($"component type :{type.FullName} for implementing ISupportedSingleCollection, it is required that the Id must be the same as the parent"); - } -#endif - var typeHashCode = Scene.EntityComponent.GetHashCode(type); - - if (_tree == null) - { - _tree = Scene.EntitySortedDictionaryPool.Rent(); - } - else if (_tree.ContainsKey(typeHashCode)) - { - Log.Error($"type:{type.FullName} If you want to add multiple components of the same type, please implement IMultiEntity"); - return; - } - - _tree.Add(typeHashCode, component); -#if FANTASY_NET - if (SupportedDataBaseChecker.IsSupported) - { - _treeDb ??= Scene.EntityListPool.Rent(); - _treeDb.Add(component); - } -#endif - } - - component.Parent = this; - component.Scene = Scene; - } - - /// - /// 添加一个组件到当前实体上 - /// - /// 组件的类型 - /// 是否在对象池创建 - /// - public Entity AddComponent(Type type, bool isPool = true) - { - var id = typeof(ISupportedMultiEntity).IsAssignableFrom(type) ? Scene.EntityIdFactory.Create : Id; - var entity = Entity.Create(Scene, type, id, isPool, false); - AddComponent(entity); - Scene.EntityComponent.Awake(entity); - Scene.EntityComponent.StartUpdate(entity); -#if FANTASY_UNITY - Scene.EntityComponent.StartLateUpdate(entity); -#endif - return entity; - } - - #endregion - - #region HasComponent - - /// - /// 当前实体上是否有指定类型的组件 - /// - /// - /// - public bool HasComponent() where T : Entity, new() - { - return HasComponent(typeof(T)); - } - - /// - /// 当前实体上是否有指定类型的组件 - /// - /// - /// - public bool HasComponent(Type type) - { - if (_tree == null) - { - return false; - } - - return _tree.ContainsKey(Scene.EntityComponent.GetHashCode(type)); - } - - /// - /// 当前实体上是否有指定类型的组件 - /// - /// - /// - /// - public bool HasComponent(long id) where T : Entity, ISupportedMultiEntity, new() - { - if (_multi == null) - { - return false; - } - - return _multi.ContainsKey(id); - } - - #endregion - - #region GetComponent - - /// - /// 当前实体上查找一个字实体 - /// - /// 要查找实体泛型类型 - /// 查找的实体实例 - public T GetComponent() where T : Entity, new() - { - if (_tree == null) - { - return null; - } - - var typeHashCode = Scene.EntityComponent.GetHashCode(typeof(T)); - return _tree.TryGetValue(typeHashCode, out var component) ? (T)component : null; - } - - /// - /// 当前实体上查找一个字实体 - /// - /// 要查找实体类型 - /// 查找的实体实例 - public Entity GetComponent(Type type) - { - if (_tree == null) - { - return null; - } - - var typeHashCode = Scene.EntityComponent.GetHashCode(type); - return _tree.TryGetValue(typeHashCode, out var component) ? component : null; - } - - /// - /// 当前实体上查找一个字实体 - /// - /// 要查找实体的Id - /// 要查找实体泛型类型 - /// 查找的实体实例 - public T GetComponent(long id) where T : Entity, ISupportedMultiEntity, new() - { - if (_multi == null) - { - return default; - } - - return _multi.TryGetValue(id, out var entity) ? (T)entity : default; - } - - /// - /// 当前实体上查找一个字实体,如果没有就创建一个新的并添加到当前实体上 - /// - /// 是否从对象池创建 - /// 要查找或添加实体泛型类型 - /// 查找的实体实例 - public T GetOrAddComponent(bool isPool = true) where T : Entity, new() - { - return GetComponent() ?? AddComponent(isPool); - } - - #endregion - - #region RemoveComponent - - /// - /// 当前实体下删除一个实体 - /// - /// 是否执行删除实体的Dispose方法 - /// 实体的泛型类型 - /// - public void RemoveComponent(bool isDispose = true) where T : Entity, new() - { - if (SupportedMultiEntityChecker.IsSupported) - { - throw new NotSupportedException($"{typeof(T).FullName} message:Cannot delete components that implement the ISupportedMultiEntity interface"); - } - - if (_tree == null) - { - return; - } - - var type = typeof(T); - var typeHashCode = Scene.EntityComponent.GetHashCode(type); - if (!_tree.TryGetValue(typeHashCode, out var component)) - { - return; - } -#if FANTASY_NET - if (_treeDb != null && SupportedDataBaseChecker.IsSupported) - { - _treeDb.Remove(component); - - if (_treeDb.Count == 0) - { - Scene.EntityListPool.Return(_treeDb); - _treeDb = null; - } - } -#endif - _tree.Remove(typeHashCode); - - if (_tree.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_tree); - _tree = null; - } - - if (isDispose) - { - component.Dispose(); - } - } - - /// - /// 当前实体下删除一个实体 - /// - /// 要删除的实体Id - /// 是否执行删除实体的Dispose方法 - /// 实体的泛型类型 - public void RemoveComponent(long id, bool isDispose = true) where T : Entity, ISupportedMultiEntity, new() - { - if (_multi == null) - { - return; - } - - if (!_multi.TryGetValue(id, out var component)) - { - return; - } -#if FANTASY_NET - if (SupportedDataBaseChecker.IsSupported) - { - _multiDb.Remove(component); - if (_multiDb.Count == 0) - { - Scene.EntityListPool.Return(_multiDb); - _multiDb = null; - } - } -#endif - _multi.Remove(component.Id); - if (_multi.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_multi); - _multi = null; - } - - if (isDispose) - { - component.Dispose(); - } - } - - /// - /// 当前实体下删除一个实体 - /// - /// 要删除的实体实例 - /// 是否执行删除实体的Dispose方法 - public void RemoveComponent(Entity component, bool isDispose = true) - { - if (this == component) - { - return; - } - - if (component is ISupportedMultiEntity) - { - if (_multi != null) - { - if (!_multi.ContainsKey(component.Id)) - { - return; - } -#if FANTASY_NET - if (component is ISupportedDataBase) - { - _multiDb.Remove(component); - if (_multiDb.Count == 0) - { - Scene.EntityListPool.Return(_multiDb); - _multiDb = null; - } - } -#endif - _multi.Remove(component.Id); - if (_multi.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_multi); - _multi = null; - } - } - } - else if (_tree != null) - { - var typeHashCode = Scene.EntityComponent.GetHashCode(component.Type); - if (!_tree.ContainsKey(typeHashCode)) - { - return; - } -#if FANTASY_NET - if (_treeDb != null && component is ISupportedDataBase) - { - _treeDb.Remove(component); - - if (_treeDb.Count == 0) - { - Scene.EntityListPool.Return(_treeDb); - _treeDb = null; - } - } -#endif - _tree.Remove(typeHashCode); - - if (_tree.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_tree); - _tree = null; - } - } - - if (isDispose) - { - component.Dispose(); - } - } - - /// - /// 当前实体下删除一个实体 - /// - /// 要删除的实体实例 - /// 是否执行删除实体的Dispose方法 - /// 实体的泛型类型 - public void RemoveComponent(T component, bool isDispose = true) where T : Entity - { - if (this == component) - { - return; - } - - if (typeof(T) == typeof(Entity)) - { - Log.Error("Cannot remove a generic Entity type as a component. Specify a more specific type."); - return; - } - - if (SupportedMultiEntityChecker.IsSupported) - { - if (_multi != null) - { - if (!_multi.ContainsKey(component.Id)) - { - return; - } -#if FANTASY_NET - if (SupportedDataBaseChecker.IsSupported) - { - _multiDb.Remove(component); - if (_multiDb.Count == 0) - { - Scene.EntityListPool.Return(_multiDb); - _multiDb = null; - } - } -#endif - _multi.Remove(component.Id); - if (_multi.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_multi); - _multi = null; - } - } - } - else if (_tree != null) - { - var typeHashCode = Scene.EntityComponent.GetHashCode(typeof(T)); - if (!_tree.ContainsKey(typeHashCode)) - { - return; - } -#if FANTASY_NET - if (_treeDb != null && SupportedDataBaseChecker.IsSupported) - { - _treeDb.Remove(component); - - if (_treeDb.Count == 0) - { - Scene.EntityListPool.Return(_treeDb); - _treeDb = null; - } - } -#endif - _tree.Remove(typeHashCode); - - if (_tree.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_tree); - _tree = null; - } - } - - if (isDispose) - { - component.Dispose(); - } - } - - #endregion - - #region Deserialize - - /// - /// 反序列化当前实体,因为在数据库加载过来的或通过协议传送过来的实体并没有跟当前Scene做关联。 - /// 所以必须要执行一下这个反序列化的方法才可以使用。 - /// - /// Scene - /// 是否是重新生成实体的Id,如果是数据库加载过来的一般是不需要的 - public void Deserialize(Scene scene, bool resetId = false) - { - if (RuntimeId != 0) - { - return; - } - - try - { - Scene = scene; - Type ??= GetType(); - RuntimeId = Scene.RuntimeIdFactory.Create; - if (resetId) - { - Id = RuntimeId; - } -#if FANTASY_NET - if (_treeDb != null && _treeDb.Count > 0) - { - _tree = Scene.EntitySortedDictionaryPool.Rent(); - foreach (var entity in _treeDb) - { - entity.Parent = this; - entity.Type = entity.GetType(); - var typeHashCode = Scene.EntityComponent.GetHashCode(entity.Type); - _tree.Add(typeHashCode, entity); - entity.Deserialize(scene, resetId); - } - } - - if (_multiDb != null && _multiDb.Count > 0) - { - _multi = Scene.EntitySortedDictionaryPool.Rent(); - foreach (var entity in _multiDb) - { - entity.Parent = this; - entity.Deserialize(scene, resetId); - _multi.Add(entity.Id, entity); - } - } -#endif - scene.AddEntity(this); - scene.EntityComponent.Deserialize(this); - } - catch (Exception e) - { - if (RuntimeId != 0) - { - scene.RemoveEntity(RuntimeId); - } - - Log.Error(e); - } - } - - #endregion - - #region ForEach -#if FANTASY_NET - /// - /// 查询当前实体下支持数据库分表存储实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public IEnumerable ForEachSingleCollection - { - get - { - foreach (var (_, treeEntity) in _tree) - { - if (treeEntity is not ISupportedSingleCollection) - { - continue; - } - - yield return treeEntity; - } - } - } - /// - /// 查询当前实体下支持传送实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public IEnumerable ForEachTransfer - { - get - { - if (_tree != null) - { - foreach (var (_, treeEntity) in _tree) - { - if (treeEntity is ISupportedTransfer) - { - yield return treeEntity; - } - } - } - - if (_multiDb != null) - { - foreach (var treeEntity in _multiDb) - { - if (treeEntity is not ISupportedTransfer) - { - continue; - } - - yield return treeEntity; - } - } - } - } -#endif - /// - /// 查询当前实体下的实现了ISupportedMultiEntity接口的实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public IEnumerable ForEachMultiEntity - { - get - { - if (_multi == null) - { - yield break; - } - - foreach (var (_, supportedMultiEntity) in _multi) - { - yield return supportedMultiEntity; - } - } - } - /// - /// 查找当前实体下的所有实体,不包括实现ISupportedMultiEntity接口的实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public IEnumerable ForEachEntity - { - get - { - if (_tree == null) - { - yield break; - } - - foreach (var (_, entity) in _tree) - { - yield return entity; - } - } - } - #endregion - - #region Dispose - - /// - /// 销毁当前实体,销毁后会自动销毁当前实体下的所有实体。 - /// - public virtual void Dispose() - { - if (IsDisposed) - { - return; - } - - var scene = Scene; - var runTimeId = RuntimeId; - RuntimeId = 0; - - if (_tree != null) - { - foreach (var (_, entity) in _tree) - { - entity.Dispose(); - } - - _tree.Clear(); - scene.EntitySortedDictionaryPool.Return(_tree); - _tree = null; - } - - if (_multi != null) - { - foreach (var (_, entity) in _multi) - { - entity.Dispose(); - } - - _multi.Clear(); - scene.EntitySortedDictionaryPool.Return(_multi); - _multi = null; - } -#if FANTASY_NET - if (_treeDb != null) - { - foreach (var entity in _treeDb) - { - entity.Dispose(); - } - - _treeDb.Clear(); - scene.EntityListPool.Return(_treeDb); - _treeDb = null; - } - - if (_multiDb != null) - { - foreach (var entity in _multiDb) - { - entity.Dispose(); - } - - _multiDb.Clear(); - scene.EntityListPool.Return(_multiDb); - _multiDb = null; - } -#endif - scene.EntityComponent.Destroy(this); - - if (Parent != null && Parent != this && !Parent.IsDisposed) - { - Parent.RemoveComponent(this, false); - Parent = null; - } - - Id = 0; - Scene = null; - Parent = null; - scene.RemoveEntity(runTimeId); - - if (IsPool()) - { - scene.EntityPool.Return(Type, this); - } - - Type = null; - } - - #endregion - - #region Pool - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - - #endregion - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/EntityPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/EntityPool.cs deleted file mode 100644 index 9a6441c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/EntityPool.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. - -namespace Fantasy.Entitas -{ - internal sealed class EntityPool : PoolCore - { - public EntityPool() : base(4096) { } - } - - internal sealed class EntityList : List, IPool where T : Entity - { - private bool _isPool; - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - internal sealed class EntityListPool : PoolCore> where T : Entity - { - public EntityListPool() : base(4096) { } - } - - internal sealed class EntitySortedDictionary : SortedDictionary, IPool where TN : Entity - { - private bool _isPool; - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - internal sealed class EntitySortedDictionaryPool : PoolCore> where TN : Entity - { - public EntitySortedDictionaryPool() : base(4096) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/EntityReference.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/EntityReference.cs deleted file mode 100644 index dd1a3fd..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/EntityReference.cs +++ /dev/null @@ -1,59 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -namespace Fantasy.Entitas -{ - /// - /// 实体引用检查组件 - /// - /// - public struct EntityReference where T : Entity - { - private T _entity; - private readonly long _runTimeId; - - private EntityReference(T t) - { - if (t == null) - { - _entity = null; - _runTimeId = 0; - return; - } - - _entity = t; - _runTimeId = t.RuntimeId; - } - - /// - /// 将一个实体转换为EntityReference - /// - /// 实体泛型类型 - /// 返回一个EntityReference - public static implicit operator EntityReference(T t) - { - return new EntityReference(t); - } - - /// - /// 将一个EntityReference转换为实体 - /// - /// 实体泛型类型 - /// 当实体已经被销毁过会返回null - public static implicit operator T(EntityReference v) - { - if (v._entity == null) - { - return null; - } - - if (v._entity.RuntimeId != v._runTimeId) - { - v._entity = null; - } - - return v._entity; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISingleCollectionRoot.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISingleCollectionRoot.cs deleted file mode 100644 index 84de7a4..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISingleCollectionRoot.cs +++ /dev/null @@ -1,17 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Entitas.Interface -{ - /// - /// Entity保存到数据库的时候会根据子组件设置分离存储特性分表存储在不同的集合表中 - /// - public interface ISingleCollectionRoot { } - public static class SingleCollectionRootChecker where T : Entity - { - public static bool IsSupported { get; } - - static SingleCollectionRootChecker() - { - IsSupported = typeof(ISingleCollectionRoot).IsAssignableFrom(typeof(T)); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedDataBase.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedDataBase.cs deleted file mode 100644 index f505241..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedDataBase.cs +++ /dev/null @@ -1,19 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Entitas.Interface -{ - /// - /// Entity支持数据库 - /// - // ReSharper disable once InconsistentNaming - public interface ISupportedDataBase { } - - public static class SupportedDataBaseChecker where T : Entity - { - public static bool IsSupported { get; } - - static SupportedDataBaseChecker() - { - IsSupported = typeof(ISupportedDataBase).IsAssignableFrom(typeof(T)); - } - } -} diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedMultiEntity.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedMultiEntity.cs deleted file mode 100644 index ee6aeb7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedMultiEntity.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Entitas.Interface -{ - /// - /// 支持再一个组件里添加多个同类型组件 - /// - public interface ISupportedMultiEntity : IDisposable { } - - public static class SupportedMultiEntityChecker where T : Entity - { - public static bool IsSupported { get; } - - static SupportedMultiEntityChecker() - { - IsSupported = typeof(ISupportedMultiEntity).IsAssignableFrom(typeof(T)); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedSingleCollection.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedSingleCollection.cs deleted file mode 100644 index 302e697..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedSingleCollection.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Entitas.Interface -{ - // Entity是单一集合、保存到数据库的时候不会跟随父组件保存在一个集合里、会单独保存在一个集合里 - // 需要配合SingleCollectionAttribute一起使用、如在Entity类头部定义SingleCollectionAttribute(typeOf(Unit)) - // SingleCollectionAttribute用来定义这个Entity是属于哪个Entity的子集 - /// - /// 定义实体支持单一集合存储的接口。当实体需要单独存储在一个集合中,并且在保存到数据库时不会与父组件一起保存在同一个集合中时,应实现此接口。 - /// - public interface ISupportedSingleCollection { } - public static class SupportedSingleCollectionChecker where T : Entity - { - public static bool IsSupported { get; } - - static SupportedSingleCollectionChecker() - { - IsSupported = typeof(ISupportedSingleCollection).IsAssignableFrom(typeof(T)); - } - } - /// - /// 表示用于指定实体的单一集合存储属性。此属性用于配合 接口使用, - /// 用于定义实体属于哪个父实体的子集合,以及在数据库中使用的集合名称。 - /// - [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] - public class SingleCollectionAttribute : Attribute - { - /// - /// 获取父实体的类型,指示此实体是属于哪个父实体的子集合。 - /// - public readonly Type RootType; - /// - /// 获取在数据库中使用的集合名称。 - /// - public readonly string CollectionName; - /// - /// 初始化 类的新实例,指定父实体类型和集合名称。 - /// - /// 父实体的类型。 - /// 在数据库中使用的集合名称。 - public SingleCollectionAttribute(Type rootType, string collectionName) - { - RootType = rootType; - CollectionName = collectionName; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedTransfer.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedTransfer.cs deleted file mode 100644 index a3ae4a9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/Supported/ISupportedTransfer.cs +++ /dev/null @@ -1,19 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#if FANTASY_NET -namespace Fantasy.Entitas.Interface -{ - /// - /// Entity支持传送 - /// - public interface ISupportedTransfer { } - public static class SupportedTransferChecker where T : Entity - { - public static bool IsSupported { get; } - - static SupportedTransferChecker() - { - IsSupported = typeof(ISupportedTransfer).IsAssignableFrom(typeof(T)); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IAwakeSystem.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IAwakeSystem.cs deleted file mode 100644 index f651701..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IAwakeSystem.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Entitas.Interface -{ - internal interface IAwakeSystem : IEntitiesSystem { } - /// - /// 实体的Awake事件的抽象接口 - /// - /// 实体的泛型类型 - public abstract class AwakeSystem : IAwakeSystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Awake(T self); - /// - /// 框架内部调用的触发Awake的方法。 - /// - /// 触发事件的实体实例 - public void Invoke(Entity self) - { - Awake((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/ICustomEntitiesSystem.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/ICustomEntitiesSystem.cs deleted file mode 100644 index da42e58..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/ICustomEntitiesSystem.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; - -namespace Fantasy.Entitas.Interface -{ - /// - /// 自定义组件事件系统接口 - /// 如果需要自定义组件事件系统,请继承此接口。 - /// 这个接口内部使用。不对外开放。 - /// - internal interface ICustomEntitiesSystem - { - /// - /// 事件类型 - /// 用于触发这个组件事件关键因素。 - /// - int CustomEventType { get; } - /// - /// 实体的类型 - /// - /// - Type EntitiesType(); - /// - /// 框架内部调用的触发事件方法 - /// - /// - void Invoke(Entity entity); - } - - /// - /// 自定义组件事件系统抽象类 - /// 如果需要自定义组件事件系统,请继承此抽象类。 - /// - /// - public abstract class CustomSystem : ICustomEntitiesSystem where T : Entity - { - /// - /// 这个1表示是一个自定义事件类型,执行这个事件是时候需要用到这个1. - /// - public abstract int CustomEventType { get; } - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Custom(T self); - /// - /// 实体的类型 - /// - /// - public abstract Type EntitiesType(); - /// - /// 框架内部调用的触发Awake的方法。 - /// - /// 触发事件的实体实例 - public void Invoke(Entity self) - { - Custom((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IDeserializeSystem.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IDeserializeSystem.cs deleted file mode 100644 index 9c38ab6..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IDeserializeSystem.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Entitas.Interface -{ - internal interface IDeserializeSystem : IEntitiesSystem { } - /// - /// 实体的反序列化事件的抽象接口 - /// - /// 实体的泛型数据 - public abstract class DeserializeSystem : IDeserializeSystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Deserialize(T self); - /// - /// 框架内部调用的触发Deserialize的方法 - /// - /// 触发事件的实体实例 - public void Invoke(Entity self) - { - Deserialize((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IDestroySystem.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IDestroySystem.cs deleted file mode 100644 index 531ebbe..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IDestroySystem.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Entitas.Interface -{ - internal interface IDestroySystem : IEntitiesSystem { } - /// - /// 实体销毁事件的抽象接口 - /// - /// - public abstract class DestroySystem : IDestroySystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Destroy(T self); - /// - /// 框架内部调用的触发Destroy的方法 - /// - /// - public void Invoke(Entity self) - { - Destroy((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IEntitiesSystem.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IEntitiesSystem.cs deleted file mode 100644 index 555d21a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IEntitiesSystem.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Entitas.Interface -{ - /// - /// ECS事件系统的核心接口,任何事件都是要继承这个接口 - /// - public interface IEntitiesSystem - { - /// - /// 实体的类型 - /// - /// - Type EntitiesType(); - /// - /// 框架内部调用的触发事件方法 - /// - /// - void Invoke(Entity entity); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/ILateUpdateSystem.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/ILateUpdateSystem.cs deleted file mode 100644 index 34b5f80..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/ILateUpdateSystem.cs +++ /dev/null @@ -1,36 +0,0 @@ -#if FANTASY_UNITY -using System; - -namespace Fantasy.Entitas.Interface -{ - internal interface ILateUpdateSystem : IEntitiesSystem { } - - /// - /// 实体的LateUpdate事件的抽象接口 - /// - /// 实体的泛型类型 - public abstract class LateUpdateSystem : ILateUpdateSystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void LateUpdate(T self); - - /// - /// 框架内部调用的触发Awake的方法。 - /// - /// 触发事件的实体实例 - public void Invoke(Entity self) - { - LateUpdate((T)self); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IUpdateSystem.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IUpdateSystem.cs deleted file mode 100644 index 4b34ac8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Interface/System/IUpdateSystem.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; - -namespace Fantasy.Entitas.Interface -{ - internal interface IUpdateSystem : IEntitiesSystem { } - /// - /// Update事件的抽象接口 - /// - /// - public abstract class UpdateSystem : IUpdateSystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Update(T self); - /// - /// 框架内部调用的触发Update的方法 - /// - /// 触发事件的实体实例 - public void Invoke(Entity self) - { - Update((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Builder/AsyncFTaskCompletedMethodBuilder.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Builder/AsyncFTaskCompletedMethodBuilder.cs deleted file mode 100644 index 60b0d08..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Builder/AsyncFTaskCompletedMethodBuilder.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - public struct AsyncFTaskCompletedMethodBuilder - { - public FTaskCompleted Task => default; - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncFTaskCompletedMethodBuilder Create() - { - return new AsyncFTaskCompletedMethodBuilder(); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - ExceptionDispatchInfo.Capture(exception).Throw(); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult() { } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.OnCompleted(stateMachine.MoveNext); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.UnsafeOnCompleted(stateMachine.MoveNext); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetStateMachine(IAsyncStateMachine stateMachine) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Builder/AsyncFTaskMethodBuilder.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Builder/AsyncFTaskMethodBuilder.cs deleted file mode 100644 index 6c072cd..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Builder/AsyncFTaskMethodBuilder.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -// ReSharper disable MemberCanBePrivate.Global -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8604 // Possible null reference argument. - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - public readonly struct AsyncFTaskMethodBuilder - { - public FTask Task - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncFTaskMethodBuilder Create() - { - return new AsyncFTaskMethodBuilder(FTask.Create()); - } - - public AsyncFTaskMethodBuilder(FTask fTask) - { - Task = fTask; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult() - { - Task.SetResult(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - Task.SetException(exception); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine - { - // 通常在异步方法中遇到 await 关键字时调用,并且需要将执行恢复到调用 await 之前的同步上下文。 - awaiter.OnCompleted(stateMachine.MoveNext); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine - { - // 通常在你不需要恢复到原始同步上下文时调用,这意味着你不关心在什么线程上恢复执行。 - awaiter.UnsafeOnCompleted(stateMachine.MoveNext); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetStateMachine(IAsyncStateMachine stateMachine) - { - // 用于设置和保存异步方法的状态机实例。 - // 编译器在生成异步方法时要求其存在。 - // 编译器生成的代码已经足够处理状态机的管理,所以这里没有什么特殊要求所以保持空实现。 - } - } - - [StructLayout(LayoutKind.Auto)] - public readonly struct AsyncFTaskMethodBuilder - { - public FTask Task - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncFTaskMethodBuilder Create() - { - return new AsyncFTaskMethodBuilder(FTask.Create()); - } - - public AsyncFTaskMethodBuilder(FTask fTask) - { - Task = fTask; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult(T value) - { - Task.SetResult(value); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - Task.SetException(exception); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.OnCompleted(stateMachine.MoveNext); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.UnsafeOnCompleted(stateMachine.MoveNext); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetStateMachine(IAsyncStateMachine stateMachine) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Builder/AsyncFVoidMethodBuilder.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Builder/AsyncFVoidMethodBuilder.cs deleted file mode 100644 index b9f7bc0..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Builder/AsyncFVoidMethodBuilder.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - internal struct AsyncFVoidMethodBuilder - { - public FVoid Task - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => default; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncFVoidMethodBuilder Create() - { - return default; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult() { } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - ExceptionDispatchInfo.Capture(exception).Throw(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.OnCompleted(stateMachine.MoveNext); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.UnsafeOnCompleted(stateMachine.MoveNext); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetStateMachine(IAsyncStateMachine stateMachine) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/FCancellationToken/FCancellationToken.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/FCancellationToken/FCancellationToken.cs deleted file mode 100644 index 90913e3..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/FCancellationToken/FCancellationToken.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; - -namespace Fantasy.Async -{ - /// - /// 用于FTask取消的CancellationToken - /// - public sealed class FCancellationToken : IDisposable - { - private bool _isDispose; - private bool _isCancel; - private readonly HashSet _actions = new HashSet(); - /// - /// 当前CancellationToken是否已经取消过了 - /// - public bool IsCancel => _isDispose || _isCancel; - /// - /// 添加一个取消要执行的Action - /// - /// - public void Add(Action action) - { - if (_isDispose) - { - return; - } - - _actions.Add(action); - } - /// - /// 移除一个取消要执行的Action - /// - /// - public void Remove(Action action) - { - if (_isDispose) - { - return; - } - - _actions.Remove(action); - } - /// - /// 取消CancellationToken - /// - public void Cancel() - { - if (IsCancel) - { - return; - } - - _isCancel = true; - - foreach (var action in _actions) - { - try - { - action.Invoke(); - } - catch (Exception e) - { - Console.WriteLine(e); - } - } - - _actions.Clear(); - } - /// - /// 销毁掉CancellationToken,会执行Cancel方法。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - if (!IsCancel) - { - Cancel(); - _isCancel = true; - } - - _isDispose = true; - - if (Caches.Count > 2000) - { - return; - } - - Caches.Enqueue(this); - } - - #region Static - - private static readonly ConcurrentQueue Caches = new ConcurrentQueue(); - - /// - /// 获取一个新的CancellationToken - /// - public static FCancellationToken ToKen - { - get - { - if (!Caches.TryDequeue(out var fCancellationToken)) - { - fCancellationToken = new FCancellationToken(); - } - - fCancellationToken._isCancel = false; - fCancellationToken._isDispose = false; - return fCancellationToken; - } - } - - #endregion - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/FTask.Extension/FTask.Factory.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/FTask.Extension/FTask.Factory.cs deleted file mode 100644 index 80c7fc8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/FTask.Extension/FTask.Factory.cs +++ /dev/null @@ -1,115 +0,0 @@ -#if !FANTASY_WEBGL -using System.Collections.Concurrent; -#endif -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.CompilerServices; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Async -{ - /// - /// 一个异步任务 - /// - public partial class FTask - { - private bool _isPool; -#if FANTASY_WEBGL - private static readonly Queue Caches = new Queue(); -#else - private static readonly ConcurrentQueue Caches = new ConcurrentQueue(); -#endif - /// - /// 创建一个空的任务 - /// - public static FTaskCompleted CompletedTask => new FTaskCompleted(); - - private FTask() { } - - /// - /// 创建一个任务 - /// - /// 是否从对象池中创建 - /// - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static FTask Create(bool isPool = true) - { - if (!isPool) - { - return new FTask(); - } - - if (!Caches.TryDequeue(out var fTask)) - { - fTask = new FTask(); - } - - fTask._isPool = true; - return fTask; - } - - private void Return() - { - if (!_isPool || Caches.Count > 2000) - { - return; - } - - _callBack = null; - _status = STaskStatus.Pending; - Caches.Enqueue(this); - } - } - - /// - /// 一个异步任务 - /// - /// 任务的泛型类型 - public partial class FTask - { - private bool _isPool; -#if FANTASY_WEBGL - private static readonly Queue> Caches = new Queue>(); -#else - private static readonly ConcurrentQueue> Caches = new ConcurrentQueue>(); -#endif - /// - /// 创建一个任务 - /// - /// 是否从对象池中创建 - /// - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static FTask Create(bool isPool = true) - { - if (!isPool) - { - return new FTask(); - } - - if (!Caches.TryDequeue(out var fTask)) - { - fTask = new FTask(); - } - - fTask._isPool = true; - return fTask; - } - - private FTask() { } - - private void Return() - { - if (!_isPool || Caches.Count > 2000) - { - return; - } - - _callBack = null; - _status = STaskStatus.Pending; - Caches.Enqueue(this); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/FTask.Extension/FTask.Tools.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/FTask.Extension/FTask.Tools.cs deleted file mode 100644 index a42edec..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/FTask.Extension/FTask.Tools.cs +++ /dev/null @@ -1,345 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -using System; -using System.Collections.Generic; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Async -{ - public partial class FTask - { - #region NetTimer - - /// - /// 异步等待指定时间 - /// - /// - /// - /// - /// - public static FTask Wait(Scene scene, long time, FCancellationToken cancellationToken = null) - { - return scene.TimerComponent.Net.WaitAsync(time, cancellationToken); - } - - /// - /// 异步等待直到指定时间 - /// - /// - /// - /// - /// - public static FTask WaitTill(Scene scene, long time, FCancellationToken cancellationToken = null) - { - return scene.TimerComponent.Net.WaitTillAsync(time, cancellationToken); - } - - /// - /// 异步等待一帧时间 - /// - /// - /// - public static FTask WaitFrame(Scene scene) - { - return scene.TimerComponent.Net.WaitFrameAsync(); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间 - /// - /// - /// - /// - /// - public static long OnceTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Net.OnceTimer(time, action); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。 - /// - /// - /// - /// - /// - public static long OnceTillTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Net.OnceTillTimer(time, action); - } - - /// - /// 创建一个只执行一次的计时器,用于发布指定类型的事件。 - /// - /// - /// - /// - /// - /// - public static long OnceTimer(Scene scene, long time, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Net.OnceTimer(time, timerHandlerType); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间,用于发布指定类型的事件。 - /// - /// - /// - /// - /// - /// - public static long OnceTillTimer(Scene scene, long tillTime, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Net.OnceTillTimer(tillTime, timerHandlerType); - } - - /// - /// 创建一个重复执行的计时器。 - /// - /// - /// - /// - /// - public static long RepeatedTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Net.RepeatedTimer(time, action); - } - - /// - /// 创建一个重复执行的计时器,用于发布指定类型的事件。 - /// - /// - /// - /// - /// - /// - public static long RepeatedTimer(Scene scene, long time, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Net.RepeatedTimer(time, timerHandlerType); - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// - /// - /// - public static bool RemoveTimer(Scene scene, ref long timerId) - { - return scene.TimerComponent.Net.Remove(ref timerId); - } - - #endregion - - #region Unity - -#if FANTASY_UNITY - /// - /// 异步等待指定时间。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static FTask UnityWait(Scene scene, long time, FCancellationToken cancellationToken = null) - { - return scene.TimerComponent.Unity.WaitAsync(time, cancellationToken); - } - - /// - /// 异步等待直到指定时间。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static FTask UnityWaitTill(Scene scene, long time, FCancellationToken cancellationToken = null) - { - return scene.TimerComponent.Unity.WaitTillAsync(time, cancellationToken); - } - - /// - /// 异步等待一帧时间。(使用Unity的Time时间) - /// - /// - /// - public static FTask UnityWaitFrame(Scene scene) - { - return scene.TimerComponent.Unity.WaitFrameAsync(); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static long UnityOnceTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Unity.OnceTimer(time, action); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static long UnityOnceTillTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Unity.OnceTillTimer(time, action); - } - - /// - /// 创建一个只执行一次的计时器,用于发布指定类型的事件。(使用Unity的Time时间) - /// - /// - /// - /// - /// - /// - public static long UnityOnceTimer(Scene scene, long time, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Unity.OnceTimer(time, timerHandlerType); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间,用于发布指定类型的事件。(使用Unity的Time时间) - /// - /// - /// - /// - /// - /// - public static long UnityOnceTillTimer(Scene scene, long tillTime, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Unity.OnceTillTimer(tillTime, timerHandlerType); - } - - /// - /// 创建一个重复执行的计时器。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static long UnityRepeatedTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Unity.RepeatedTimer(time, action); - } - - /// - /// 创建一个重复执行的计时器,用于发布指定类型的事件。(使用Unity的Time时间) - /// - /// - /// - /// - /// - /// - public static long UnityRepeatedTimer(Scene scene, long time, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Unity.RepeatedTimer(time, timerHandlerType); - } - - /// - /// 移除指定 ID 的计时器。(使用Unity的Time时间) - /// - /// - /// - /// - public static bool UnityRemoveTimer(Scene scene, ref long timerId) - { - return scene.TimerComponent.Unity.Remove(ref timerId); - } -#endif - - #endregion - - /// - /// 创建并运行一个异步任务 - /// - /// - /// - public static FTask Run(Func factory) - { - return factory(); - } - - /// - /// 创建并运行一个带有结果的异步任务 - /// - /// - /// - /// - public static FTask Run(Func> factory) - { - return factory(); - } - - /// - /// 等待所有任务完成 - /// - /// - public static async FTask WaitAll(List tasks) - { - if (tasks.Count <= 0) - { - return; - } - - var count = tasks.Count; - var sTaskCompletionSource = Create(); - - foreach (var task in tasks) - { - RunSTask(task).Coroutine(); - } - - await sTaskCompletionSource; - - async FVoid RunSTask(FTask task) - { - await task; - count--; - if (count <= 0) - { - sTaskCompletionSource.SetResult(); - } - } - } - /// - /// 等待其中一个任务完成 - /// - /// - public static async FTask WaitAny(List tasks) - { - if (tasks.Count <= 0) - { - return; - } - - var count = 1; - var sTaskCompletionSource = Create(); - - foreach (var task in tasks) - { - RunSTask(task).Coroutine(); - } - - await sTaskCompletionSource; - - async FVoid RunSTask(FTask task) - { - await task; - count--; - if (count == 0) - { - sTaskCompletionSource.SetResult(); - } - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Task/FTask.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Task/FTask.cs deleted file mode 100644 index ce925f2..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Task/FTask.cs +++ /dev/null @@ -1,263 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable ConditionalAccessQualifierIsNonNullableAccordingToAPIContract -// ReSharper disable CheckNamespace -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Async -{ - public enum STaskStatus : byte - { - Pending = 0, // The operation has not yet completed. - Succeeded = 1, // The operation completed successfully. - Faulted = 2 // The operation completed with an error. - } - - [AsyncMethodBuilder(typeof(AsyncFTaskMethodBuilder))] - public sealed partial class FTask : ICriticalNotifyCompletion - { - private Action _callBack; - private ExceptionDispatchInfo _exception; - private STaskStatus _status = STaskStatus.Pending; - public bool IsCompleted - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _status != STaskStatus.Pending; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public FTask GetAwaiter() => this; - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private async FVoid InnerCoroutine() - { - await this; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Coroutine() - { - InnerCoroutine().Coroutine(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void GetResult() - { - switch (_status) - { - case STaskStatus.Succeeded: - { - Return(); - return; - } - case STaskStatus.Faulted: - { - Return(); - - if (_exception == null) - { - return; - } - - var exception = _exception; - _exception = null; - exception.Throw(); - return; - } - default: - { - throw new NotSupportedException("Direct call to getResult is not allowed"); - } - } - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult() - { - if (_status != STaskStatus.Pending) - { - throw new InvalidOperationException("The task has been completed"); - } - - _status = STaskStatus.Succeeded; - - if (_callBack == null) - { - return; - } - - var callBack = _callBack; - _callBack = null; - callBack.Invoke(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void OnCompleted(Action action) - { - UnsafeOnCompleted(action); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UnsafeOnCompleted(Action action) - { - if (_status != STaskStatus.Pending) - { - action?.Invoke(); - return; - } - - _callBack = action; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - if (_status != STaskStatus.Pending) - { - throw new InvalidOperationException("The task has been completed"); - } - - _status = STaskStatus.Faulted; - _exception = ExceptionDispatchInfo.Capture(exception); - _callBack?.Invoke(); - } - } - - [AsyncMethodBuilder(typeof(AsyncFTaskMethodBuilder<>))] - public sealed partial class FTask : ICriticalNotifyCompletion - { - private T _value; - private Action _callBack; - private ExceptionDispatchInfo _exception; - private STaskStatus _status = STaskStatus.Pending; - public bool IsCompleted - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _status != STaskStatus.Pending; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public FTask GetAwaiter() => this; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerHidden] - private async FVoid InnerCoroutine() - { - await this; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Coroutine() - { - InnerCoroutine().Coroutine(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T GetResult() - { - switch (_status) - { - case STaskStatus.Succeeded: - { - var value = _value; - Return(); - return value; - } - case STaskStatus.Faulted: - { - Return(); - - if (_exception == null) - { - return default; - } - - var exception = _exception; - _exception = null; - exception.Throw(); - return default; - } - default: - { - throw new NotSupportedException("Direct call to getResult is not allowed"); - } - } - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult(T value) - { - if (_status != STaskStatus.Pending) - { - throw new InvalidOperationException("The task has been completed"); - } - - _value = value; - _status = STaskStatus.Succeeded; - - if (_callBack == null) - { - return; - } - - var callBack = _callBack; - _callBack = null; - callBack.Invoke(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void OnCompleted(Action action) - { - UnsafeOnCompleted(action); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UnsafeOnCompleted(Action action) - { - if (_status != STaskStatus.Pending) - { - action?.Invoke(); - return; - } - - _callBack = action; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - if (_status != STaskStatus.Pending) - { - throw new InvalidOperationException("The task has been completed"); - } - - _status = STaskStatus.Faulted; - _exception = ExceptionDispatchInfo.Capture(exception); - _callBack?.Invoke(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Task/FTaskCompleted.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Task/FTaskCompleted.cs deleted file mode 100644 index 48b9e36..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Task/FTaskCompleted.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - [AsyncMethodBuilder(typeof(AsyncFTaskCompletedMethodBuilder))] - public struct FTaskCompleted : ICriticalNotifyCompletion - { - [DebuggerHidden] - public bool IsCompleted => true; - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public FTaskCompleted GetAwaiter() - { - return this; - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void GetResult() { } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void OnCompleted(Action continuation) { } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UnsafeOnCompleted(Action continuation) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Task/FVoid.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Task/FVoid.cs deleted file mode 100644 index f10ca7c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/FTask/Task/FVoid.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - [AsyncMethodBuilder(typeof(AsyncFVoidMethodBuilder))] - internal struct FVoid : ICriticalNotifyCompletion - { - public bool IsCompleted - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => true; - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Coroutine() { } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void OnCompleted(Action continuation) { } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UnsafeOnCompleted(Action continuation) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/ByteHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/ByteHelper.cs deleted file mode 100644 index 3e8492b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/ByteHelper.cs +++ /dev/null @@ -1,801 +0,0 @@ -using System; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace Fantasy.Helper -{ - /// - /// 提供字节操作辅助方法的静态类。 - /// - public static class ByteHelper - { - private static readonly string[] HexTableUpper = new string[256]; - private static readonly string[] HexTableLower = new string[256]; - private static readonly string[] Suffix = { "Byte", "KB", "MB", "GB", "TB" }; - private static readonly long[] Divisors = { 1L, 1024L, 1024L * 1024, 1024L * 1024 * 1024, 1024L * 1024 * 1024 * 1024 }; - - static ByteHelper() - { - // 预计算所有256个字节的十六进制表示 - for (var i = 0; i < 256; i++) - { - HexTableUpper[i] = i.ToString("X2"); // 大写:00, 01, ..., FF - HexTableLower[i] = i.ToString("x2"); // 小写:00, 01, ..., ff - } - } - - #region Read - - /// - /// 从指定的流中读取一个 64 位整数。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long ReadInt64(this Stream stream) - { - Span buffer = stackalloc byte[8]; -#if FANTASY_NET - stream.ReadExactly(buffer); -#else - _ = stream.Read(buffer); -#endif - return MemoryMarshal.Read(buffer); - } - - /// - /// 从指定的流中读取一个 32 位整数。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ReadInt32(this Stream stream) - { - Span buffer = stackalloc byte[4]; -#if FANTASY_NET - stream.ReadExactly(buffer); -#else - _ = stream.Read(buffer); -#endif - return MemoryMarshal.Read(buffer); - } - - /// - /// 从指定的流中读取一个 16 位整数。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ReadInt16(this Stream stream) - { - Span buffer = stackalloc byte[2]; -#if FANTASY_NET - stream.ReadExactly(buffer); -#else - _ = stream.Read(buffer); -#endif - return MemoryMarshal.Read(buffer); - } - - /// - /// 从指定的流中读取一个无符号 64 位整数。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong ReadUInt64(this Stream stream) - { - Span buffer = stackalloc byte[8]; -#if FANTASY_NET - stream.ReadExactly(buffer); -#else - _ = stream.Read(buffer); -#endif - return MemoryMarshal.Read(buffer); - } - - /// - /// 从指定的流中读取一个无符号 32 位整数。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong ReadUInt32(this Stream stream) - { - Span buffer = stackalloc byte[4]; -#if FANTASY_NET - stream.ReadExactly(buffer); -#else - _ = stream.Read(buffer); -#endif - return MemoryMarshal.Read(buffer); - } - - /// - /// 从指定的流中读取一个无符号 16 位整数。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong ReadUInt16(this Stream stream) - { - Span buffer = stackalloc byte[2]; -#if FANTASY_NET - stream.ReadExactly(buffer); -#else - _ = stream.Read(buffer); -#endif - return MemoryMarshal.Read(buffer); - } - - #endregion - - #region WriteTo - - /// - /// 将值写入字节数组的指定偏移位置。 - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteTo(this byte[] bytes, int offset, T value) where T : unmanaged - { - if (offset < 0 || offset + Marshal.SizeOf() > bytes.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - MemoryMarshal.Write(bytes.AsSpan(offset), -#if FANTASY_NET || FANTASY_CONSOLE - in value -#endif -#if FANTASY_UNITY - ref value -#endif - ); - } - - /// - /// 将值写入Span的指定偏移位置。 - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteTo(this Span span, int offset, T value) where T : unmanaged - { - if (offset < 0 || offset + Marshal.SizeOf() > span.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - MemoryMarshal.Write(span.Slice(offset), -#if FANTASY_NET || FANTASY_CONSOLE - in value -#endif -#if FANTASY_UNITY - ref value -#endif - ); - } - - /// - /// 将值写入内存流 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteTo(this Stream stream, T value) where T : unmanaged - { - Span buffer = stackalloc byte[Marshal.SizeOf()]; - MemoryMarshal.Write(buffer, -#if FANTASY_NET || FANTASY_CONSOLE - in value -#endif -#if FANTASY_UNITY - ref value -#endif - ); - stream.Write(buffer); - } - - /// - /// 将值写入内存流的指定偏移位置。 - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteTo(this Stream stream, int offset, T value) where T : unmanaged - { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } - - if (!stream.CanSeek) - { - throw new NotSupportedException("Stream must support seeking"); - } - - if (offset < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - - var originalPosition = stream.Position; - try - { - stream.Position = offset; - Span buffer = stackalloc byte[Marshal.SizeOf()]; - MemoryMarshal.Write(buffer, -#if FANTASY_NET || FANTASY_CONSOLE - in value -#endif -#if FANTASY_UNITY - ref value -#endif - ); - stream.Write(buffer); - } - finally - { - stream.Position = originalPosition; - } - } - - #endregion - - #region ReadFrom - - /// - /// 从字节数组的指定偏移位置读取值。 - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T ReadFrom(this byte[] bytes, int offset) where T : unmanaged - { - if (offset < 0 || offset + Marshal.SizeOf() > bytes.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - - return MemoryMarshal.Read(bytes.AsSpan(offset)); - } - - /// - /// 从Span的指定偏移位置读取值。 - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T ReadFrom(this ReadOnlySpan span, int offset) where T : unmanaged - { - if (offset < 0 || offset + Marshal.SizeOf() > span.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - - return MemoryMarshal.Read(span.Slice(offset)); - } - - /// - /// 从流的指定偏移位置读取值 - /// - /// - /// - /// 是否在读取完成后恢复到原始位置 - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T ReadFrom(this Stream stream, int offset, bool restorePosition = false) where T : unmanaged - { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } - - if (!stream.CanSeek) - { - throw new NotSupportedException("Stream must support seeking"); - } - - if (offset < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - - var originalPosition = restorePosition ? stream.Position : 0; - - try - { - var sizeOf = Marshal.SizeOf(); - stream.Position = offset; - Span buffer = stackalloc byte[sizeOf]; -#if FANTASY_NET - stream.ReadExactly(buffer); -#else - var bytesRead = stream.Read(buffer); - if (bytesRead != sizeOf) - { - throw new EndOfStreamException($"Could not read {sizeOf} bytes from stream"); - } -#endif - return MemoryMarshal.Read(buffer); - } - finally - { - if (restorePosition) - { - stream.Position = originalPosition; - } - } - } - - #endregion - - #region GetBytes - - /// - /// 将值转换为字节数组。 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(this T value, Span buffer) where T : unmanaged - { - if (buffer.Length < Marshal.SizeOf()) - { - throw new ArgumentException($"Buffer too small. Required: {Marshal.SizeOf()}, Actual: {buffer.Length}"); - } - - MemoryMarshal.Write(buffer, -#if FANTASY_NET || FANTASY_CONSOLE - in value -#endif -#if FANTASY_UNITY - ref value -#endif - ); - } - - /// - /// 将值转换为字节数组。 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(this T value, byte[] buffer) where T : unmanaged - { - value.GetBytes(buffer.AsSpan()); - } - - /// - /// 将值转换为字节数组。 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] GetBytes(this T value) where T : unmanaged - { - var result = new byte[Marshal.SizeOf()]; - MemoryMarshal.Write(result.AsSpan(), -#if FANTASY_NET || FANTASY_CONSOLE - in value -#endif -#if FANTASY_UNITY - ref value -#endif - ); - return result; - } - - #endregion - - #region ToReadableSpeed - - /// - /// 将字节数转换为可读的大小表示 - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToReadableSpeed(this long byteCount) - { - switch (byteCount) - { - case <= 0: - { - return "0 Byte"; - } - // < 1TB,使用快速版本 - case < 1L << 40: - { - var minLevel = 0; - var temp = byteCount; - while (temp >= 1024 && minLevel < 4) - { - temp >>= 10; - minLevel++; - } - return $"{(double)byteCount / Divisors[minLevel]:0.##} {Suffix[minLevel]}"; - } - default: - { -#if NET6_0_OR_GREATER - var level = Math.Min((int)(Math.Log2(byteCount) / 10), Suffix.Length - 1); -#else - // .NET Framework / .NET Core < 6.0 替代方案 - var level = Math.Min((int)(Math.Log(byteCount) / Math.Log(2) / 10), Suffix.Length - 1); -#endif - var divisor = 1L << (level * 10); - var value = (double)byteCount / divisor; - return $"{value:0.##} {Suffix[level]}"; - } - } - } - - /// - /// 将字节数转换为可读的大小表示(无符号版本) - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToReadableSpeed(this ulong byteCount) - { - switch (byteCount) - { - case 0: - { - return "0 Byte"; - } - // < 1TB,使用快速版本 - case < 1L << 40: - { - var minLevel = 0; - var temp = byteCount; - while (temp >= 1024 && minLevel < 4) - { - temp >>= 10; - minLevel++; - } - return $"{(double)byteCount / Divisors[minLevel]:0.##} {Suffix[minLevel]}"; - } - default: - { -#if NET6_0_OR_GREATER - var level = Math.Min((int)(Math.Log2(byteCount) / 10), Suffix.Length - 1); -#else - // .NET Framework / .NET Core < 6.0 替代方案 - var level = Math.Min((int)(Math.Log(byteCount) / Math.Log(2) / 10), Suffix.Length - 1); -#endif - var divisor = 1L << (level * 10); - var value = (double)byteCount / divisor; - return $"{value:0.##} {Suffix[level]}"; - } - } - } - - #endregion - - #region MergeBytes - - /// - /// 合并字节数组到目标缓冲区(零分配版本)。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void MergeBytesTo(Span destination, ReadOnlySpan first, ReadOnlySpan second) - { - if (destination.Length < first.Length + second.Length) - throw new ArgumentException("Destination buffer too small"); - - first.CopyTo(destination); - second.CopyTo(destination.Slice(first.Length)); - } - - /// - /// 合并两个字节数组。 - /// - /// 第一个字节数组 - /// 第二个字节数组 - /// 合并后的字节数组 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] MergeBytes(byte[] bytes, byte[] otherBytes) - { - if (bytes == null) - { - throw new ArgumentNullException(nameof(bytes)); - } - - if (otherBytes == null) - { - throw new ArgumentNullException(nameof(otherBytes)); - } - - // 优化:如果其中一个为空,直接返回另一个的副本 - if (bytes.Length == 0) - { - return (byte[])otherBytes.Clone(); - } - - if (otherBytes.Length == 0) - { - return (byte[])bytes.Clone(); - } - - var result = new byte[bytes.Length + otherBytes.Length]; - bytes.CopyTo(result.AsSpan()); - otherBytes.CopyTo(result.AsSpan(bytes.Length)); - return result; - } - - #endregion - - #region ToHex - - /// - /// 将字节转换为大写十六进制字符串。 - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToHex(this byte b) - { - return HexTableUpper[b]; - } - - /// - /// 将字节转换为小写十六进制字符串。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToHexLower(this byte b) - { - return HexTableLower[b]; - } - - /// - /// 将字节转换为指定格式的十六进制字符串。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToHex(this byte b, bool upperCase) - { - return upperCase ? HexTableUpper[b] : HexTableLower[b]; - } - - /// - /// 将字节数组转换为十六进制字符串表示。 - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToHex(this byte[] bytes, bool upperCase = true) - { - if (bytes == null) - { - throw new ArgumentNullException(nameof(bytes)); - } - - if (bytes.Length == 0) - { - return string.Empty; - } - - var hexTable = upperCase ? HexTableUpper : HexTableLower; - - return string.Create(bytes.Length * 2, (bytes, hexTable), (chars, state) => - { - var (buffer, table) = state; - var charIndex = 0; - ref var bytesRef = ref MemoryMarshal.GetReference(buffer.AsSpan()); - - for (var i = 0; i < buffer.Length; i++) - { - var hexStr = table[Unsafe.Add(ref bytesRef, i)]; - chars[charIndex++] = hexStr[0]; - chars[charIndex++] = hexStr[1]; - } - }); - } - - /// - /// 将字节数组的指定范围按十六进制格式转换为字符串表示。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToHex(this byte[] bytes, int offset, int count, bool upperCase = true) - { - if (bytes == null) - { - throw new ArgumentNullException(nameof(bytes)); - } - - if (offset < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - - if (count < 0 || offset + count > bytes.Length) - { - throw new ArgumentOutOfRangeException(nameof(count)); - } - - if (count == 0) - { - return string.Empty; - } - - var hexTable = upperCase ? HexTableUpper : HexTableLower; - - return string.Create(count * 2, (bytes, offset, count, hexTable), (chars, state) => - { - var (buffer, start, length, table) = state; - var charIndex = 0; - ref var bytesRef = ref MemoryMarshal.GetReference(buffer.AsSpan()); - - for (var i = 0; i < length; i++) - { - var hexStr = table[Unsafe.Add(ref bytesRef, start + i)]; - chars[charIndex++] = hexStr[0]; - chars[charIndex++] = hexStr[1]; - } - }); - } - - /// - /// 将字节数组的指定范围按十六进制格式转换为字符串表示。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToHex(this ReadOnlySpan bytes, bool upperCase = true) - { - if (bytes.Length == 0) - { - return string.Empty; - } - - var hexTable = upperCase ? HexTableUpper : HexTableLower; - - return string.Create(bytes.Length * 2, (MemoryMarshal.GetReference(bytes), bytes.Length, hexTable), (chars, - state) => - { - var (bytesRef, length, table) = state; - var charIndex = 0; - - for (var i = 0; i < length; i++) - { - var hexStr = table[Unsafe.Add(ref bytesRef, i)]; - chars[charIndex++] = hexStr[0]; - chars[charIndex++] = hexStr[1]; - } - }); - } - - /// - /// 将十六进制字符串转换为字节数组。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] FromHex(this string hexString) - { - return hexString.AsSpan().FromHex(); - } - - /// - /// 将十六进制字符串转换为字节数组。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] FromHex(this ReadOnlySpan hexSpan) - { - if (hexSpan.Length == 0) - { - return Array.Empty(); - } - - if (hexSpan.Length % 2 != 0) - { - throw new ArgumentException("Hex string must have even length"); - } - - var result = new byte[hexSpan.Length / 2]; - - for (var i = 0; i < result.Length; i++) - { - var high = HexCharToValue(hexSpan[i * 2]); - var low = HexCharToValue(hexSpan[i * 2 + 1]); - result[i] = (byte)((high << 4) | low); - } - - return result; - } - - - /// - /// 将十六进制字符串转换到现有字节数组。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void FromHexTo(this string hexString, Span destination) - { - if (string.IsNullOrEmpty(hexString)) - { - return; - } - - if (hexString.Length % 2 != 0) - { - throw new ArgumentException("Hex string must have even length", nameof(hexString)); - } - - if (destination.Length < hexString.Length / 2) - { - throw new ArgumentException("Destination buffer too small", nameof(destination)); - } - - for (var i = 0; i < hexString.Length / 2; i++) - { - var high = HexCharToValue(hexString[i * 2]); - var low = HexCharToValue(hexString[i * 2 + 1]); - destination[i] = (byte)((high << 4) | low); - } - } - - - /// - /// 将十六进制字符转换为数值。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int HexCharToValue(char c) - { - return c switch - { - >= '0' and <= '9' => c - '0', - >= 'A' and <= 'F' => c - 'A' + 10, - >= 'a' and <= 'f' => c - 'a' + 10, - _ => throw new ArgumentException($"Invalid hex character: {c}") - }; - } - - - /// - /// 将字节数组转换为默认编码的字符串表示。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToStr(this byte[] bytes) - { - return Encoding.Default.GetString(bytes); - } - - /// - /// 将字节数组的指定范围按默认编码转换为字符串表示。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToStr(this byte[] bytes, int index, int count) - { - return Encoding.Default.GetString(bytes, index, count); - } - - /// - /// 将字节数组转换为 UTF-8 编码的字符串表示。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Utf8ToStr(this byte[] bytes) - { - return Encoding.UTF8.GetString(bytes); - } - - /// - /// 将字节数组的指定范围按 UTF-8 编码转换为字符串表示。 - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Utf8ToStr(this byte[] bytes, int index, int count) - { - return Encoding.UTF8.GetString(bytes, index, count); - } - - - #endregion - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/ADownload.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/ADownload.cs deleted file mode 100644 index 4846d51..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/ADownload.cs +++ /dev/null @@ -1,50 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public abstract class AUnityDownload : IDisposable - { - private long _timeId; - private ulong _totalDownloadedBytes; - private Download _download; - protected UnityWebRequest UnityWebRequest; - private FCancellationToken _cancellationToken; - private Scene Scene; - - protected AUnityDownload(Scene scene,Download download) - { - Scene = scene; - _download = download; - _download.Tasks.Add(this); - } - - protected UnityWebRequestAsyncOperation Start(UnityWebRequest unityWebRequest, bool monitor) - { - UnityWebRequest = unityWebRequest; - _timeId = Scene.TimerComponent.Unity.RepeatedTimer(33, Update); - return UnityWebRequest.SendWebRequest(); - } - - private void Update() - { - var downloadSpeed = UnityWebRequest.downloadedBytes - _totalDownloadedBytes; - _download.DownloadSpeed += downloadSpeed; - _download.TotalDownloadedBytes += downloadSpeed; - _totalDownloadedBytes = UnityWebRequest.downloadedBytes; - } - - public virtual void Dispose() - { - Update(); - _totalDownloadedBytes = 0; - UnityWebRequest?.Dispose(); - _download.Tasks.Remove(this); - Scene.TimerComponent.Unity.Remove(ref _timeId); - _download = null; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/ADownload.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/ADownload.cs.meta deleted file mode 100644 index 70e1e3c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/ADownload.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c5743903d34d474a818b5c2bafa31459 -timeCreated: 1726021902 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/Download.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/Download.cs deleted file mode 100644 index a53a42a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/Download.cs +++ /dev/null @@ -1,72 +0,0 @@ -#if FANTASY_UNITY -using System.Collections.Generic; -using System.Linq; -using Fantasy.Async; -using UnityEngine; - -namespace Fantasy.Unity.Download -{ - public sealed class Download - { - public Scene Scene; - public ulong DownloadSpeed; - public ulong TotalDownloadedBytes; - public readonly HashSet Tasks = new(); - - public static Download Create(Scene scene) => new Download(scene); - - private Download(Scene scene) - { - Scene = scene; - } - - public void Clear() - { - DownloadSpeed = 0; - TotalDownloadedBytes = 0; - - if (Tasks.Count <= 0) - { - return; - } - - foreach (var aUnityDownload in Tasks.ToArray()) - { - aUnityDownload.Dispose(); - } - - Tasks.Clear(); - } - - public FTask DownloadAssetBundle(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadAssetBundle(Scene, this).StartDownload(url, monitor, cancellationToken); - } - - public FTask DownloadAudioClip(string url, AudioType audioType, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadAudioClip(Scene, this).StartDownload(url, audioType, monitor, cancellationToken); - } - - public FTask DownloadSprite(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadSprite(Scene, this).StartDownload(url, monitor, cancellationToken); - } - - public FTask DownloadTexture(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadTexture(Scene, this).StartDownload(url, monitor, cancellationToken); - } - - public FTask DownloadText(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadText(Scene, this).StartDownload(url, monitor, cancellationToken); - } - - public FTask DownloadByte(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadByte(Scene, this).StartDownload(url, monitor, cancellationToken); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/Download.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/Download.cs.meta deleted file mode 100644 index 41e84be..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/Download.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5715816370e84842aaab799c9776a5e4 -timeCreated: 1726023436 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAssetBundle.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAssetBundle.cs deleted file mode 100644 index 9d8f5a4..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAssetBundle.cs +++ /dev/null @@ -1,54 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadAssetBundle : AUnityDownload - { - public DownloadAssetBundle(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequestAssetBundle.GetAssetBundle(Uri.EscapeUriString(url)), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var assetBundle = DownloadHandlerAssetBundle.GetContent(UnityWebRequest); - task.SetResult(assetBundle); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAssetBundle.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAssetBundle.cs.meta deleted file mode 100644 index c6bf29a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAssetBundle.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 07cbb9a010ed4fe1b90919f81847b9ea -timeCreated: 1726023471 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAudioClip.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAudioClip.cs deleted file mode 100644 index 29b3dc5..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAudioClip.cs +++ /dev/null @@ -1,54 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadAudioClip : AUnityDownload - { - public DownloadAudioClip(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, AudioType audioType, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequestMultimedia.GetAudioClip(Uri.EscapeUriString(url), audioType), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var audioClip = DownloadHandlerAudioClip.GetContent(UnityWebRequest); - task.SetResult(audioClip); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAudioClip.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAudioClip.cs.meta deleted file mode 100644 index 6440f22..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadAudioClip.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 66d3739ec33845148534e6ecaf134b73 -timeCreated: 1726023476 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadByte.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadByte.cs deleted file mode 100644 index 6c934d9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadByte.cs +++ /dev/null @@ -1,52 +0,0 @@ -#if FANTASY_UNITY -using Fantasy.Async; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadByte : AUnityDownload - { - public DownloadByte(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequest.Get(url), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var bytes = UnityWebRequest.downloadHandler.data; - task.SetResult(bytes); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadByte.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadByte.cs.meta deleted file mode 100644 index 0aa0487..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadByte.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ae87f3ea9f4e4c9ebabedf45b0bb83b1 -timeCreated: 1726023481 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadSprite.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadSprite.cs deleted file mode 100644 index 802a967..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadSprite.cs +++ /dev/null @@ -1,55 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadSprite : AUnityDownload - { - public DownloadSprite(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequestTexture.GetTexture(Uri.EscapeUriString(url)), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var texture = DownloadHandlerTexture.GetContent(UnityWebRequest); - var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 5, 1f); - task.SetResult(sprite); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadSprite.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadSprite.cs.meta deleted file mode 100644 index 354e3e3..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadSprite.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 0c2a0f442e974169b7d8b7a5878fe0e6 -timeCreated: 1726023487 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadText.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadText.cs deleted file mode 100644 index 50d8329..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadText.cs +++ /dev/null @@ -1,52 +0,0 @@ -#if FANTASY_UNITY -using Fantasy.Async; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadText : AUnityDownload - { - public DownloadText(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequest.Get(url), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var text = UnityWebRequest.downloadHandler.text; - task.SetResult(text); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadText.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadText.cs.meta deleted file mode 100644 index 35892a9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadText.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 4284aafa8572453cb75920d2d58e9c50 -timeCreated: 1726023491 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadTexture.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadTexture.cs deleted file mode 100644 index f66533d..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadTexture.cs +++ /dev/null @@ -1,54 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadTexture : AUnityDownload - { - public DownloadTexture(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequestTexture.GetTexture(Uri.EscapeUriString(url)), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var texture = DownloadHandlerTexture.GetContent(UnityWebRequest); - task.SetResult(texture); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadTexture.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadTexture.cs.meta deleted file mode 100644 index 7b48ea6..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/Download/DownloadTexture.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5eaa6023378844ebb51e4b80425d8a4e -timeCreated: 1726023496 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/EncryptHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/EncryptHelper.cs deleted file mode 100644 index 5cbe7c7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/EncryptHelper.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.IO; -using System.Security.Cryptography; -using System.Text; - -namespace Fantasy.Helper -{ - /// - /// 提供计算 MD5 散列值的辅助方法。 - /// - public static partial class EncryptHelper - { - private static readonly SHA256 Sha256Hash = SHA256.Create(); - - /// - /// 计算指定字节数组的Sha256。 - /// - /// - /// - public static byte[] ComputeSha256Hash(byte[] bytes) - { -#if FANTASY_UNITY - using var sha256Hash = SHA256.Create(); - return sha256Hash.ComputeHash(bytes); -#else - return SHA256.HashData(bytes); -#endif - } - - /// - /// 计算指定文件的 MD5 散列值。 - /// - /// 要计算散列值的文件路径。 - /// 表示文件的 MD5 散列值的字符串。 - public static string FileMD5(string filePath) - { - using var file = new FileStream(filePath, FileMode.Open); - return FileMD5(file); - } - - /// - /// 计算给定文件流的 MD5 散列值。 - /// - /// 要计算散列值的文件流。 - /// 表示文件流的 MD5 散列值的字符串。 - public static string FileMD5(FileStream fileStream) - { - var md5 = MD5.Create(); - return md5.ComputeHash(fileStream).ToHex(false); - } - - /// - /// 计算给定字节数组的 MD5 散列值。 - /// - /// 要计算散列值的字节数组。 - /// 表示字节数组的 MD5 散列值的字符串。 - public static string BytesMD5(byte[] bytes) - { - var md5 = MD5.Create(); - bytes = md5.ComputeHash(bytes); - return bytes.ToHex(false); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/FileHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/FileHelper.cs deleted file mode 100644 index 00c18ec..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/FileHelper.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace Fantasy.Helper -{ - /// - /// 文件操作助手类,提供了各种文件操作方法。 - /// - public static partial class FileHelper - { - /// - /// 获取相对路径的完整路径。 - /// - /// 相对路径。 - /// 完整路径。 - public static string GetFullPath(string relativePath) - { - return Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, relativePath)); - } - - /// - /// 获取相对路径的完整路径。 - /// - /// 相对于指定的目录的相对路径。 - /// 指定的目录 - /// 完整路径。 - public static string GetFullPath(string relativePath, string srcDir) - { - return Path.GetFullPath(Path.Combine(srcDir, relativePath)); - } - - /// - /// 获取相对路径的的文本信息。 - /// - /// - /// - public static async Task GetTextByRelativePath(string relativePath) - { - var fullPath = GetFullPath(relativePath); - return await File.ReadAllTextAsync(fullPath, Encoding.UTF8); - } - - /// - /// 获取绝对路径的的文本信息。 - /// - /// - /// - public static async Task GetText(string fullPath) - { - return await File.ReadAllTextAsync(fullPath, Encoding.UTF8); - } - - /// - /// 根据文件夹路径创建文件夹,如果文件夹不存在会自动创建文件夹。 - /// - /// - public static void CreateDirectory(string directoryPath) - { - if (directoryPath.LastIndexOf('/') != directoryPath.Length - 1) - { - directoryPath += "/"; - } - - var directoriesByFilePath = GetDirectoriesByFilePath(directoryPath); - - foreach (var dir in directoriesByFilePath) - { - if (Directory.Exists(dir)) - { - continue; - } - - Directory.CreateDirectory(dir); - } - } - - /// - /// 将文件复制到目标路径,如果目标目录不存在会自动创建目录。 - /// - /// 源文件路径。 - /// 目标文件路径。 - /// 是否覆盖已存在的目标文件。 - public static void Copy(string sourceFile, string destinationFile, bool overwrite) - { - CreateDirectory(destinationFile); - File.Copy(sourceFile, destinationFile, overwrite); - } - - /// - /// 获取文件路径内的所有文件夹路径。 - /// - /// 文件路径。 - /// 文件夹路径列表。 - public static IEnumerable GetDirectoriesByFilePath(string filePath) - { - var dir = ""; - var fileDirectories = filePath.Split('/'); - - for (var i = 0; i < fileDirectories.Length - 1; i++) - { - dir = $"{dir}{fileDirectories[i]}/"; - yield return dir; - } - - if (fileDirectories.Length == 1) - { - yield return filePath; - } - } - - /// - /// 将文件夹内的所有内容复制到目标位置。 - /// - /// 源文件夹路径。 - /// 目标文件夹路径。 - /// 是否覆盖已存在的文件。 - public static void CopyDirectory(string sourceDirectory, string destinationDirectory, bool overwrite) - { - // 创建目标文件夹 - - if (!Directory.Exists(destinationDirectory)) - { - Directory.CreateDirectory(destinationDirectory); - } - - // 获取当前文件夹中的所有文件 - - var files = Directory.GetFiles(sourceDirectory); - - // 拷贝文件到目标文件夹 - - foreach (var file in files) - { - var fileName = Path.GetFileName(file); - var destinationPath = Path.Combine(destinationDirectory, fileName); - File.Copy(file, destinationPath, overwrite); - } - - // 获取源文件夹中的所有子文件夹 - - var directories = Directory.GetDirectories(sourceDirectory); - - // 递归方式拷贝文件夹 - - foreach (var directory in directories) - { - var directoryName = Path.GetFileName(directory); - var destinationPath = Path.Combine(destinationDirectory, directoryName); - CopyDirectory(directory, destinationPath, overwrite); - } - } - - /// - /// 获取目录下的所有文件 - /// - /// 文件夹路径。 - /// 需要查找的文件通配符 - /// 查找的类型 - /// - public static string[] GetDirectoryFile(string folderPath, string searchPattern, SearchOption searchOption) - { - return Directory.GetFiles(folderPath, searchPattern, searchOption); - } - - /// - /// 清空文件夹内的所有文件。 - /// - /// 文件夹路径。 - public static void ClearDirectoryFile(string folderPath) - { - if (!Directory.Exists(folderPath)) - { - return; - } - - var files = Directory.GetFiles(folderPath); - - foreach (var file in files) - { - File.Delete(file); - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HashCodeHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HashCodeHelper.cs deleted file mode 100644 index 4ea6f29..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HashCodeHelper.cs +++ /dev/null @@ -1,336 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -// ReSharper disable InconsistentNaming - -namespace Fantasy.Helper -{ - /// - /// HashCode算法帮助类 - /// - public static partial class HashCodeHelper - { - /// - /// 计算两个字符串的HashCode - /// - /// - /// - /// - public static int GetHashCode(string a, string b) - { - var hash = 17; - hash = hash * 31 + a.GetHashCode(); - hash = hash * 31 + b.GetHashCode(); - return hash; - } - - /// - /// 使用bkdr算法生成一个long的值 - /// - /// - /// - public static long GetBKDRHashCode(string str) - { - ulong hash = 0; - const uint seed = 13131; // 如果要修改这个种子、建议选择一个质数来做种子 31 131 1313 13131 131313 etc.. - var span = str.AsSpan(); - ref var local = ref MemoryMarshal.GetReference(span); - - for (var i = 0; i < span.Length; i++) - { - var c = Unsafe.Add(ref local, i); - var high = (byte)(c >> 8); - var low = (byte)(c & byte.MaxValue); - hash = hash * seed + high; - hash = hash * seed + low; - } - - return (long)hash; - } - - /// - /// 使用MurmurHash3算法生成一个uint的值 - /// - /// - /// - public static uint MurmurHash3(string str) - { - const uint seed = 0xc58f1a7b; - uint hash = seed; - uint c1 = 0xcc9e2d51; - uint c2 = 0x1b873593; - - var span = str.AsSpan(); - ref var local = ref MemoryMarshal.GetReference(span); - - for (var i = 0; i < span.Length; i++) - { - var k1 = (uint)Unsafe.Add(ref local, i); - k1 *= c1; - k1 = (k1 << 15) | (k1 >> (32 - 15)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 13) | (hash >> (32 - 13)); - hash = hash * 5 + 0xe6546b64; - } - - hash ^= (uint)str.Length; - hash ^= hash >> 16; - hash *= 0x85ebca6b; - hash ^= hash >> 13; - hash *= 0xc2b2ae35; - hash ^= hash >> 16; - return hash; - } - - /// - /// 使用MurmurHash3算法生成一个long的值 - /// - /// - /// - public static long ComputeHash64(string str) - { - const ulong seed = 0xc58f1a7bc58f1a7bUL; // 64-bit seed - var hash = seed; - var c1 = 0x87c37b91114253d5UL; - var c2 = 0x4cf5ad432745937fUL; - - var span = str.AsSpan(); - ref var local = ref MemoryMarshal.GetReference(span); - - for (var i = 0; i < span.Length; i++) - { - var k1 = (ulong)Unsafe.Add(ref local, i); - k1 *= c1; - k1 = (k1 << 31) | (k1 >> (64 - 31)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 27) | (hash >> (64 - 27)); - hash = hash * 5 + 0x52dce729; - } - - hash ^= (ulong)str.Length; - hash ^= hash >> 33; - hash *= 0xff51afd7ed558ccdUL; - hash ^= hash >> 33; - hash *= 0xc4ceb9fe1a85ec53UL; - hash ^= hash >> 33; - return (long)hash; - } - - /// - /// 根据字符串计算一个Hash值 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Hash32(string obj, uint seed = 0) => Hash32(obj.AsSpan(), seed); - - /// - /// 根据字符串计算一个Hash值 - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Hash32(in T obj, uint seed = 0) where T : unmanaged => Hash32( - MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref Unsafe.AsRef(in obj)), Unsafe.SizeOf()), - seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int Hash32(ReadOnlySpan buffer, uint seed = 0) where T : unmanaged => - Hash32(MemoryMarshal.Cast(buffer), seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int Hash32(ReadOnlySpan buffer, uint seed = 0) - { - int length = buffer.Length; - ref byte local1 = ref MemoryMarshal.GetReference(buffer); - uint num1; - if (buffer.Length >= 16) - { - uint num2 = seed + 606290984U; - uint num3 = seed + 2246822519U; - uint num4 = seed; - uint num5 = seed - 2654435761U; - for (; length >= 16; length -= 16) - { - const nint elementOffset1 = 4; - const nint elementOffset2 = 8; - const nint elementOffset3 = 12; - nint byteOffset = buffer.Length - length; - ref byte local2 = ref Unsafe.AddByteOffset(ref local1, byteOffset); - uint num6 = num2 + Unsafe.ReadUnaligned(ref local2) * 2246822519U; - num2 = (uint)((((int)num6 << 13) | (int)(num6 >> 19)) * -1640531535); - uint num7 = num3 + - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, elementOffset1)) * - 2246822519U; - num3 = (uint)((((int)num7 << 13) | (int)(num7 >> 19)) * -1640531535); - uint num8 = num4 + - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, elementOffset2)) * - 2246822519U; - num4 = (uint)((((int)num8 << 13) | (int)(num8 >> 19)) * -1640531535); - uint num9 = num5 + - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, elementOffset3)) * - 2246822519U; - num5 = (uint)((((int)num9 << 13) | (int)(num9 >> 19)) * -1640531535); - } - - num1 = (uint)((((int)num2 << 1) | (int)(num2 >> 31)) + (((int)num3 << 7) | (int)(num3 >> 25)) + - (((int)num4 << 12) | (int)(num4 >> 20)) + (((int)num5 << 18) | (int)(num5 >> 14)) + - buffer.Length); - } - else - num1 = (uint)((int)seed + 374761393 + buffer.Length); - - for (; length >= 4; length -= 4) - { - nint byteOffset = buffer.Length - length; - uint num10 = Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local1, byteOffset)); - uint num11 = num1 + num10 * 3266489917U; - num1 = (uint)((((int)num11 << 17) | (int)(num11 >> 15)) * 668265263); - } - - nint byteOffset1 = buffer.Length - length; - ref byte local3 = ref Unsafe.AddByteOffset(ref local1, byteOffset1); - for (int index = 0; index < length; ++index) - { - nint byteOffset2 = index; - uint num12 = Unsafe.AddByteOffset(ref local3, byteOffset2); - uint num13 = num1 + num12 * 374761393U; - num1 = (uint)((((int)num13 << 11) | (int)(num13 >> 21)) * -1640531535); - } - -#if NET7_0_OR_GREATER - int num14 = ((int)num1 ^ (int)(num1 >> 15)) * -2048144777; - int num15 = (num14 ^ (num14 >>> 13)) * -1028477379; - return num15 ^ (num15 >>> 16); -#else - int num14 = ((int)num1 ^ (int)(num1 >> 15)) * -2048144777; - int num15 = (num14 ^ (int)((uint)num14 >> 13)) * -1028477379; - return num15 ^ (int)((uint)num15 >> 16); -#endif - } - - /// - /// 根据字符串计算一个Hash值 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Hash64(string obj, ulong seed = 0) => Hash64(obj.AsSpan(), seed); - - /// - /// 根据字符串计算一个Hash值 - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Hash64(in T obj, ulong seed = 0) where T : unmanaged => Hash64( - MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref Unsafe.AsRef(in obj)), Unsafe.SizeOf()), - seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long Hash64(ReadOnlySpan buffer, ulong seed = 0) where T : unmanaged => - Hash64(MemoryMarshal.Cast(buffer), seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long Hash64(ReadOnlySpan buffer, ulong seed = 0) - { - ref var local1 = ref MemoryMarshal.GetReference(buffer); - var length = buffer.Length; - ulong num1; - if (buffer.Length >= 32) - { - var num2 = seed + 6983438078262162902UL; - var num3 = seed + 14029467366897019727UL; - var num4 = seed; - var num5 = seed - 11400714785074694791UL; - for (; length >= 32; length -= 32) - { - ref var local2 = ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length)); - var num6 = num2 + Unsafe.ReadUnaligned(ref local2) * 14029467366897019727UL; - num2 = (ulong)((((long)num6 << 31) | (long)(num6 >> 33)) * -7046029288634856825L); - var num7 = num3 + - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, new UIntPtr(8U))) * - 14029467366897019727UL; - num3 = (ulong)((((long)num7 << 31) | (long)(num7 >> 33)) * -7046029288634856825L); - var num8 = num4 + - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, new UIntPtr(16U))) * - 14029467366897019727UL; - num4 = (ulong)((((long)num8 << 31) | (long)(num8 >> 33)) * -7046029288634856825L); - var num9 = num5 + - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, new UIntPtr(24U))) * - 14029467366897019727UL; - num5 = (ulong)((((long)num9 << 31) | (long)(num9 >> 33)) * -7046029288634856825L); - } - - var num10 = (((long)num2 << 1) | (long)(num2 >> 63)) + (((long)num3 << 7) | (long)(num3 >> 57)) + - (((long)num4 << 12) | (long)(num4 >> 52)) + (((long)num5 << 18) | (long)(num5 >> 46)); - var num11 = num2 * 14029467366897019727UL; - var num12 = (((long)num11 << 31) | (long)(num11 >> 33)) * -7046029288634856825L; - var num13 = (num10 ^ num12) * -7046029288634856825L + -8796714831421723037L; - var num14 = num3 * 14029467366897019727UL; - var num15 = (((long)num14 << 31) | (long)(num14 >> 33)) * -7046029288634856825L; - var num16 = (num13 ^ num15) * -7046029288634856825L + -8796714831421723037L; - var num17 = num4 * 14029467366897019727UL; - var num18 = (((long)num17 << 31) | (long)(num17 >> 33)) * -7046029288634856825L; - var num19 = (num16 ^ num18) * -7046029288634856825L + -8796714831421723037L; - var num20 = num5 * 14029467366897019727UL; - var num21 = (((long)num20 << 31) | (long)(num20 >> 33)) * -7046029288634856825L; - num1 = (ulong)((num19 ^ num21) * -7046029288634856825L + -8796714831421723037L); - } - else - num1 = seed + 2870177450012600261UL; - - var num22 = num1 + (ulong)buffer.Length; - for (; length >= 8; length -= 8) - { - var num23 = Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local1, - (IntPtr)(buffer.Length - length))) * 14029467366897019727UL; - var num24 = (ulong)((((long)num23 << 31) | (long)(num23 >> 33)) * -7046029288634856825L); - var num25 = num22 ^ num24; - num22 = (ulong)((((long)num25 << 27) | (long)(num25 >> 37)) * -7046029288634856825L + - -8796714831421723037L); - } - - if (length >= 4) - { - ulong num26 = - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length))); - var num27 = num22 ^ (num26 * 11400714785074694791UL); - num22 = (ulong)((((long)num27 << 23) | (long)(num27 >> 41)) * -4417276706812531889L + - 1609587929392839161L); - length -= 4; - } - - for (var byteOffset = 0; byteOffset < length; ++byteOffset) - { - ulong num28 = - Unsafe.AddByteOffset(ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length)), - (IntPtr)byteOffset); - var num29 = num22 ^ (num28 * 2870177450012600261UL); - num22 = (ulong)((((long)num29 << 11) | (long)(num29 >> 53)) * -7046029288634856825L); - } - -#if NET7_0_OR_GREATER - var num30 = (long)num22; - var num31 = (num30 ^ (num30 >>> 33)) * -4417276706812531889L; - var num32 = (num31 ^ (num31 >>> 29)) * 1609587929392839161L; - return num32 ^ (num32 >>> 32); -#else - var num30 = (long)num22; - var num31 = (num30 ^ (long)((ulong)num30 >> 33)) * -4417276706812531889L; - var num32 = (num31 ^ (long)((ulong)num31 >> 29)) * 1609587929392839161L; - return num32 ^ (long)((ulong)num32 >> 32); -#endif - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs deleted file mode 100644 index 3954a8c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs +++ /dev/null @@ -1,144 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Pool; -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Http -{ - /// - /// HTTP帮助类 - /// - public static partial class HttpClientHelper - { - private static readonly HttpClient Client = new HttpClient(new HttpClientHandler - { - ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true - }); - - /// - /// 用Post方式请求string数据 - /// - /// - /// - /// - /// - public static async FTask CallNotDeserializeByPost(string url, HttpContent content) - { - var response = await Client.PostAsync(url, content); - - if (response.StatusCode != HttpStatusCode.OK) - { - throw new Exception($"Unable to connect to server url {(object)url} HttpStatusCode:{(object)response.StatusCode}"); - } - - return await response.Content.ReadAsStringAsync(); - } - - /// - /// 用Get方式请求string数据 - /// - /// - /// - /// - public static async FTask CallNotDeserializeByGet(string url) - { - var response = await Client.GetAsync(url); - - if (response.StatusCode != HttpStatusCode.OK) - { - throw new Exception($"Unable to connect to server url {(object)url} HttpStatusCode:{(object)response.StatusCode}"); - } - - return await response.Content.ReadAsStringAsync(); - } - - /// - /// 用Post方式请求JSON数据,并自动把JSON转换为对象。 - /// - /// - /// - /// - /// - public static async FTask CallByPost(string url, HttpContent content) - { - return await Deserialize(url, await Client.PostAsync(url, content)); - } - - /// - /// 用Post方式请求JSON数据,并自动把JSON转换为对象。 - /// - /// - /// - /// - /// - public static async FTask CallByPost(string url, HttpMethod method) - { - return await Deserialize(url, await Client.SendAsync(new HttpRequestMessage(method, url))); - } - - /// - /// 用Get方式请求JSON数据,并自动把JSON转换为对象。 - /// - /// - /// - /// - public static async FTask CallByGet(string url) - { - return await Deserialize(url, await Client.GetAsync(url)); - } - - /// - /// 用Post方式请求JSON数据,并自动把JSON转换为对象。 - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static async FTask Call(string url, int id, AuthenticationHeaderValue authentication, string method, params object[] @params) where TRequest : class, IJsonRpcRequest, new() - { - var request = Pool.Rent(); - using var httpClientPool = HttpClientPool.Create(); - var client = httpClientPool.Client; - client.DefaultRequestHeaders.Authorization = authentication; - - try - { - request.Init(method, id, @params); - var content = new StringContent(request.ToJson(), Encoding.UTF8, "application/json"); - var response = await Deserialize(url, await client.PostAsync(url, content)); - return response; - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - Pool.Return(request); - } - - return default; - } - - private static async FTask Deserialize(string url, HttpResponseMessage response) - { - if (response.StatusCode != HttpStatusCode.OK) - { - throw new Exception($"Unable to connect to server url {(object)url} HttpStatusCode:{(object)response.StatusCode}"); - } - - return (await response.Content.ReadAsStringAsync()).Deserialize(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs.meta deleted file mode 100644 index 70e3bd5..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f8005f3a1a1945a2929442f82832e765 -timeCreated: 1726023741 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientPool.cs deleted file mode 100644 index de421ff..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientPool.cs +++ /dev/null @@ -1,44 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Net.Http; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Http -{ - internal class HttpClientPool : IDisposable - { - private bool IsDispose { get; set; } - public HttpClient Client { get; private set; } - private static readonly Queue Pools = new Queue(); - private static readonly HttpClientHandler ClientHandler = new HttpClientHandler - { - ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true - }; - - public static HttpClientPool Create() - { - if (Pools.TryDequeue(out var httpClientPool)) - { - httpClientPool.IsDispose = false; - return httpClientPool; - } - - httpClientPool = new HttpClientPool(); - httpClientPool.Client = new HttpClient(ClientHandler); - return httpClientPool; - } - - public void Dispose() - { - if (IsDispose) - { - return; - } - - IsDispose = true; - Pools.Enqueue(this); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientPool.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientPool.cs.meta deleted file mode 100644 index a1ac3bf..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/HttpClientPool.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: a78c441357d244d5ba490a13c89e1c50 -timeCreated: 1726023895 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs deleted file mode 100644 index ae756c5..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Fantasy.Pool; - -#if !FANTASY_WEBGL -namespace Fantasy.Http -{ - /// - /// 一个JsonRPC的接口 - /// - public interface IJsonRpcRequest : IPool - { - /// - /// 用于初始化这个Json对象 - /// - /// - /// - /// - void Init(string method, int id, params object[] @params); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs.meta deleted file mode 100644 index 9e01783..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 72a03580c619417b9f8f92d99938e371 -timeCreated: 1726023900 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/JsonHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/JsonHelper.cs deleted file mode 100644 index 2b10fab..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/JsonHelper.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using Newtonsoft.Json; -#pragma warning disable CS8603 - -namespace Fantasy.Helper -{ - /// - /// 提供操作 JSON 数据的辅助方法。 - /// - public static partial class JsonHelper - { - /// - /// 将对象序列化为 JSON 字符串。 - /// - /// 要序列化的对象类型。 - /// 要序列化的对象。 - /// 表示序列化对象的 JSON 字符串。 - public static string ToJson(this T t) - { - return JsonConvert.SerializeObject(t); - } - - /// - /// 反序列化 JSON 字符串为指定类型的对象。 - /// - /// 要反序列化的 JSON 字符串。 - /// 目标对象的类型。 - /// 是否使用反射进行反序列化(默认为 true)。 - /// 反序列化后的对象。 - public static object Deserialize(this string json, Type type, bool reflection = true) - { - return JsonConvert.DeserializeObject(json, type); - } - - /// - /// 反序列化 JSON 字符串为指定类型的对象。 - /// - /// 目标对象的类型。 - /// 要反序列化的 JSON 字符串。 - /// 反序列化后的对象。 - public static T Deserialize(this string json) - { - return JsonConvert.DeserializeObject(json); - } - - /// - /// 克隆对象,通过将对象序列化为 JSON,然后再进行反序列化。 - /// - /// 要克隆的对象类型。 - /// 要克隆的对象。 - /// 克隆后的对象。 - public static T Clone(T t) - { - return t.ToJson().Deserialize(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/NetworkHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/NetworkHelper.cs deleted file mode 100644 index 867ba91..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/NetworkHelper.cs +++ /dev/null @@ -1,445 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.NetworkInformation; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -#pragma warning disable CS8603 // Possible null reference return. - -// ReSharper disable InconsistentNaming - -namespace Fantasy.Helper -{ - /// - /// 提供网络操作相关的帮助方法。 - /// - public static partial class NetworkHelper - { - /// - /// 根据字符串获取一个IPEndPoint - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IPEndPoint GetIPEndPoint(string address) - { - try - { - var addressSplit = address.Split(':'); - if (addressSplit.Length != 2) - { - throw new FormatException("Invalid format"); - } - - var ipString = addressSplit[0]; - var portString = addressSplit[1]; - - if (!IPAddress.TryParse(ipString, out var ipAddress)) - { - throw new FormatException("Invalid IP address"); - } - - if (!int.TryParse(portString, out var port) || port < 0 || port > 65535) - { - throw new FormatException("Invalid port number"); - } - - return new IPEndPoint(ipAddress, port); - } - catch (Exception e) - { - Log.Error($"Error parsing IP and Port:{e.Message}"); - return null; - } - } - - /// - /// 克隆一个IPEndPoint - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IPEndPoint Clone(this EndPoint endPoint) - { - var ip = (IPEndPoint)endPoint; - return new IPEndPoint(ip.Address, ip.Port); - } - - /// - /// 比较两个IPEndPoint是否相等 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IPEndPointEquals(this EndPoint endPoint, IPEndPoint ipEndPoint) - { - var ip = (IPEndPoint)endPoint; - return ip.Address.Equals(ipEndPoint.Address) && ip.Port == ipEndPoint.Port; - } - - /// - /// 比较两个IPEndPoint是否相等 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IPEndPointEquals(this IPEndPoint endPoint, IPEndPoint ipEndPoint) - { - return endPoint.Address.Equals(ipEndPoint.Address) && endPoint.Port == ipEndPoint.Port; - } -#if !FANTASY_WEBGL - /// - /// 将SocketAddress写入到Byte[]中 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SocketAddressToByte(this SocketAddress socketAddress, byte[] buffer, int offset) - { - if (socketAddress == null) - { - throw new ArgumentNullException(nameof(socketAddress), "The SocketAddress cannot be null."); - } - - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer), "The buffer cannot be null."); - } - - if (buffer.Length < socketAddress.Size + offset + 8) - { - throw new ArgumentException( - "The buffer length is insufficient. It must be at least the size of the SocketAddress plus 8 bytes.", - nameof(buffer)); - } - - var span = buffer.AsSpan(offset); - var addressFamilyValue = (int)socketAddress.Family; - var socketAddressSizeValue = socketAddress.Size; - - Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(span), addressFamilyValue); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), 4), socketAddressSizeValue); - - for (var i = 0; i < socketAddress.Size - 2; i++) - { - Unsafe.Add(ref MemoryMarshal.GetReference(span), 8 + i) = socketAddress[i + 2]; - } - } - - /// - /// 将byre[]转换为SocketAddress - /// - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ByteToSocketAddress(byte[] buffer, int offset, out SocketAddress socketAddress) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer), "The buffer cannot be null."); - } - - if (buffer.Length < 8) - { - throw new ArgumentException("Buffer length is insufficient. It must be at least 8 bytes.", - nameof(buffer)); - } - - try - { - var span = buffer.AsSpan(offset); - ref var spanRef = ref MemoryMarshal.GetReference(span); - - var addressFamily = (AddressFamily)Unsafe.ReadUnaligned(ref spanRef); - var socketAddressSize = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, 4)); - - if (buffer.Length < offset + 8 + socketAddressSize) - { - throw new ArgumentException("Buffer length is insufficient for the given SocketAddress size.", - nameof(buffer)); - } - - socketAddress = new SocketAddress(addressFamily, socketAddressSize); - - for (var i = 0; i < socketAddressSize - 2; i++) - { - socketAddress[i + 2] = Unsafe.Add(ref spanRef, 8 + i); - } - - return 8 + offset + socketAddressSize; - } - catch (ArgumentNullException ex) - { - throw new InvalidOperationException("An argument provided to the method is null.", ex); - } - catch (ArgumentException ex) - { - throw new InvalidOperationException("An argument provided to the method is invalid.", ex); - } - catch (Exception ex) - { - throw new InvalidOperationException("An unexpected error occurred while processing the buffer.", ex); - } - } - - /// - /// 将ReadOnlyMemory转换为SocketAddress - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ByteToSocketAddress(ReadOnlyMemory buffer, int offset, out SocketAddress socketAddress) - { - if (buffer.Length < 8) - { - throw new ArgumentException("Buffer length is insufficient. It must be at least 8 bytes.", - nameof(buffer)); - } - - try - { - var span = buffer.Span.Slice(offset); - ref var spanRef = ref MemoryMarshal.GetReference(span); - - var addressFamily = (AddressFamily)Unsafe.ReadUnaligned(ref spanRef); - var socketAddressSize = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, 4)); - - if (buffer.Length < offset + 8 + socketAddressSize) - { - throw new ArgumentException("Buffer length is insufficient for the given SocketAddress size.", - nameof(buffer)); - } - - socketAddress = new SocketAddress(addressFamily, socketAddressSize); - - for (var i = 0; i < socketAddressSize - 2; i++) - { - socketAddress[i + 2] = Unsafe.Add(ref spanRef, 8 + i); - } - - return 8 + offset + socketAddressSize; - } - catch (ArgumentNullException ex) - { - throw new InvalidOperationException("An argument provided to the method is null.", ex); - } - catch (ArgumentException ex) - { - throw new InvalidOperationException("An argument provided to the method is invalid.", ex); - } - catch (Exception ex) - { - throw new InvalidOperationException("An unexpected error occurred while processing the buffer.", ex); - } - } - - /// - /// 根据SocketAddress获得IPEndPoint - /// - /// - /// - /// - public static IPEndPoint GetIPEndPoint(this SocketAddress socketAddress) - { - switch (socketAddress.Family) - { - case AddressFamily.InterNetwork: - { - var ipBytes = new byte[4]; - for (var i = 0; i < 4; i++) - { - ipBytes[i] = socketAddress[4 + i]; - } - - var port = (socketAddress[2] << 8) + socketAddress[3]; - var ip = new IPAddress(ipBytes); - return new IPEndPoint(ip, port); - } - case AddressFamily.InterNetworkV6: - { - var ipBytes = new byte[16]; - Span socketAddressSpan = stackalloc byte[28]; - - for (var i = 0; i < 28; i++) - { - socketAddressSpan[i] = socketAddress[i]; - } - - ref var spanRef = ref MemoryMarshal.GetReference(socketAddressSpan); - - for (var i = 0; i < 16; i++) - { - ipBytes[i] = Unsafe.Add(ref spanRef, 8 + i); - } - - var port = (Unsafe.Add(ref spanRef, 2) << 8) + Unsafe.Add(ref spanRef, 3); - var scopeId = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, 24)); - var ip = new IPAddress(ipBytes, scopeId); - return new IPEndPoint(ip, port); - } - default: - { - throw new NotSupportedException("Address family not supported."); - } - } - } -#endif - /// - /// 获取本机所有网络适配器的IP地址。 - /// - /// IP地址数组。 - public static string[] GetAddressIPs() - { - var list = new List(); - foreach (var networkInterface in NetworkInterface.GetAllNetworkInterfaces()) - { - // 仅考虑以太网类型的网络适配器 - if (networkInterface.NetworkInterfaceType != NetworkInterfaceType.Ethernet) - { - continue; - } - - foreach (var add in networkInterface.GetIPProperties().UnicastAddresses) - { - list.Add(add.Address.ToString()); - } - } - - return list.ToArray(); - } - - /// - /// 将主机名和端口号转换为 实例。 - /// - /// 主机名。 - /// 端口号。 - /// 实例。 - public static IPEndPoint ToIPEndPoint(string host, int port) - { - return new IPEndPoint(IPAddress.Parse(host), port); - } - - /// - /// 将地址字符串转换为 实例。 - /// - /// 地址字符串,格式为 "主机名:端口号"。 - /// 实例。 - public static IPEndPoint ToIPEndPoint(string address) - { - var index = address.LastIndexOf(':'); - var host = address.Substring(0, index); - var p = address.Substring(index + 1); - var port = int.Parse(p); - return ToIPEndPoint(host, port); - } - - /// - /// 将 实例转换为字符串表示形式。 - /// - /// 实例。 - /// 表示 的字符串。 - public static string IPEndPointToStr(this IPEndPoint self) - { - return $"{self.Address}:{self.Port}"; - } - - /// - /// 针对 Windows 平台设置UDP连接重置选项。 - /// - /// 要设置选项的 实例。 - public static void SetSioUdpConnReset(this Socket socket) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return; - } - - /* - 目前这个问题只有Windows下才会出现。 - 服务器端在发送数据时捕获到了一个异常, - 这个异常导致原因应该是远程客户端的UDP监听已停止导致数据发送出错。 - 按理说UDP是无连接的,报这个异常是不合理的 - 这个异常让整UDP的服务监听也停止了。 - 这样就因为一个客户端的数据发送无法到达而导致了服务挂了,所有客户端都无法与服务器通信了 - 想详细了解看下https://blog.csdn.net/sunzhen6251/article/details/124168805*/ - const uint IOC_IN = 0x80000000; - const uint IOC_VENDOR = 0x18000000; - const int SIO_UDP_CONNRESET = unchecked((int)(IOC_IN | IOC_VENDOR | 12)); - - socket.IOControl(SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null); - } - - /// - /// 将 Socket 缓冲区大小设置为操作系统限制。 - /// - /// 要设置缓冲区大小的 Socket。 - public static void SetSocketBufferToOsLimit(this Socket socket) - { - socket.SetReceiveBufferToOSLimit(); - socket.SetSendBufferToOSLimit(); - } - - /// - /// 将 Socket 接收缓冲区大小设置为操作系统限制。 - /// 尝试增加接收缓冲区大小的次数 = 默认 + 最大增加 100 MB。 - /// - /// 要设置接收缓冲区大小的 Socket。 - /// 每次增加的步长大小。 - /// 尝试增加缓冲区大小的次数。 - public static void SetReceiveBufferToOSLimit(this Socket socket, int stepSize = 1024, int attempts = 100_000) - { - // setting a too large size throws a socket exception. - // so let's keep increasing until we encounter it. - for (int i = 0; i < attempts; ++i) - { - // increase in 1 KB steps - try - { - socket.ReceiveBufferSize += stepSize; - } - catch (SocketException) - { - break; - } - } - } - - /// - /// 将 Socket 发送缓冲区大小设置为操作系统限制。 - /// 尝试增加发送缓冲区大小的次数 = 默认 + 最大增加 100 MB。 - /// - /// 要设置发送缓冲区大小的 Socket。 - /// 每次增加的步长大小。 - /// 尝试增加缓冲区大小的次数。 - public static void SetSendBufferToOSLimit(this Socket socket, int stepSize = 1024, int attempts = 100_000) - { - // setting a too large size throws a socket exception. - // so let's keep increasing until we encounter it. - for (var i = 0; i < attempts; ++i) - { - // increase in 1 KB steps - try - { - socket.SendBufferSize += stepSize; - } - catch (SocketException) - { - break; - } - } - } - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/RandomHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/RandomHelper.cs deleted file mode 100644 index b07ffb8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/RandomHelper.cs +++ /dev/null @@ -1,415 +0,0 @@ -#if FANTASY_NET || !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -namespace Fantasy.Helper -{ - /// - /// 随机数操作助手类,提供各种随机数生成和操作方法。 - /// - public static partial class RandomHelper - { - [ThreadStatic] - private static Random _random; - - /// - /// 生成一个随机的无符号 64 位整数。 - /// - /// 无符号 64 位整数。 - public static ulong RandUInt64() - { - var byte8 = new FixedBytes8().AsSpan(); - var random = _random ??= new Random(); - random.NextBytes(byte8); - return BitConverter.ToUInt64(byte8); - } - - /// - /// 生成一个随机的 64 位整数。 - /// - /// 64 位整数。 - public static long RandInt64() - { - var byte8 = new FixedBytes8().AsSpan(); - var random = _random ??= new Random(); - random.NextBytes(byte8); - return BitConverter.ToInt64(byte8); - } - - /// - /// 生成一个随机的无符号 32 位整数。 - /// - /// 无符号 32 位整数。 - public static uint RandUInt32() - { - var random = _random ??= new Random(); - return (uint) random.Next(); - } - - /// - /// 生成一个随机的无符号 16 位整数。 - /// - /// 无符号 16 位整数。 - public static ushort RandUInt16() - { - var byte2 = new FixedBytes2().AsSpan(); - var random = _random ??= new Random(); - random.NextBytes(byte2); - return BitConverter.ToUInt16(byte2); - } - - /// - /// 在指定范围内生成一个随机整数(包含下限,不包含上限)。 - /// - /// 下限。 - /// 上限。 - /// 生成的随机整数。 - public static int RandomNumber(int lower, int upper) - { - var random = _random ??= new Random(); - return random.Next(lower, upper); - } - - /// - /// 生成一个随机的布尔值。 - /// - /// 随机的布尔值。 - public static bool RandomBool() - { - var random = _random ??= new Random(); - return (random.Next() & 1) == 0; - } - - /// - /// 从数组中随机选择一个元素。 - /// - /// 数组元素的类型。 - /// 要选择的数组。 - /// 随机选择的数组元素。 - public static T RandomArray(this T[] array) - { - return array[RandomNumber(0, array.Count())]; - } - - /// - /// 从列表中随机选择一个元素。 - /// - /// 列表元素的类型。 - /// 要选择的列表。 - /// 随机选择的列表元素。 - public static T RandomArray(this List array) - { - return array[RandomNumber(0, array.Count())]; - } - - /// - /// 打乱列表中元素的顺序。 - /// - /// 列表元素的类型。 - /// 要打乱顺序的列表。 - public static void BreakRank(List arr) - { - if (arr == null || arr.Count < 2) - { - return; - } - - var random = _random ??= new Random(); - for (var i = 0; i < arr.Count / 2; i++) - { - var index = random.Next(0, arr.Count); - (arr[index], arr[arr.Count - index - 1]) = (arr[arr.Count - index - 1], arr[index]); - } - } - - /// - /// 生成一个介于 0 和 1 之间的随机单精度浮点数。 - /// - /// 随机单精度浮点数。 - public static float RandFloat01() - { - var random = _random ??= new Random(); - var value = random.NextDouble(); - return (float) value; - } - - private static int Rand(int n) - { - var rd = new Random(); - // 注意,返回值是左闭右开,所以maxValue要加1 - return rd.Next(1, n + 1); - } - - /// - /// 根据权重随机选择一个索引。 - /// - /// 权重数组,每个元素表示相应索引的权重。 - /// 随机选择的索引值。 - public static int RandomByWeight(int[] weights) - { - var sum = weights.Sum(); - var numberRand = Rand(sum); - var sumTemp = 0; - for (var i = 0; i < weights.Length; i++) - { - sumTemp += weights[i]; - if (numberRand <= sumTemp) - { - return i; - } - } - - return -1; - } - - /// - /// 根据固定概率随机选择一个索引,即某个数值上限内随机多少次。 - /// - /// 概率数组,每个元素表示相应索引的概率。 - /// 随机选择的索引值。 - public static int RandomByFixedProbability(int[] args) - { - var random = _random ??= new Random(); - var argCount = args.Length; - var sum = args.Sum(); - var value = random.NextDouble() * sum; - while (sum > value) - { - sum -= args[argCount - 1]; - argCount--; - } - - return argCount; - } - - /// - /// 返回随机数。 - /// - /// 是否包含负数。 - /// 返回一个随机的单精度浮点数。 - public static float NextFloat(bool containNegative = false) - { - var random = _random ??= new Random(); - float f; - var buffer = new FixedBytes4().AsSpan(); - if (containNegative) - { - do - { - random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer); - } while ((f >= float.MinValue && f < float.MaxValue) == false); - - return f; - } - - do - { - random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer); - } while ((f >= 0 && f < float.MaxValue) == false); - - return f; - } - - /// - /// 返回一个小于所指定最大值的非负随机数。 - /// - /// 要生成的随机数的上限(随机数不能取该上限值)。 maxValue 必须大于或等于零。 - /// 大于等于零且小于 maxValue 的单精度浮点数,即:返回值的范围通常包括零但不包括 maxValue。 不过,如果 maxValue 等于零,则返回 maxValue。 - public static float NextFloat(float maxValue) - { - if (maxValue.Equals(0)) - { - return maxValue; - } - - if (maxValue < 0) - { - throw new ArgumentOutOfRangeException("“maxValue”必须大于 0。", "maxValue"); - } - - var random = _random ??= new Random(); - float f; - var buffer = new FixedBytes4().AsSpan(); - - do - { - random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer); - } while ((f >= 0 && f < maxValue) == false); - - return f; - } - - /// - /// 返回一个指定范围内的随机数。 - /// - /// 返回的随机数的下界(随机数可取该下界值)。 - /// 返回的随机数的上界(随机数不能取该上界值)。 maxValue 必须大于或等于 minValue。 - /// 一个大于等于 minValue 且小于 maxValue 的单精度浮点数,即:返回的值范围包括 minValue 但不包括 maxValue。 如果 minValue 等于 maxValue,则返回 minValue。 - public static float NextFloat(float minValue, float maxValue) - { - if (minValue.Equals(maxValue)) - { - return minValue; - } - - if (minValue > maxValue) - { - throw new ArgumentOutOfRangeException("“minValue”不能大于 maxValue。", "minValue"); - } - - var random = _random ??= new Random(); - var buffer = new FixedBytes4().AsSpan(); - float f; - - do - { - random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer); - } while ((f >= minValue && f < maxValue) == false); - - return f; - } - - /// - /// 在指定的矩形区域内随机生成一个二维向量位置。 - /// - /// X轴最小值。 - /// X轴最大值。 - /// Y轴最小值。 - /// Y轴最大值。 - /// 随机生成的二维向量位置。 - public static Vector2 NextVector2(float minX, float maxX, float minY, float maxY) - { - return new Vector2(NextFloat(minX, maxX), NextFloat(minY, maxY)); - } - - /// - /// 生成指定长度的随机数字代码。 - /// - /// 数字代码的长度。 - /// 生成的随机数字代码。 - public static string RandomNumberCode(int len = 6) - { - int num = 0; - for (int i = 0; i < len; i++) - { - int number = RandomNumber(0, 10); - num = num * 10 + number; - } - - return num.ToString(); - } - } - - #region FixedBytes - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes1 - { - private byte _e0; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes2 - { - private FixedBytes1 _e0; - private FixedBytes1 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes4 - { - private FixedBytes2 _e0; - private FixedBytes2 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes8 - { - private FixedBytes4 _e0; - private FixedBytes4 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes16 - { - private FixedBytes8 _e0; - private FixedBytes8 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes32 - { - private FixedBytes16 _e0; - private FixedBytes16 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes64 - { - private FixedBytes32 _e0; - private FixedBytes32 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes128 - { - private FixedBytes64 _e0; - private FixedBytes64 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes256 - { - private FixedBytes128 _e0; - private FixedBytes128 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes512 - { - private FixedBytes256 _e0; - private FixedBytes256 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes1024 - { - private FixedBytes512 _e0; - private FixedBytes512 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - #endregion -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/RandomHelperWebgl.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/RandomHelperWebgl.cs deleted file mode 100644 index 0820acf..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/RandomHelperWebgl.cs +++ /dev/null @@ -1,295 +0,0 @@ -#if FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; - -namespace Fantasy.Helper -{ - /// - /// 随机数操作助手类,提供各种随机数生成和操作方法。 - /// - public static partial class RandomHelper - { - private static readonly Random Random = new Random(); - private static readonly byte[] Byte8 = new byte[8]; - private static readonly byte[] Byte2 = new byte[2]; - - /// - /// 生成一个随机的无符号 64 位整数。 - /// - /// 无符号 64 位整数。 - public static ulong RandUInt64() - { - Random.NextBytes(Byte8); - return BitConverter.ToUInt64(Byte8, 0); - } - - /// - /// 生成一个随机的 64 位整数。 - /// - /// 64 位整数。 - public static long RandInt64() - { - Random.NextBytes(Byte8); - return BitConverter.ToInt64(Byte8, 0); - } - - /// - /// 生成一个随机的无符号 32 位整数。 - /// - /// 无符号 32 位整数。 - public static uint RandUInt32() - { - return (uint) Random.Next(); - } - - /// - /// 生成一个随机的无符号 16 位整数。 - /// - /// 无符号 16 位整数。 - public static ushort RandUInt16() - { - Random.NextBytes(Byte2); - return BitConverter.ToUInt16(Byte2, 0); - } - - /// - /// 在指定范围内生成一个随机整数(包含下限,不包含上限)。 - /// - /// 下限。 - /// 上限。 - /// 生成的随机整数。 - public static int RandomNumber(int lower, int upper) - { - return Random.Next(lower, upper); - } - - /// - /// 生成一个随机的布尔值。 - /// - /// 随机的布尔值。 - public static bool RandomBool() - { - return Random.Next(2) == 0; - } - - /// - /// 从数组中随机选择一个元素。 - /// - /// 数组元素的类型。 - /// 要选择的数组。 - /// 随机选择的数组元素。 - public static T RandomArray(this T[] array) - { - return array[RandomNumber(0, array.Count())]; - } - - /// - /// 从列表中随机选择一个元素。 - /// - /// 列表元素的类型。 - /// 要选择的列表。 - /// 随机选择的列表元素。 - public static T RandomArray(this List array) - { - return array[RandomNumber(0, array.Count())]; - } - - /// - /// 打乱列表中元素的顺序。 - /// - /// 列表元素的类型。 - /// 要打乱顺序的列表。 - public static void BreakRank(List arr) - { - if (arr == null || arr.Count < 2) - { - return; - } - - for (var i = 0; i < arr.Count / 2; i++) - { - var index = Random.Next(0, arr.Count); - (arr[index], arr[arr.Count - index - 1]) = (arr[arr.Count - index - 1], arr[index]); - } - } - - /// - /// 生成一个介于 0 和 1 之间的随机单精度浮点数。 - /// - /// 随机单精度浮点数。 - public static float RandFloat01() - { - var value = Random.NextDouble(); - return (float) value; - } - - private static int Rand(int n) - { - var rd = new Random(); - // 注意,返回值是左闭右开,所以maxValue要加1 - return rd.Next(1, n + 1); - } - - /// - /// 根据权重随机选择一个索引。 - /// - /// 权重数组,每个元素表示相应索引的权重。 - /// 随机选择的索引值。 - public static int RandomByWeight(int[] weights) - { - var sum = weights.Sum(); - var numberRand = Rand(sum); - var sumTemp = 0; - for (var i = 0; i < weights.Length; i++) - { - sumTemp += weights[i]; - if (numberRand <= sumTemp) - { - return i; - } - } - - return -1; - } - - /// - /// 根据固定概率随机选择一个索引,即某个数值上限内随机多少次。 - /// - /// 概率数组,每个元素表示相应索引的概率。 - /// 随机选择的索引值。 - public static int RandomByFixedProbability(int[] args) - { - var argCount = args.Length; - var sum = args.Sum(); - var random = Random.NextDouble() * sum; - while (sum > random) - { - sum -= args[argCount - 1]; - argCount--; - } - - return argCount; - } - - /// - /// 返回随机数。 - /// - /// 是否包含负数。 - /// 返回一个随机的单精度浮点数。 - public static float NextFloat(bool containNegative = false) - { - float f; - var buffer = new byte[4]; - if (containNegative) - { - do - { - Random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer, 0); - } while ((f >= float.MinValue && f < float.MaxValue) == false); - - return f; - } - - do - { - Random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer, 0); - } while ((f >= 0 && f < float.MaxValue) == false); - - return f; - } - - /// - /// 返回一个小于所指定最大值的非负随机数。 - /// - /// 要生成的随机数的上限(随机数不能取该上限值)。 maxValue 必须大于或等于零。 - /// 大于等于零且小于 maxValue 的单精度浮点数,即:返回值的范围通常包括零但不包括 maxValue。 不过,如果 maxValue 等于零,则返回 maxValue。 - public static float NextFloat(float maxValue) - { - if (maxValue.Equals(0)) - { - return maxValue; - } - - if (maxValue < 0) - { - throw new ArgumentOutOfRangeException("“maxValue”必须大于 0。", "maxValue"); - } - - float f; - var buffer = new byte[4]; - - do - { - Random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer, 0); - } while ((f >= 0 && f < maxValue) == false); - - return f; - } - - /// - /// 返回一个指定范围内的随机数。 - /// - /// 返回的随机数的下界(随机数可取该下界值)。 - /// 返回的随机数的上界(随机数不能取该上界值)。 maxValue 必须大于或等于 minValue。 - /// 一个大于等于 minValue 且小于 maxValue 的单精度浮点数,即:返回的值范围包括 minValue 但不包括 maxValue。 如果 minValue 等于 maxValue,则返回 minValue。 - public static float NextFloat(float minValue, float maxValue) - { - if (minValue.Equals(maxValue)) - { - return minValue; - } - - if (minValue > maxValue) - { - throw new ArgumentOutOfRangeException("“minValue”不能大于 maxValue。", "minValue"); - } - - float f; - var buffer = new byte[4]; - - do - { - Random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer, 0); - } while ((f >= minValue && f < maxValue) == false); - - return f; - } - - /// - /// 在指定的矩形区域内随机生成一个二维向量位置。 - /// - /// X轴最小值。 - /// X轴最大值。 - /// Y轴最小值。 - /// Y轴最大值。 - /// 随机生成的二维向量位置。 - public static Vector2 NextVector2(float minX, float maxX, float minY, float maxY) - { - return new Vector2(NextFloat(minX, maxX), NextFloat(minY, maxY)); - } - - /// - /// 生成指定长度的随机数字代码。 - /// - /// 数字代码的长度。 - /// 生成的随机数字代码。 - public static string RandomNumberCode(int len = 6) - { - int num = 0; - for (int i = 0; i < len; i++) - { - int number = RandomNumber(0, 10); - num = num * 10 + number; - } - - return num.ToString(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/SocketHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/SocketHelper.cs deleted file mode 100644 index 15027c5..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/SocketHelper.cs +++ /dev/null @@ -1,74 +0,0 @@ -#if !FANTASY_WEBGL -using System.Net; -using System.Net.Sockets; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Helper -{ - /// - /// Socket帮助类 - /// - public static partial class SocketHelper - { - // always pass the same IPEndPointNonAlloc instead of allocating a new - // one each time. - // - // use IPEndPointNonAlloc.temp to get the latest SocketAdddress written - // by ReceiveFrom_Internal! - // - // IMPORTANT: .temp will be overwritten in next call! - // hash or manually copy it if you need to store it, e.g. - // when adding a new connection. - public static int ReceiveFrom_NonAlloc( - this Socket socket, - byte[] buffer, - int offset, - int size, - SocketFlags socketFlags, - EndPoint remoteEndPoint) - { - // call ReceiveFrom with IPEndPointNonAlloc. - // need to wrap this in ReceiveFrom_NonAlloc because it's not - // obvious that IPEndPointNonAlloc.Create does NOT create a new - // IPEndPoint. it saves the result in IPEndPointNonAlloc.temp! -#if FANTASY_UNITY - EndPoint casted = remoteEndPoint; - return socket.ReceiveFrom(buffer, offset, size, socketFlags, ref casted); -#else - return socket.ReceiveFrom(buffer, offset, size, socketFlags, ref remoteEndPoint); -#endif - } - - // same as above, different parameters - public static int ReceiveFrom_NonAlloc(this Socket socket, byte[] buffer, ref EndPoint remoteEndPoint) - { -#if UNITY - EndPoint casted = remoteEndPoint; - return socket.ReceiveFrom(buffer, ref casted); -#else - return socket.ReceiveFrom(buffer, ref remoteEndPoint); -#endif - - } - - // SendTo allocates too: - // https://github.com/mono/mono/blob/f74eed4b09790a0929889ad7fc2cf96c9b6e3757/mcs/class/System/System.Net.Sockets/Socket.cs#L2240 - // -> the allocation is in EndPoint.Serialize() - // NOTE: technically this function isn't necessary. - // could just pass IPEndPointNonAlloc. - // still good for strong typing. - //public static int SendTo_NonAlloc( - // this Socket socket, - // byte[] buffer, - // int offset, - // int size, - // SocketFlags socketFlags, - // IPEndPointNonAlloc remoteEndPoint) - //{ - // EndPoint casted = remoteEndPoint; - // return socket.SendTo(buffer, offset, size, socketFlags, casted); - //} - } -} -#endif - - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/TimeHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/TimeHelper.cs deleted file mode 100644 index b0eb60a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/TimeHelper.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -#if FANTASY_UNITY -using UnityEngine; -#endif - -namespace Fantasy.Helper -{ - /// - /// 提供与时间相关的帮助方法。 - /// - public static partial class TimeHelper - { - /// - /// 一小时的毫秒值。 - /// - public const long Hour = 3600000; - /// - /// 一分钟的毫秒值。 - /// - public const long Minute = 60000; - /// - /// 一天的毫秒值。 - /// - public const long OneDay = 86400000; - // 1970年1月1日的Ticks - private const long Epoch = 621355968000000000L; - /// - /// 获取当前时间的毫秒数,从1970年1月1日开始计算。 - /// - public static long Now => (DateTime.UtcNow.Ticks - Epoch) / 10000; -#if FANTASY_UNITY || FANTASY_CONSOLE - /// - /// 与服务器时间的偏差。 - /// - public static long TimeDiff; - /// - /// 获取当前服务器时间的毫秒数,加上与服务器时间的偏差。 - /// - public static long ServerNow => Now + TimeDiff; -#if FANTASY_UNITY - /// - /// 获取当前Unity运行的总时间的毫秒数。 - /// - public static long UnityNow => (long) (Time.time * 1000); -#endif -#endif - /// - /// 根据时间获取时间戳 - /// - public static long Transition(DateTime dateTime) - { - return (dateTime.ToUniversalTime().Ticks - Epoch) / 10000; - } - - /// - /// 根据时间获取 时间戳 - /// - public static long TransitionToSeconds(DateTime dateTime) - { - return (dateTime.ToUniversalTime().Ticks - Epoch) / 10000000; - } - - /// - /// 将毫秒数转换为日期时间。 - /// - /// 要转换的毫秒数。 - /// 转换后的日期时间。 - public static DateTime Transition(this long timeStamp) - { - return new DateTime(Epoch + timeStamp * 10000, DateTimeKind.Utc).ToUniversalTime(); - } - - /// - /// 将毫秒数转换为本地时间的日期时间。 - /// - /// 要转换的毫秒数。 - /// 转换后的本地时间的日期时间。 - public static DateTime TransitionLocal(this long timeStamp) - { - return new DateTime(Epoch + timeStamp * 10000, DateTimeKind.Utc).ToLocalTime(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs deleted file mode 100644 index dbc0334..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs +++ /dev/null @@ -1,244 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity -{ - /// - /// UnityWebRequest的帮助类 - /// - public static class UnityWebRequestHelper - { - /// - /// 获取一个文本 - /// - /// - /// - /// - public static FTask GetText(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequest.Get(url); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var text = unityWebRequest.downloadHandler.text; - task.SetResult(text); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - - /// - /// 获取一个Sprite - /// - /// - /// - /// - public static FTask GetSprite(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequestTexture.GetTexture(Uri.EscapeUriString(url)); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var texture = DownloadHandlerTexture.GetContent(unityWebRequest); - var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 5, 1f); - task.SetResult(sprite); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - - /// - /// 获取一个Texture - /// - /// - /// - /// - public static FTask GetTexture(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequestTexture.GetTexture(Uri.EscapeUriString(url)); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var texture = DownloadHandlerTexture.GetContent(unityWebRequest); - task.SetResult(texture); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - - /// - /// 获取Bytes - /// - /// - /// - /// - public static FTask GetBytes(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequest.Get(url); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var bytes = unityWebRequest.downloadHandler.data; - task.SetResult(bytes); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - - /// - /// 获取AssetBundle - /// - /// - /// - /// - public static FTask GetAssetBundle(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequestAssetBundle.GetAssetBundle(Uri.EscapeUriString(url)); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var assetBundle = DownloadHandlerAssetBundle.GetContent(unityWebRequest); - task.SetResult(assetBundle); - return; - } - - Log.Error(unityWebRequest.error); - task.SetResult(null); - }; - - return task; - } - - /// - /// 获取AudioClip - /// - /// - /// - /// - /// - public static FTask GetAudioClip(string url, AudioType audioType, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(Uri.EscapeUriString(url), audioType); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var audioClip = DownloadHandlerAudioClip.GetContent(unityWebRequest); - task.SetResult(audioClip); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs.meta b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs.meta deleted file mode 100644 index 53b7c3c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 4a679bf05117455388666f6d8cc35d7d -timeCreated: 1726022012 \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/WebSocketHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/WebSocketHelper.cs deleted file mode 100644 index 822db06..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/WebSocketHelper.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace Fantasy.Helper -{ - /// - /// WebSocket帮助类 - /// - public static partial class WebSocketHelper - { - /// - /// 根据字符串获取WebSocket的连接地址 - /// - /// 目标服务器地址格式为:127.0.0.1:2000 - /// 目标服务器是否为加密连接也就是https - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string GetWebSocketAddress(string address, bool isHttps) - { - var addressSplit = address.Split(':'); - if (addressSplit.Length != 2) - { - throw new FormatException("Invalid format"); - } - - var ipString = addressSplit[0]; - var portString = addressSplit[1]; - - if (!int.TryParse(portString, out var port) || port < 0 || port > 65535) - { - throw new FormatException("Invalid port number"); - } - - return isHttps ? $"wss://{ipString}:{portString}" : $"ws://{ipString}:{portString}"; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/WinPeriod.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/WinPeriod.cs deleted file mode 100644 index a1a5aca..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Helper/WinPeriod.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Fantasy.Helper -{ - /// - /// 精度设置 - /// - public static partial class WinPeriod - { - // 一般默认的精度不止1毫秒(不同操作系统有所不同),需要调用timeBeginPeriod与timeEndPeriod来设置精度 - [DllImport("winmm")] - private static extern void timeBeginPeriod(int t); - /// - /// 针对Windows平台设置精度 - /// - public static void Initialize() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - timeBeginPeriod(1); - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Default/EntityIdStruct.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Default/EntityIdStruct.cs deleted file mode 100644 index ef30b18..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Default/EntityIdStruct.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.IdFactory -{ - /// - /// 表示一个唯一实体的ID。 - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct EntityIdStruct - { - // EntityId:39 + 16 + 18 = 64 - // +-------------------+-----------------------------+------------------------------------+ - // | time(30) 最大34年 | SceneId(16) 最多65535个Scene | sequence(18) 每秒每个进程能生产262143个 - // +-------------------+-----------------------------+------------------------------------+ - public uint Time { get; set; } - public uint SceneId { get; set; } - public uint Sequence { get; set; } - - public const uint MaskSequence = 0x3FFFF; - public const uint MaskSceneId = 0xFFFF; - public const uint MaskTime = 0x3FFFFFFF; - - /// - /// WorldEntityIdStruct(如果超过下面参数的设定该ID会失效)。 - /// - /// time不能超过1073741823 - /// sceneId不能超过65535 - /// sequence不能超过262143 - public EntityIdStruct(uint time, uint sceneId, uint sequence) - { - // 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。 - Time = time; - SceneId = sceneId; - Sequence = sequence; - } - - public static implicit operator long(EntityIdStruct entityIdStruct) - { - ulong result = 0; - result |= entityIdStruct.Sequence; - result |= (ulong)entityIdStruct.SceneId << 18; - result |= (ulong)entityIdStruct.Time << 34; - return (long)result; - } - - public static implicit operator EntityIdStruct(long entityId) - { - var result = (ulong) entityId; - var entityIdStruct = new EntityIdStruct - { - Sequence = (uint)(result & MaskSequence) - }; - result >>= 18; - entityIdStruct.SceneId = (uint)(result & MaskSceneId); - result >>= 16; - entityIdStruct.Time = (uint)(result & MaskTime); - return entityIdStruct; - } - } - - public sealed class EntityIdFactory : IEntityIdFactory - { - private readonly ushort _sceneId; - - private uint _lastTime; - private uint _lastSequence; - private static readonly long Epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; - private static readonly long EpochThisYear = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000 - Epoch1970; - - private EntityIdFactory() { } - - public EntityIdFactory(uint sceneId) - { - switch (sceneId) - { - case > 65535: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255"); - } - default: - { - _sceneId = (ushort)sceneId; - break; - } - } - } - - public long Create - { - get - { - var time = (uint)((TimeHelper.Now - EpochThisYear) / 1000); - - if (time > _lastTime) - { - _lastTime = time; - _lastSequence = 0; - } - else if (++_lastSequence > EntityIdStruct.MaskSequence - 1) - { - _lastTime++; - _lastSequence = 0; - } - - return new EntityIdStruct(time, _sceneId, _lastSequence); - } - } - } - - public sealed class EntityIdFactoryTool : IIdFactoryTool - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetTime(ref long entityId) - { - var result = (ulong)entityId >> 34; - return (uint)(result & EntityIdStruct.MaskTime); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetSceneId(ref long entityId) - { - var result = (ulong)entityId >> 18; - return (uint)(result & EntityIdStruct.MaskSceneId); - } - - public byte GetWorldId(ref long entityId) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Default/RuntimeIdStruct.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Default/RuntimeIdStruct.cs deleted file mode 100644 index a5d5e10..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Default/RuntimeIdStruct.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.IdFactory -{ - /// - /// 表示一个运行时的ID。 - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct RuntimeIdStruct - { - // RuntimeId:23 + 8 + 8 + 25 = 64 - // +-------------------+-----------------------------+--------------------------------------+ - // | time(23) 最大60天 | SceneId(16) 最多65535个Scene | sequence(25) 每秒每个进程能生产33554431个 - // +-------------------+-----------------------------+--------------------------------------+ - public uint Time { get; private set; } - public uint SceneId { get; private set; } - public uint Sequence { get; private set; } - - public const uint MaskSequence = 0x1FFFFFF; - public const uint MaskSceneId = 0xFFFF; - public const uint MaskTime = 0x7FFFFF; - - /// - /// RuntimeIdStruct(如果超过下面参数的设定该ID会失效)。 - /// - /// time不能超过8388607 - /// sceneId不能超过65535 - /// sequence不能超过33554431 - public RuntimeIdStruct(uint time, uint sceneId, uint sequence) - { - // 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。 - Time = time; - SceneId = sceneId; - Sequence = sequence; - } - - public static implicit operator long(RuntimeIdStruct runtimeIdStruct) - { - ulong result = runtimeIdStruct.Sequence; - result |= (ulong)runtimeIdStruct.SceneId << 25; - result |= (ulong)runtimeIdStruct.Time << 41; - return (long)result; - } - - public static implicit operator RuntimeIdStruct(long runtimeId) - { - var result = (ulong)runtimeId; - var runtimeIdStruct = new RuntimeIdStruct - { - Sequence = (uint)(result & MaskSequence) - }; - result >>= 25; - runtimeIdStruct.SceneId = (byte)(result & MaskSceneId); - result >>= 16; - runtimeIdStruct.Time = (uint)(result & MaskTime); - return runtimeIdStruct; - } - } - - public sealed class RuntimeIdFactory : IRuntimeIdFactory - { - private readonly uint _sceneId; - - private uint _lastTime; - private uint _lastSequence; - private readonly long _epochNow; - private readonly long _epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; - - private RuntimeIdFactory() { } - - public RuntimeIdFactory(uint sceneId) : this(TimeHelper.Now, sceneId) { } - - public RuntimeIdFactory(long epochNow, uint sceneId) - { - switch (sceneId) - { - case > 65535: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255"); - } - default: - { - _sceneId = (ushort)sceneId; - _epochNow = epochNow - _epoch1970; - break; - } - } - } - - public long Create - { - get - { - var time = (uint)((TimeHelper.Now - _epochNow) / 1000); - - if (time > _lastTime) - { - _lastTime = time; - _lastSequence = 0; - } - else if (++_lastSequence > RuntimeIdStruct.MaskSequence - 1) - { - _lastTime++; - _lastSequence = 0; - } - - return new RuntimeIdStruct(time, _sceneId, _lastSequence); - } - } - } - - public sealed class RuntimeIdFactoryTool : IIdFactoryTool - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetTime(ref long runtimeId) - { - var result = (ulong)runtimeId >> 41; - return (uint)(result & RuntimeIdStruct.MaskTime); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetSceneId(ref long runtimeId) - { - var result = (ulong)runtimeId >> 25; - return (uint)(result & RuntimeIdStruct.MaskSceneId); - } - - public byte GetWorldId(ref long entityId) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/IdFactoryHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/IdFactoryHelper.cs deleted file mode 100644 index c60da0b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/IdFactoryHelper.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using Fantasy.Helper; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -namespace Fantasy.IdFactory -{ - /// - /// Id生成器帮助类 - /// - public static class IdFactoryHelper - { - private static IdFactoryType _idFactoryType = IdFactoryType.World; - - /// - /// EntityId工具 - /// - public static IIdFactoryTool EntityIdTool { get; private set; } = new WorldEntityIdFactoryTool(); - - /// - /// RuntimeId工具 - /// - public static IIdFactoryTool RuntimeIdTool { get; private set; } = new WorldRuntimeIdFactoryTool(); - - /// - /// 初始化 - /// - /// - public static void Initialize(IdFactoryType idFactoryType) - { - _idFactoryType = idFactoryType; - - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - EntityIdTool = new EntityIdFactoryTool(); - RuntimeIdTool = new RuntimeIdFactoryTool(); - return; - } - case IdFactoryType.World: - { - EntityIdTool = new WorldEntityIdFactoryTool(); - RuntimeIdTool = new WorldRuntimeIdFactoryTool(); - return; - } - } - } - - /// - /// 获得当前的IdFactoryType - /// - /// - public static IdFactoryType GetIdFactoryType() - { - return _idFactoryType; - } - - internal static IEntityIdFactory EntityIdFactory(uint sceneId, byte worldId) - { - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - return new EntityIdFactory(sceneId); - } - case IdFactoryType.World: - { - return new WorldEntityIdFactory(sceneId, worldId); - } - default: - { - throw new NotSupportedException($"IdFactoryType {_idFactoryType} is not supported."); - } - } - } - - internal static IRuntimeIdFactory RuntimeIdFactory(long epochNow, uint sceneId, byte worldId) - { - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - return new RuntimeIdFactory(sceneId); - } - case IdFactoryType.World: - { - if (epochNow == 0) - { - epochNow = TimeHelper.Now; - } - - return new WorldRuntimeIdFactory(epochNow, sceneId, worldId); - } - default: - { - throw new NotSupportedException($"IdFactoryType {_idFactoryType} is not supported."); - } - } - } - - internal static long EntityId(uint time, uint sceneId, byte wordId, uint sequence) - { - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - return new EntityIdStruct(time, sceneId, sequence); - } - case IdFactoryType.World: - { - return new WorldEntityIdStruct(time, sceneId, wordId, sequence); - } - default: - { - throw new NotSupportedException($"IdFactoryType {_idFactoryType} is not supported."); - } - } - } - - internal static long RuntimeId(uint time, uint sceneId, byte wordId, uint sequence) - { - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - return new RuntimeIdStruct(time, sceneId, sequence); - } - case IdFactoryType.World: - { - return new WorldRuntimeIdStruct(time, sceneId, wordId, sequence); - } - default: - { - throw new NotSupportedException($"IdFactoryType {_idFactoryType} is not supported."); - } - } - } - } -} - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/IdFactoryType.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/IdFactoryType.cs deleted file mode 100644 index d465b5b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/IdFactoryType.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Fantasy.IdFactory -{ - /// - /// ID生成器规则 - /// - public enum IdFactoryType - { - /// - /// 空。 - /// - None = 0, - /// - /// 默认生成器 - /// Scene最大为65535个。 - /// - Default = 1, - /// - /// ID中包含World,使用这种方式可以不用管理合区的ID重复的问题。 - /// 但Scene的数量也会限制到255个。 - /// - World = 2 - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Interface/IIdFactory.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Interface/IIdFactory.cs deleted file mode 100644 index d71c15b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Interface/IIdFactory.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Fantasy.IdFactory -{ - /// - /// EntityId生成器接口类 - /// - public interface IEntityIdFactory - { - /// - /// 创建一个新的Id - /// - public long Create { get; } - } - - /// - /// RuntimeId生成器接口类 - /// - public interface IRuntimeIdFactory - { - /// - /// 创建一个新的Id - /// - public long Create { get; } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Interface/IIdFactoryTool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Interface/IIdFactoryTool.cs deleted file mode 100644 index 8dd1e99..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/Interface/IIdFactoryTool.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Fantasy.IdFactory -{ - /// - /// Id扩展工具接口 - /// - public interface IIdFactoryTool - { - /// - /// 获得创建时间 - /// - /// - /// - public uint GetTime(ref long entityId); - /// - /// 获得SceneId - /// - /// - /// - public uint GetSceneId(ref long entityId); - /// - /// 获得WorldId - /// - /// - /// - public byte GetWorldId(ref long entityId); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/World/WorldEntityIdFactory.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/World/WorldEntityIdFactory.cs deleted file mode 100644 index dbba88f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/World/WorldEntityIdFactory.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.IdFactory -{ - /// - /// 表示一个唯一实体的ID。 - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct WorldEntityIdStruct - { - // EntityId:39 + 8 + 8 + 18 = 64 - // +-------------------+--------------------------+-----------------------+------------------------------------+ - // | time(30) 最大34年 | SceneId(8) 最多255个Scene | WordId(8) 最多255个世界 | sequence(18) 每秒每个进程能生产262143个 - // +-------------------+--------------------------+-----------------------+------------------------------------+ - public uint Time { get; private set; } - public uint SceneId { get; private set; } - public byte WordId { get; private set; } - public uint Sequence { get; private set; } - - public const uint MaskSequence = 0x3FFFF; - public const uint MaskSceneId = 0xFF; - public const uint MaskWordId = 0xFF; - public const uint MaskTime = 0x3FFFFFFF; - - /// - /// WorldEntityIdStruct(如果超过下面参数的设定该ID会失效)。 - /// - /// time不能超过1073741823 - /// sceneId不能超过255 - /// wordId不能超过255 - /// sequence不能超过262143 - public WorldEntityIdStruct(uint time, uint sceneId, byte wordId, uint sequence) - { - // 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。 - Time = time; - SceneId = sceneId; - WordId = wordId; - Sequence = sequence; - } - - public static implicit operator long(WorldEntityIdStruct entityIdStruct) - { - ulong result = 0; - result |= entityIdStruct.Sequence; - result |= (ulong)entityIdStruct.WordId << 18; - result |= (ulong)(entityIdStruct.SceneId % (entityIdStruct.WordId * 1000)) << 26; - result |= (ulong)entityIdStruct.Time << 34; - return (long)result; - } - - public static implicit operator WorldEntityIdStruct(long entityId) - { - var result = (ulong) entityId; - var entityIdStruct = new WorldEntityIdStruct - { - Sequence = (uint)(result & MaskSequence) - }; - result >>= 18; - entityIdStruct.WordId = (byte)(result & MaskWordId); - result >>= 8; - entityIdStruct.SceneId = (uint)(result & MaskSceneId) + (uint)entityIdStruct.WordId * 1000; - result >>= 8; - entityIdStruct.Time = (uint)(result & MaskTime); - return entityIdStruct; - } - } - - public sealed class WorldEntityIdFactory : IEntityIdFactory - { - private readonly uint _sceneId; - private readonly byte _worldId; - - private uint _lastTime; - private uint _lastSequence; - private static readonly long Epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; - private static readonly long EpochThisYear = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000 - Epoch1970; - - private WorldEntityIdFactory() { } - - public WorldEntityIdFactory(uint sceneId, byte worldId) - { - switch (sceneId) - { - case > 255255: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255"); - } - case < 1001: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be less than 1001"); - } - default: - { - _sceneId = sceneId; - _worldId = worldId; - break; - } - } - } - - public long Create - { - get - { - var time = (uint)((TimeHelper.Now - EpochThisYear) / 1000); - - if (time > _lastTime) - { - _lastTime = time; - _lastSequence = 0; - } - else if (++_lastSequence > WorldEntityIdStruct.MaskSequence - 1) - { - _lastTime++; - _lastSequence = 0; - } - - return new WorldEntityIdStruct(time, _sceneId, _worldId, _lastSequence); - } - } - } - - public sealed class WorldEntityIdFactoryTool : IIdFactoryTool - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetTime(ref long entityId) - { - var result = (ulong)entityId >> 34; - return (uint)(result & WorldEntityIdStruct.MaskTime); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetSceneId(ref long entityId) - { - var result = (ulong)entityId >> 18; - var worldId = (uint)(result & WorldEntityIdStruct.MaskWordId) * 1000; - result >>= 8; - return (uint)(result & WorldEntityIdStruct.MaskSceneId) + worldId; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public byte GetWorldId(ref long entityId) - { - var result = (ulong)entityId >> 18; - return (byte)(result & WorldEntityIdStruct.MaskWordId); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/World/WorldRuntimeIdFactory.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/World/WorldRuntimeIdFactory.cs deleted file mode 100644 index a5d582b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/IdFactory/World/WorldRuntimeIdFactory.cs +++ /dev/null @@ -1,155 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.IdFactory -{ - /// - /// 表示一个运行时的ID。 - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct WorldRuntimeIdStruct - { - // RuntimeId:23 + 8 + 8 + 25 = 64 - // +-------------------+--------------------------+-----------------------+--------------------------------------+ - // | time(23) 最大60天 | SceneId(8) 最多255个Scene | WordId(8) 最多255个世界 | sequence(25) 每秒每个进程能生产33554431个 - // +-------------------+--------------------------+-----------------------+--------------------------------------+ - public uint Time { get; private set; } - public uint SceneId { get; private set; } - public byte WordId { get; private set; } - public uint Sequence { get; private set; } - - public const uint MaskSequence = 0x1FFFFFF; - public const uint MaskSceneId = 0xFF; - public const uint MaskWordId = 0xFF; - public const uint MaskTime = 0x7FFFFF; - - /// - /// WorldRuntimeIdStruct(如果超过下面参数的设定该ID会失效)。 - /// - /// time不能超过8388607 - /// sceneId不能超过255 - /// wordId不能超过255 - /// sequence不能超过33554431 - public WorldRuntimeIdStruct(uint time, uint sceneId, byte wordId, uint sequence) - { - // 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。 - Time = time; - SceneId = sceneId; - WordId = wordId; - Sequence = sequence; - } - - public static implicit operator long(WorldRuntimeIdStruct runtimeIdStruct) - { - ulong result = runtimeIdStruct.Sequence; - result |= (ulong)runtimeIdStruct.WordId << 25; - result |= (ulong)(runtimeIdStruct.SceneId % (runtimeIdStruct.WordId * 1000)) << 33; - result |= (ulong)runtimeIdStruct.Time << 41; - return (long)result; - } - - public static implicit operator WorldRuntimeIdStruct(long runtimeId) - { - var result = (ulong)runtimeId; - var runtimeIdStruct = new WorldRuntimeIdStruct - { - Sequence = (uint)(result & MaskSequence) - }; - result >>= 25; - runtimeIdStruct.WordId = (byte)(result & MaskWordId); - result >>= 8; - runtimeIdStruct.SceneId = (uint)(result & MaskSceneId) + (uint)runtimeIdStruct.WordId * 1000; - result >>= 8; - runtimeIdStruct.Time = (uint)(result & MaskTime); - return runtimeIdStruct; - } - } - - public sealed class WorldRuntimeIdFactory : IRuntimeIdFactory - { - private readonly uint _sceneId; - private readonly byte _worldId; - - private uint _lastTime; - private uint _lastSequence; - private readonly long _epochNow; - private readonly long _epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; - - private WorldRuntimeIdFactory() { } - - public WorldRuntimeIdFactory(uint sceneId, byte worldId) : this(TimeHelper.Now, sceneId, worldId) { } - - public WorldRuntimeIdFactory(long epochNow, uint sceneId, byte worldId) - { - switch (sceneId) - { - case > 255255: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255"); - } - case < 1001: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be less than 1001"); - } - default: - { - _sceneId = sceneId; - _worldId = worldId; - _epochNow = epochNow - _epoch1970; - break; - } - } - } - - public long Create - { - get - { - var time = (uint)((TimeHelper.Now - _epochNow) / 1000); - - if (time > _lastTime) - { - _lastTime = time; - _lastSequence = 0; - } - else if (++_lastSequence > WorldRuntimeIdStruct.MaskSequence - 1) - { - _lastTime++; - _lastSequence = 0; - } - - return new WorldRuntimeIdStruct(time, _sceneId, _worldId, _lastSequence); - } - } - } - - public sealed class WorldRuntimeIdFactoryTool : IIdFactoryTool - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetTime(ref long runtimeId) - { - var result = (ulong)runtimeId >> 41; - return (uint)(result & WorldRuntimeIdStruct.MaskTime); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetSceneId(ref long runtimeId) - { - var result = (ulong)runtimeId >> 25; - var worldId = (uint)(result & WorldRuntimeIdStruct.MaskWordId) * 1000; - result >>= 8; - return (uint)(result & WorldRuntimeIdStruct.MaskSceneId) + worldId; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public byte GetWorldId(ref long runtimeId) - { - var result = (ulong)runtimeId >> 25; - return (byte)(result & WorldRuntimeIdStruct.MaskWordId); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/InnerErrorCode.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/InnerErrorCode.cs deleted file mode 100644 index e549a22..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/InnerErrorCode.cs +++ /dev/null @@ -1,66 +0,0 @@ -namespace Fantasy.Network -{ - /// - /// 定义 Fantasy 框架中的内部错误代码。 - /// - public class InnerErrorCode - { - private InnerErrorCode() { } - /// - /// 表示 Rpc 消息发送失败的错误代码。 - /// - public const uint ErrRpcFail = 100000002; - /// - /// 表示未找到 Route 消息的错误代码。 - /// - public const uint ErrNotFoundRoute = 100000003; - /// - /// 表示发送 Route 消息超时的错误代码。 - /// - public const uint ErrRouteTimeout = 100000004; - /// - /// 表示未找到实体的错误代码。 - /// - public const uint ErrEntityNotFound = 100000008; - /// - /// 表示传送过程中发生错误的错误代码。 - /// - public const uint ErrTransfer = 100000009; - /// - /// 表示连接Roaming时候已经存在同RoamingType的Roaming了。 - /// - public const uint ErrLinkRoamingAlreadyExists = 100000009; - /// - /// 表示连接Roaming时候在漫游终端已经存在同Id的终端。 - /// - public const uint ErrAddRoamingTerminalAlreadyExists = 100000010; - /// - /// 表示未找到 Roaming 消息的错误代码。 - /// - public const uint ErrNotFoundRoaming = 100000011; - /// - /// 表示发送 Roaming 消息超时的错误代码。 - /// - public const uint ErrRoamingTimeout = 100000012; - /// - /// 表示再锁定 Roaming 消息的时候没有找到对应的Session错误代码。 - /// - public const uint ErrLockTerminusIdNotFoundSession = 100000013; - /// - /// 表示再锁定 Roaming 消息的时候没有找到对应的RoamingType错误代码。 - /// - public const uint ErrLockTerminusIdNotFoundRoamingType = 100000014; - /// - /// 表示再解除锁定 Roaming 消息的时候没有找到对应的Session错误代码。 - /// - public const uint ErrUnLockTerminusIdNotFoundSession = 100000015; - /// - /// 表示再解除锁定 Roaming 消息的时候没有找到对应的RoamingType错误代码。 - /// - public const uint ErrUnLockTerminusIdNotFoundRoamingType = 100000016; - /// - /// 表示再传送 Terminus 时对应的错误代码。 - /// - public const uint ErrTerminusStartTransfer = 100000017; - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/ConsoleLog.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/ConsoleLog.cs deleted file mode 100644 index 0d57e22..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/ConsoleLog.cs +++ /dev/null @@ -1,144 +0,0 @@ -#if FANTASY_NET -using Fantasy.Platform.Net; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy; - -/// -/// 标准的控制台Log -/// -public sealed class ConsoleLog : ILog -{ - /// - /// 初始化方法 - /// - /// - public void Initialize(ProcessMode processMode) { } - - /// - /// 记录跟踪级别的日志消息。 - /// - /// 日志消息。 - public void Trace(string message) - { - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(message); - } - - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - public void Warning(string message) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine(message); - } - - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - public void Info(string message) - { - Console.ForegroundColor = ConsoleColor.Gray; - Console.WriteLine(message); - } - - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - public void Debug(string message) - { - Console.ForegroundColor = ConsoleColor.DarkGreen; - Console.WriteLine(message); - } - - /// - /// 记录错误级别的日志消息。 - /// - /// 日志消息。 - public void Error(string message) - { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.WriteLine(message); - } - - /// - /// 记录严重错误级别的日志消息。 - /// - /// 日志消息。 - public void Fatal(string message) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(message); - } - - /// - /// 记录跟踪级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Trace(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(message, args); - } - - /// - /// 记录警告级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Warning(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine(message, args); - } - - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Info(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.Gray; - Console.WriteLine(message, args); - } - - /// - /// 记录调试级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Debug(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.DarkGreen; - Console.WriteLine(message, args); - } - - /// - /// 记录错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Error(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.WriteLine(message, args); - } - - /// - /// 记录严重错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Fatal(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(message, args); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/ILog.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/ILog.cs deleted file mode 100644 index b01e857..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/ILog.cs +++ /dev/null @@ -1,74 +0,0 @@ -#if FANTASY_NET -using Fantasy.Platform.Net; -#endif -namespace Fantasy -{ - /// - /// 定义日志记录功能的接口。 - /// - public interface ILog - { -#if FANTASY_NET - /// - /// 初始化 - /// - /// - void Initialize(ProcessMode processMode); -#endif - /// - /// 记录跟踪级别的日志消息。 - /// - /// 日志消息。 - void Trace(string message); - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - void Warning(string message); - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - void Info(string message); - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - void Debug(string message); - /// - /// 记录错误级别的日志消息。 - /// - /// 日志消息。 - void Error(string message); - /// - /// 记录跟踪级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Trace(string message, params object[] args); - /// - /// 记录警告级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Warning(string message, params object[] args); - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Info(string message, params object[] args); - /// - /// 记录调试级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Debug(string message, params object[] args); - /// - /// 记录错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Error(string message, params object[] args); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/Log.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/Log.cs deleted file mode 100644 index 3b9cc15..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/Log.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System; -using System.Diagnostics; -#if FANTASY_NET -using Fantasy.Platform.Net; -#endif - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy -{ - /// - /// 提供日志记录功能的静态类。 - /// - public static class Log - { - private static ILog _logCore; - private static bool _isRegister; -#if FANTASY_NET - /// - /// 初始化Log系统 - /// - public static void Initialize() - { - if (!_isRegister) - { - Register(new ConsoleLog()); - return; - } - - _logCore.Initialize(ProgramDefine.RuntimeMode); - } -#endif - /// - /// 注册一个日志系统 - /// - /// - public static void Register(ILog log) - { - if (_isRegister) - { - return; - } - - _logCore = log; - _isRegister = true; - } - - /// - /// 记录跟踪级别的日志消息。 - /// - /// 日志消息。 - public static void Trace(string msg) - { - var st = new StackTrace(1, true); - _logCore.Trace($"{msg}\n{st}"); - } - - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - public static void Debug(string msg) - { - _logCore.Debug(msg); - } - - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - public static void Info(string msg) - { - _logCore.Info(msg); - } - - /// - /// 记录跟踪级别的日志消息,并附带调用栈信息。 - /// - /// 日志消息。 - public static void TraceInfo(string msg) - { - var st = new StackTrace(1, true); - _logCore.Trace($"{msg}\n{st}"); - } - - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - public static void Warning(string msg) - { - _logCore.Warning(msg); - } - - /// - /// 记录错误级别的日志消息,并附带调用栈信息。 - /// - /// 日志消息。 - public static void Error(string msg) - { - var st = new StackTrace(1, true); - _logCore.Error($"{msg}\n{st}"); - } - - /// - /// 记录异常的错误级别的日志消息,并附带调用栈信息。 - /// - /// 异常对象。 - public static void Error(Exception e) - { - if (e.Data.Contains("StackTrace")) - { - _logCore.Error($"{e.Data["StackTrace"]}\n{e}"); - return; - } - var str = e.ToString(); - _logCore.Error(str); - } - - /// - /// 记录跟踪级别的格式化日志消息,并附带调用栈信息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Trace(string message, params object[] args) - { - var st = new StackTrace(1, true); - _logCore.Trace($"{string.Format(message, args)}\n{st}"); - } - - /// - /// 记录警告级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Warning(string message, params object[] args) - { - _logCore.Warning(string.Format(message, args)); - } - - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Info(string message, params object[] args) - { - _logCore.Info(string.Format(message, args)); - } - - /// - /// 记录调试级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Debug(string message, params object[] args) - { - _logCore.Debug(string.Format(message, args)); - } - - /// - /// 记录错误级别的格式化日志消息,并附带调用栈信息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Error(string message, params object[] args) - { - var st = new StackTrace(1, true); - var s = string.Format(message, args) + '\n' + st; - _logCore.Error(s); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/UnityLog.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/UnityLog.cs deleted file mode 100644 index df95444..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Log/UnityLog.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Collections.Generic; -#if UNITY_EDITOR -using System; -using System.Reflection; -using System.Text.RegularExpressions; -using UnityEditor; -using UnityEditor.Callbacks; -using UnityEditorInternal; -#else -using System; -#endif - -#if FANTASY_UNITY -namespace Fantasy -{ - public class UnityLog : ILog - { - public void Trace(string msg) - { - UnityEngine.Debug.Log(msg); - } - - public void Debug(string msg) - { - UnityEngine.Debug.Log(msg); - } - - public void Info(string msg) - { - UnityEngine.Debug.Log(msg); - } - - public void Warning(string msg) - { - UnityEngine.Debug.LogWarning(msg); - } - - public void Error(string msg) - { - UnityEngine.Debug.LogError(msg); - } - - public void Error(Exception e) - { - UnityEngine.Debug.LogException(e); - } - - public void Trace(string message, params object[] args) - { - UnityEngine.Debug.LogFormat(message, args); - } - - public void Warning(string message, params object[] args) - { - UnityEngine.Debug.LogWarningFormat(message, args); - } - - public void Info(string message, params object[] args) - { - UnityEngine.Debug.LogFormat(message, args); - } - - public void Debug(string message, params object[] args) - { - UnityEngine.Debug.LogFormat(message, args); - } - - public void Error(string message, params object[] args) - { - UnityEngine.Debug.LogErrorFormat(message, args); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableHelper.cs deleted file mode 100644 index 098ba8a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableHelper.cs +++ /dev/null @@ -1,141 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Platform.Net; -namespace Fantasy.Network.Route -{ - /// - /// 提供操作地址映射的辅助方法。 - /// - public static class AddressableHelper - { - // 声明一个私有静态只读列表 AddressableScenes,用于存储地址映射的场景配置信息 - private static readonly List AddressableScenes = new List(); - - static AddressableHelper() - { - // 遍历场景配置信息,筛选出地址映射类型的场景,并添加到 AddressableScenes 列表中 - foreach (var sceneConfig in SceneConfigData.Instance.List) - { - if (sceneConfig.SceneTypeString == "Addressable") - { - AddressableScenes.Add(new AddressableScene(sceneConfig)); - } - } - } - - /// - /// 添加地址映射并返回操作结果。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - /// 路由 ID。 - /// 是否锁定。 - public static async FTask AddAddressable(Scene scene, long addressableId, long routeId, bool isLock = true) - { - // 获取指定索引的地址映射场景配置信息 - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - // 调用内部路由方法,发送添加地址映射的请求并等待响应 - var response = await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableAdd_Request - { - AddressableId = addressableId, RouteId = routeId, IsLock = isLock - }); - if (response.ErrorCode != 0) - { - Log.Error($"AddAddressable error is {response.ErrorCode}"); - } - } - - /// - /// 获取地址映射的路由 ID。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - /// 地址映射的路由 ID。 - public static async FTask GetAddressableRouteId(Scene scene, long addressableId) - { - // 获取指定索引的地址映射场景配置信息 - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - // 调用内部路由方法,发送获取地址映射路由 ID 的请求并等待响应 - var response = (I_AddressableGet_Response) await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableGet_Request - { - AddressableId = addressableId - }); - // 检查响应错误码,如果为零,返回路由 ID;否则,输出错误信息并返回 0 - if (response.ErrorCode == 0) - { - return response.RouteId; - } - - Log.Error($"GetAddressable error is {response.ErrorCode} addressableId:{addressableId}"); - return 0; - } - - /// - /// 移除指定地址映射。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - public static async FTask RemoveAddressable(Scene scene, long addressableId) - { - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - var response = await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableRemove_Request - { - AddressableId = addressableId - }); - - if (response.ErrorCode != 0) - { - Log.Error($"RemoveAddressable error is {response.ErrorCode}"); - } - } - - /// - /// 锁定指定地址映射。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - public static async FTask LockAddressable(Scene scene, long addressableId) - { - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - var response = await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableLock_Request - { - AddressableId = addressableId - }); - - if (response.ErrorCode != 0) - { - Log.Error($"LockAddressable error is {response.ErrorCode}"); - } - } - - /// - /// 解锁指定地址映射。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - /// 路由 ID。 - /// 解锁来源。 - public static async FTask UnLockAddressable(Scene scene, long addressableId, long routeId, string source) - { - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - var response = await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableUnLock_Request - { - AddressableId = addressableId, - RouteId = routeId, - Source = source - }); - - if (response.ErrorCode != 0) - { - Log.Error($"UnLockAddressable error is {response.ErrorCode}"); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableManageComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableManageComponent.cs deleted file mode 100644 index 8d08f08..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableManageComponent.cs +++ /dev/null @@ -1,144 +0,0 @@ -#if FANTASY_NET -using System; -using System.Collections.Generic; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network.Route -{ - public class AddressableManageComponentAwakeSystem : AwakeSystem - { - protected override void Awake(AddressableManageComponent self) - { - self.AddressableLock = self.Scene.CoroutineLockComponent.Create(self.GetType().TypeHandle.Value.ToInt64()); - } - } - - public class AddressableManageComponentDestroySystem : DestroySystem - { - protected override void Destroy(AddressableManageComponent self) - { - foreach (var (_, waitCoroutineLock) in self.Locks) - { - waitCoroutineLock.Dispose(); - } - - self.Locks.Clear(); - self.Addressable.Clear(); - self.AddressableLock.Dispose(); - self.AddressableLock = null; - } - } - - public sealed class AddressableManageComponent : Entity - { - public CoroutineLock AddressableLock; - public readonly Dictionary Addressable = new(); - public readonly Dictionary Locks = new(); - - /// - /// 添加地址映射。 - /// - /// 地址映射的唯一标识。 - /// 路由 ID。 - /// 是否进行锁定。 - public async FTask Add(long addressableId, long routeId, bool isLock) - { - WaitCoroutineLock waitCoroutineLock = null; - - try - { - if (isLock) - { - waitCoroutineLock = await AddressableLock.Wait(addressableId); - } - - Addressable[addressableId] = routeId; -#if FANTASY_DEVELOP - Log.Debug($"AddressableManageComponent Add addressableId:{addressableId} routeId:{routeId}"); -#endif - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - waitCoroutineLock?.Dispose(); - } - } - - /// - /// 获取地址映射的路由 ID。 - /// - /// 地址映射的唯一标识。 - /// 地址映射的路由 ID。 - public async FTask Get(long addressableId) - { - using (await AddressableLock.Wait(addressableId)) - { - Addressable.TryGetValue(addressableId, out var routeId); - return routeId; - } - } - - /// - /// 移除地址映射。 - /// - /// 地址映射的唯一标识。 - public async FTask Remove(long addressableId) - { - using (await AddressableLock.Wait(addressableId)) - { - Addressable.Remove(addressableId); -#if FANTASY_DEVELOP - Log.Debug($"Addressable Remove addressableId: {addressableId} _addressable:{Addressable.Count}"); -#endif - } - } - - /// - /// 锁定地址映射。 - /// - /// 地址映射的唯一标识。 - public async FTask Lock(long addressableId) - { - var waitCoroutineLock = await AddressableLock.Wait(addressableId); - Locks.Add(addressableId, waitCoroutineLock); - } - - /// - /// 解锁地址映射。 - /// - /// 地址映射的唯一标识。 - /// 新的路由 ID。 - /// 解锁来源。 - public void UnLock(long addressableId, long routeId, string source) - { - if (!Locks.Remove(addressableId, out var coroutineLock)) - { - Log.Error($"Addressable unlock not found addressableId: {addressableId} Source:{source}"); - return; - } - - Addressable.TryGetValue(addressableId, out var oldAddressableId); - - if (routeId != 0) - { - Addressable[addressableId] = routeId; - } - - coroutineLock.Dispose(); -#if FANTASY_DEVELOP - Log.Debug($"Addressable UnLock key: {addressableId} oldAddressableId : {oldAddressableId} routeId: {routeId} Source:{source}"); -#endif - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableMessageComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableMessageComponent.cs deleted file mode 100644 index 03e0def..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableMessageComponent.cs +++ /dev/null @@ -1,91 +0,0 @@ -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - public class AddressableMessageComponentDestroySystem : DestroySystem - { - protected override void Destroy(AddressableMessageComponent self) - { - if (self.AddressableId != 0) - { - AddressableHelper.RemoveAddressable(self.Scene, self.AddressableId).Coroutine(); - self.AddressableId = 0; - } - } - } - - /// - /// 可寻址消息组件、挂载了这个组件可以接收Addressable消息 - /// - public sealed class AddressableMessageComponent : Entity - { - /// - /// 可寻址消息组件的唯一标识。 - /// - public long AddressableId; - - /// - /// 注册可寻址消息组件。 - /// - /// 是否进行锁定。 - public FTask Register(bool isLock = true) - { - if (Parent == null) - { - throw new Exception("AddressableRouteComponent must be mounted under a component"); - } - - AddressableId = Parent.Id; - - if (AddressableId == 0) - { - throw new Exception("AddressableRouteComponent.Parent.Id is null"); - } - -#if FANTASY_DEVELOP - Log.Debug($"AddressableMessageComponent Register addressableId:{AddressableId} RouteId:{Parent.RouteId}"); -#endif - return AddressableHelper.AddAddressable(Scene, AddressableId, Parent.RouteId, isLock); - } - - /// - /// 锁定可寻址消息组件。 - /// - public FTask Lock() - { -#if FANTASY_DEVELOP - Log.Debug($"AddressableMessageComponent Lock {Parent.Id}"); -#endif - return AddressableHelper.LockAddressable(Scene, Parent.Id); - } - - /// - /// 解锁可寻址消息组件。 - /// - /// 解锁来源。 - public FTask UnLock(string source) - { -#if FANTASY_DEVELOP - Log.Debug($"AddressableMessageComponent UnLock {Parent.Id} {Parent.RouteId}"); -#endif - return AddressableHelper.UnLockAddressable(Scene, Parent.Id, Parent.RouteId, source); - } - - /// - /// 锁定可寻址消息并且释放掉AddressableMessageComponent组件。 - /// 该方法不会自动取Addressable中心删除自己的信息。 - /// 用于传送或转移到其他服务器时使用 - /// - public async FTask LockAndRelease() - { - await Lock(); - AddressableId = 0; - Dispose(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableRouteComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableRouteComponent.cs deleted file mode 100644 index bf439d7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableRouteComponent.cs +++ /dev/null @@ -1,218 +0,0 @@ -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Scheduler; -using Fantasy.Timer; - -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - public class AddressableRouteComponentAwakeSystem : AwakeSystem - { - protected override void Awake(AddressableRouteComponent self) - { - ((Session)self.Parent).AddressableRouteComponent = self; - - var selfScene = self.Scene; - self.TimerComponent = selfScene.TimerComponent; - self.NetworkMessagingComponent = selfScene.NetworkMessagingComponent; - self.MessageDispatcherComponent = selfScene.MessageDispatcherComponent; - self.AddressableRouteLock = - selfScene.CoroutineLockComponent.Create(self.GetType().TypeHandle.Value.ToInt64()); - } - } - - public class AddressableRouteComponentDestroySystem : DestroySystem - { - protected override void Destroy(AddressableRouteComponent self) - { - self.AddressableRouteLock.Dispose(); - - self.AddressableRouteId = 0; - self.AddressableId = 0; - self.TimerComponent = null; - self.AddressableRouteLock = null; - self.NetworkMessagingComponent = null; - self.MessageDispatcherComponent = null; - } - } - - /// - /// 可寻址路由消息组件,挂载了这个组件可以接收和发送 Addressable 消息。 - /// - public sealed class AddressableRouteComponent : Entity - { - public long AddressableId; - public long AddressableRouteId; - public CoroutineLock AddressableRouteLock; - public TimerComponent TimerComponent; - public NetworkMessagingComponent NetworkMessagingComponent; - public MessageDispatcherComponent MessageDispatcherComponent; - - internal void Send(IAddressableRouteMessage message) - { - Call(message).Coroutine(); - } - - internal async FTask Send(Type requestType, APackInfo packInfo) - { - await Call(requestType, packInfo); - } - - internal async FTask Call(Type requestType, APackInfo packInfo) - { - if (IsDisposed) - { - return MessageDispatcherComponent.CreateResponse(requestType, InnerErrorCode.ErrNotFoundRoute); - } - - packInfo.IsDisposed = true; - var failCount = 0; - var runtimeId = RuntimeId; - IResponse iRouteResponse = null; - - try - { - using (await AddressableRouteLock.Wait(AddressableId, "AddressableRouteComponent Call MemoryStream")) - { - while (!IsDisposed) - { - if (AddressableRouteId == 0) - { - AddressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, AddressableId); - } - - if (AddressableRouteId == 0) - { - return MessageDispatcherComponent.CreateResponse(requestType, - InnerErrorCode.ErrNotFoundRoute); - } - - iRouteResponse = await NetworkMessagingComponent.CallInnerRoute(AddressableRouteId, requestType, packInfo); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRouteTimeout; - } - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrRouteTimeout: - { - return iRouteResponse; - } - case InnerErrorCode.ErrNotFoundRoute: - { - if (++failCount > 20) - { - Log.Error($"AddressableComponent.Call failCount > 20 route send message fail, routeId: {RouteId} AddressableRouteComponent:{Id}"); - return iRouteResponse; - } - - await TimerComponent.Net.WaitAsync(100); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRouteTimeout; - } - - AddressableRouteId = 0; - continue; - } - default: - { - return iRouteResponse; // 对于其他情况,直接返回响应,无需额外处理 - } - } - } - } - } - finally - { - packInfo.Dispose(); - } - - - return iRouteResponse; - } - - /// - /// 调用可寻址路由消息并等待响应。 - /// - /// 可寻址路由请求。 - private async FTask Call(IAddressableRouteMessage request) - { - if (IsDisposed) - { - return MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoute); - } - - var failCount = 0; - var runtimeId = RuntimeId; - - using (await AddressableRouteLock.Wait(AddressableId, "AddressableRouteComponent Call")) - { - while (true) - { - if (AddressableRouteId == 0) - { - AddressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, AddressableId); - } - - if (AddressableRouteId == 0) - { - return MessageDispatcherComponent.CreateResponse(request.GetType(), - InnerErrorCode.ErrNotFoundRoute); - } - - var iRouteResponse = await NetworkMessagingComponent.CallInnerRoute(AddressableRouteId, request); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRouteTimeout; - } - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrNotFoundRoute: - { - if (++failCount > 20) - { - Log.Error( - $"AddressableRouteComponent.Call failCount > 20 route send message fail, routeId: {RouteId} AddressableRouteComponent:{Id}"); - return iRouteResponse; - } - - await TimerComponent.Net.WaitAsync(500); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRouteTimeout; - } - - AddressableRouteId = 0; - continue; - } - case InnerErrorCode.ErrRouteTimeout: - { - return iRouteResponse; - } - default: - { - return iRouteResponse; - } - } - } - } - } - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableScene.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableScene.cs deleted file mode 100644 index 3105fca..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/AddressableScene.cs +++ /dev/null @@ -1,31 +0,0 @@ -#if FANTASY_NET -using Fantasy.IdFactory; -using Fantasy.Platform.Net; - -namespace Fantasy.Network.Route -{ - /// - /// AddressableScene - /// - public sealed class AddressableScene - { - /// - /// Id - /// - public readonly long Id; - /// - /// RunTimeId - /// - public readonly long RunTimeId; - /// - /// 构造方法 - /// - /// sceneConfig - public AddressableScene(SceneConfig sceneConfig) - { - Id = IdFactoryHelper.EntityId(0, sceneConfig.Id, (byte)sceneConfig.WorldConfigId, 0); - RunTimeId = IdFactoryHelper.RuntimeId(0, sceneConfig.Id, (byte)sceneConfig.WorldConfigId, 0); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableAddHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableAddHandler.cs deleted file mode 100644 index 847625b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableAddHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableAddHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableAddHandler : RouteRPC - { - /// - /// 在收到地址映射添加请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableAdd_Request 实例。 - /// 用于构建响应的 I_AddressableAdd_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableAdd_Request request, I_AddressableAdd_Response response, Action reply) - { - await scene.GetComponent().Add(request.AddressableId, request.RouteId, request.IsLock); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableGetHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableGetHandler.cs deleted file mode 100644 index f53c1f1..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableGetHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableGetHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableGetHandler : RouteRPC - { - /// - /// 在收到地址映射获取请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableGet_Request 实例。 - /// 用于构建响应的 I_AddressableGet_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableGet_Request request, I_AddressableGet_Response response, Action reply) - { - response.RouteId = await scene.GetComponent().Get(request.AddressableId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableLockHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableLockHandler.cs deleted file mode 100644 index b964274..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableLockHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableLockHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableLockHandler : RouteRPC - { - /// - /// 在收到地址映射锁定请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableLock_Request 实例。 - /// 用于构建响应的 I_AddressableLock_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableLock_Request request, I_AddressableLock_Response response, Action reply) - { - await scene.GetComponent().Lock(request.AddressableId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableRemoveHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableRemoveHandler.cs deleted file mode 100644 index c4e9654..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableRemoveHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableRemoveHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableRemoveHandler : RouteRPC - { - /// - /// 在收到地址映射移除请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableRemove_Request 实例。 - /// 用于构建响应的 I_AddressableRemove_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableRemove_Request request, I_AddressableRemove_Response response, Action reply) - { - await scene.GetComponent().Remove(request.AddressableId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableUnLockHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableUnLockHandler.cs deleted file mode 100644 index 1ab3937..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Addressable/Handler/I_AddressableUnLockHandler.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableUnLockHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableUnLockHandler : RouteRPC - { - /// - /// 在收到地址映射解锁请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableUnLock_Request 实例。 - /// 用于构建响应的 I_AddressableUnLock_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableUnLock_Request request, I_AddressableUnLock_Response response, Action reply) - { - scene.GetComponent().UnLock(request.AddressableId, request.RouteId, request.Source); - await FTask.CompletedTask; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/MemoryStreamBufferPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/MemoryStreamBufferPool.cs deleted file mode 100644 index 6e6d4f7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/MemoryStreamBufferPool.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Serialize; -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Network -{ - /// - /// MemoryStreamBuffer对象池类 - /// - public sealed class MemoryStreamBufferPool : IDisposable - { - private readonly int _poolSize; - private readonly int _maxMemoryStreamSize; - private readonly Queue _memoryStreamPool = new Queue(); - - /// - /// 构造方法 - /// - /// - /// - public MemoryStreamBufferPool(int maxMemoryStreamSize = 2048, int poolSize = 512) - { - _poolSize = poolSize; - _maxMemoryStreamSize = maxMemoryStreamSize; - } - - /// - /// 租借MemoryStream - /// - /// - /// - /// - public MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0) - { - if (size > _maxMemoryStreamSize) - { - return new MemoryStreamBuffer(memoryStreamBufferSource, size); - } - - if (size < _maxMemoryStreamSize) - { - size = _maxMemoryStreamSize; - } - - if (_memoryStreamPool.Count == 0) - { - return new MemoryStreamBuffer(memoryStreamBufferSource, size); - } - - if (_memoryStreamPool.TryDequeue(out var memoryStream)) - { - memoryStream.MemoryStreamBufferSource = memoryStreamBufferSource; - return memoryStream; - } - - return new MemoryStreamBuffer(memoryStreamBufferSource, size); - } - - /// - /// 归还ReturnMemoryStream - /// - /// - public void ReturnMemoryStream(MemoryStreamBuffer memoryStreamBuffer) - { - if (memoryStreamBuffer.Capacity > _maxMemoryStreamSize) - { - return; - } - - if (_memoryStreamPool.Count > _poolSize) - { - // 设置该值只能是内网或服务器转发的时候可能在连接之前发送的数据过多的情况下可以修改。 - // 设置过大会导致内存占用过大,所以要谨慎设置。 - return; - } - - memoryStreamBuffer.SetLength(0); - memoryStreamBuffer.MemoryStreamBufferSource = MemoryStreamBufferSource.None; - _memoryStreamPool.Enqueue(memoryStreamBuffer); - } - - /// - /// 销毁方法 - /// - public void Dispose() - { - foreach (var memoryStreamBuffer in _memoryStreamPool) - { - memoryStreamBuffer.MemoryStreamBufferSource = MemoryStreamBufferSource.None; - memoryStreamBuffer.Dispose(); - } - _memoryStreamPool.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Dispatcher/Interface/IMessageHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Dispatcher/Interface/IMessageHandler.cs deleted file mode 100644 index d8f928e..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Dispatcher/Interface/IMessageHandler.cs +++ /dev/null @@ -1,220 +0,0 @@ -// ReSharper disable InconsistentNaming - -using System; -using System.Collections.Generic; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.Serialize; - -namespace Fantasy.Network.Interface -{ - /// - /// 表示消息处理器的接口,处理特定类型的消息。 - /// - public interface IMessageHandler - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type(); - /// - /// 处理消息的方法。 - /// - /// 会话对象。 - /// RPC标识。 - /// 消息类型代码。 - /// 要处理的消息。 - /// 异步任务。 - FTask Handle(Session session, uint rpcId, uint messageTypeCode, object message); - } - - /// - /// 泛型消息基类,实现了 接口。 - /// - public abstract class Message : IMessageHandler - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(T); - } - - /// - /// 处理消息的方法。 - /// - /// 会话对象。 - /// RPC标识。 - /// 消息类型代码。 - /// 要处理的消息。 - /// 异步任务。 - public async FTask Handle(Session session, uint rpcId, uint messageTypeCode, object message) - { - try - { - await Run(session, (T) message); - } - catch (Exception e) - { - Log.Error(e); - } - } - - /// - /// 运行消息处理逻辑。 - /// - /// 会话对象。 - /// 要处理的消息。 - /// 异步任务。 - protected abstract FTask Run(Session session, T message); - } - - /// - /// 泛型消息RPC基类,实现了 接口,用于处理请求和响应类型的消息。 - /// - public abstract class MessageRPC : IMessageHandler where TRequest : IRequest where TResponse : AMessage, IResponse, new() - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TRequest); - } - - /// - /// 处理消息的方法。 - /// - /// 会话对象。 - /// RPC标识。 - /// 消息类型代码。 - /// 要处理的消息。 - /// 异步任务。 - public async FTask Handle(Session session, uint rpcId, uint messageTypeCode, object message) - { - if (message is not TRequest request) - { - Log.Error($"消息类型转换错误: {message.GetType().Name} to {typeof(TRequest).Name}"); - return; - } - - var response = new TResponse(); - var isReply = false; - - void Reply() - { - if (isReply) - { - return; - } - - isReply = true; - - if (session.IsDisposed) - { - return; - } - - session.Send(response, rpcId); - } - - try - { - await Run(session, request, response, Reply); - } - catch (Exception e) - { - Log.Error(e); - response.ErrorCode = InnerErrorCode.ErrRpcFail; - } - finally - { - Reply(); - } - } - - /// - /// 运行消息处理逻辑。 - /// - /// 会话对象。 - /// 请求消息。 - /// 响应消息。 - /// 发送响应的方法。 - /// 异步任务。 - protected abstract FTask Run(Session session, TRequest request, TResponse response, Action reply); - } -#if FANTASY_UNITY - public interface IMessageDelegateHandler - { - /// - /// 注册消息处理器。 - /// - /// - public void Register(object @delegate); - /// - /// 取消注册消息处理器。 - /// - /// - public int UnRegister(object @delegate); - /// - /// 处理消息的方法。 - /// - /// - /// - public void Handle(Session session, object message); - } - public delegate FTask MessageDelegate(Session session, T msg) where T : IMessage; - public sealed class MessageDelegateHandler : IMessageDelegateHandler, IDisposable where T : IMessage - { - private readonly List> _delegates = new List>(); - - public Type Type() - { - return typeof(T); - } - - public void Register(object @delegate) - { - var a = (MessageDelegate)@delegate; - - if (_delegates.Contains(a)) - { - Log.Error($"{typeof(T).Name} already register action delegateName:{a.Method.Name}"); - return; - } - - _delegates.Add(a); - } - - public int UnRegister(object @delegate) - { - _delegates.Remove((MessageDelegate)@delegate); - return _delegates.Count; - } - - public void Handle(Session session, object message) - { - foreach (var registerDelegate in _delegates) - { - try - { - registerDelegate(session, (T)message).Coroutine(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public void Dispose() - { - _delegates.Clear(); - } - } -#endif -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Dispatcher/Interface/IRouteMessageHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Dispatcher/Interface/IRouteMessageHandler.cs deleted file mode 100644 index 839cf6b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Dispatcher/Interface/IRouteMessageHandler.cs +++ /dev/null @@ -1,490 +0,0 @@ -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Serialize; - -#if FANTASY_NET -// ReSharper disable InconsistentNaming - -namespace Fantasy.Network.Interface -{ - /// - /// 表示路由消息处理器的接口,处理特定类型的路由消息。 - /// - public interface IRouteMessageHandler - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type(); - - /// - /// 处理路由消息的方法。 - /// - /// 会话对象。 - /// 实体对象。 - /// RPC标识。 - /// 要处理的路由消息。 - /// 异步任务。 - FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage); - } - - /// - /// 泛型路由基类,实现了 接口,用于处理特定实体和路由消息类型的路由。 - /// - /// 实体类型。 - /// 路由消息类型。 - public abstract class Route : IRouteMessageHandler where TEntity : Entity where TMessage : IRouteMessage - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TMessage); - } - - /// - /// 处理路由消息的方法。 - /// - /// 会话对象。 - /// 实体对象。 - /// RPC标识。 - /// 要处理的路由消息。 - /// 异步任务。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TMessage ruteMessage) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TMessage).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"{this.GetType().Name} Route type conversion error: {entity.GetType().Name} to {typeof(TEntity).Name}"); - return; - } - - try - { - await Run(tEntity, ruteMessage); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - } - } - - /// - /// 运行路由消息处理逻辑。 - /// - /// 实体对象。 - /// 要处理的路由消息。 - /// 异步任务。 - protected abstract FTask Run(TEntity entity, TMessage message); - } - - /// - /// 泛型路由RPC基类,实现了 接口,用于处理请求和响应类型的路由。 - /// - /// 实体类型。 - /// 路由请求类型。 - /// 路由响应类型。 - public abstract class RouteRPC : IRouteMessageHandler where TEntity : Entity where TRouteRequest : IRouteRequest where TRouteResponse : AMessage, IRouteResponse, new() - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TRouteRequest); - } - - /// - /// 处理路由消息的方法。 - /// - /// 会话对象。 - /// 实体对象。 - /// RPC标识。 - /// 要处理的路由消息。 - /// 异步任务。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TRouteRequest tRouteRequest) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TRouteRequest).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"{this.GetType().Name} Route type conversion error: {entity.GetType().Name} to {typeof(TEntity).Name}"); - return; - } - - var isReply = false; - var response = new TRouteResponse(); - - void Reply() - { - if (isReply) - { - return; - } - - isReply = true; - - if (session.IsDisposed) - { - return; - } - - session.Send(response, rpcId); - } - - try - { - await Run(tEntity, tRouteRequest, response, Reply); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - response.ErrorCode = InnerErrorCode.ErrRpcFail; - } - finally - { - Reply(); - } - } - - /// - /// 运行路由消息处理逻辑。 - /// - /// 实体对象。 - /// 请求路由消息。 - /// 响应路由消息。 - /// 发送响应的方法。 - /// 异步任务。 - protected abstract FTask Run(TEntity entity, TRouteRequest request, TRouteResponse response, Action reply); - } - - /// - /// 泛型可寻址路由基类,实现了 接口,用于处理特定实体和可寻址路由消息类型的路由。 - /// - /// 实体类型。 - /// 可寻址路由消息类型。 - public abstract class Addressable : IRouteMessageHandler where TEntity : Entity where TMessage : IAddressableRouteMessage - { - /// - /// 获取消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TMessage); - } - - /// - /// 处理可寻址路由消息。 - /// - /// 会话。 - /// 实体。 - /// RPC标识。 - /// 可寻址路由消息。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TMessage ruteMessage) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TMessage).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"{this.GetType().Name} Route type conversion error: {entity.GetType().Name} to {typeof(TEntity).Name}"); - return; - } - - try - { - await Run(tEntity, ruteMessage); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - } - finally - { - session.Send(new RouteResponse(), rpcId); - } - } - - /// - /// 运行处理可寻址路由消息。 - /// - /// 实体。 - /// 可寻址路由消息。 - protected abstract FTask Run(TEntity entity, TMessage message); - } - - /// - /// 泛型可寻址RPC路由基类,实现了 接口,用于处理特定实体和可寻址RPC路由请求类型的路由。 - /// - /// 实体类型。 - /// 可寻址RPC路由请求类型。 - /// 可寻址RPC路由响应类型。 - public abstract class AddressableRPC : IRouteMessageHandler where TEntity : Entity where TRouteRequest : IAddressableRouteRequest where TRouteResponse : IAddressableRouteResponse, new() - { - /// - /// 获取消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TRouteRequest); - } - - /// - /// 处理可寻址RPC路由请求。 - /// - /// 会话。 - /// 实体。 - /// RPC标识。 - /// 可寻址RPC路由请求。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TRouteRequest tRouteRequest) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TRouteRequest).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"{this.GetType().Name} Route type conversion error: {entity.GetType().Name} to {typeof(TEntity).Name}"); - return; - } - - var isReply = false; - var response = new TRouteResponse(); - - void Reply() - { - if (isReply) - { - return; - } - - isReply = true; - - if (session.IsDisposed) - { - return; - } - - session.Send(response, rpcId); - } - - try - { - await Run(tEntity, tRouteRequest, response, Reply); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - response.ErrorCode = InnerErrorCode.ErrRpcFail; - } - finally - { - Reply(); - } - } - - /// - /// 运行处理可寻址RPC路由请求。 - /// - /// 实体。 - /// 可寻址RPC路由请求。 - /// 可寻址RPC路由响应。 - /// 回复操作。 - protected abstract FTask Run(TEntity entity, TRouteRequest request, TRouteResponse response, Action reply); - } - - /// - /// 泛型漫游路由基类,实现了 接口,用于处理特定实体和漫游路由消息类型的路由。 - /// - /// 实体类型。 - /// 漫游消息类型。 - public abstract class Roaming : IRouteMessageHandler where TEntity : Entity where TMessage : IRoamingMessage - { - /// - /// 获取消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TMessage); - } - - /// - /// 处理漫游消息。 - /// - /// 会话。 - /// 实体。 - /// RPC标识。 - /// 漫游消息。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TMessage ruteMessage) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TMessage).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"{this.GetType().Name} Route type conversion error: {entity.GetType().Name} to {typeof(TEntity).Name}"); - return; - } - - try - { - await Run(tEntity, ruteMessage); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - } - finally - { - session.Send(new RouteResponse(), rpcId); - } - } - - /// - /// 运行处理漫游消息。 - /// - /// 终点实体。 - /// 漫游消息。 - protected abstract FTask Run(TEntity terminus, TMessage message); - } - - /// - /// 漫游RPC路由基类,实现了 接口,用于处理特定实体和漫游RPC路由请求类型的路由。 - /// - /// 实体类型。 - /// 漫游RPC路由请求类型。 - /// 漫游RPC路由响应类型。 - public abstract class RoamingRPC : IRouteMessageHandler where TEntity : Entity where TRouteRequest : IRoamingRequest where TRouteResponse : IRoamingResponse, new() - { - /// - /// 获取消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TRouteRequest); - } - - /// - /// 处理漫游RPC路由请求。 - /// - /// 会话。 - /// 实体。 - /// RPC标识。 - /// 漫游RPC路由请求。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TRouteRequest tRouteRequest) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TRouteRequest).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"{this.GetType().Name} Route type conversion error: {entity.GetType().Name} to {typeof(TEntity).Name}"); - return; - } - - var isReply = false; - var response = new TRouteResponse(); - - void Reply() - { - if (isReply) - { - return; - } - - isReply = true; - - if (session.IsDisposed) - { - return; - } - - session.Send(response, rpcId); - } - - try - { - await Run(tEntity, tRouteRequest, response, Reply); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - response.ErrorCode = InnerErrorCode.ErrRpcFail; - } - finally - { - Reply(); - } - } - - /// - /// 运行处理漫游RPC路由请求。 - /// - /// 终点实体。 - /// 漫游RPC路由请求。 - /// 漫游RPC路由响应。 - /// 回复操作。 - protected abstract FTask Run(TEntity terminus, TRouteRequest request, TRouteResponse response, Action reply); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Dispatcher/MessageDispatcherComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Dispatcher/MessageDispatcherComponent.cs deleted file mode 100644 index 0a24770..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Dispatcher/MessageDispatcherComponent.cs +++ /dev/null @@ -1,426 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.DataStructure.Dictionary; -using Fantasy.Entitas; -using Fantasy.InnerMessage; -using Fantasy.Network; -#pragma warning disable CS8604 // Possible null reference argument. - -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network.Interface -{ - /// - /// 用于存储消息处理器的信息,包括类型和对象实例。 - /// - /// 消息处理器的类型 - internal sealed class HandlerInfo - { - /// - /// 获取或设置消息处理器对象。 - /// - public T Obj; - /// - /// 获取或设置消息处理器的类型。 - /// - public Type Type; - } - - /// - /// 网络消息分发组件。 - /// - public sealed class MessageDispatcherComponent : Entity, IAssembly - { - public long AssemblyIdentity { get; set; } - private readonly Dictionary _responseTypes = new Dictionary(); - private readonly DoubleMapDictionary _networkProtocols = new DoubleMapDictionary(); - private readonly Dictionary _messageHandlers = new Dictionary(); - private readonly OneToManyList _assemblyResponseTypes = new OneToManyList(); - private readonly OneToManyList _assemblyNetworkProtocols = new OneToManyList(); - private readonly OneToManyList> _assemblyMessageHandlers = new OneToManyList>(); -#if FANTASY_UNITY - private readonly Dictionary _messageDelegateHandlers = new Dictionary(); -#endif -#if FANTASY_NET - private readonly Dictionary _customRouteMap = new Dictionary(); - private readonly OneToManyList _assemblyCustomRouteMap = new OneToManyList(); - private readonly Dictionary _routeMessageHandlers = new Dictionary(); - private readonly OneToManyList> _assemblyRouteMessageHandlers = new OneToManyList>(); -#endif - private CoroutineLock _receiveRouteMessageLock; - - #region Initialize - - internal async FTask Initialize() - { - _receiveRouteMessageLock = Scene.CoroutineLockComponent.Create(GetType().TypeHandle.Value.ToInt64()); - await AssemblySystem.Register(this); - return this; - } - - public async FTask Load(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - private void LoadInner(long assemblyIdentity) - { - // 遍历所有实现了IMessage接口的类型,获取OpCode并添加到_networkProtocols字典中 - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IMessage))) - { - var obj = (IMessage) Activator.CreateInstance(type); - var opCode = obj.OpCode(); - - _networkProtocols.Add(opCode, type); - - var responseType = type.GetProperty("ResponseType"); - - // 如果类型具有ResponseType属性,将其添加到_responseTypes字典中 - if (responseType != null) - { - _responseTypes.Add(type, responseType.PropertyType); - _assemblyResponseTypes.Add(assemblyIdentity, type); - } - - _assemblyNetworkProtocols.Add(assemblyIdentity, opCode); - } - - // 遍历所有实现了IMessageHandler接口的类型,创建实例并添加到_messageHandlers字典中 - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IMessageHandler))) - { - var obj = (IMessageHandler) Activator.CreateInstance(type); - - if (obj == null) - { - throw new Exception($"message handle {type.Name} is null"); - } - - var key = obj.Type(); - _messageHandlers.Add(key, obj); - _assemblyMessageHandlers.Add(assemblyIdentity, new HandlerInfo() - { - Obj = obj, Type = key - }); - } - - // 如果编译符号FANTASY_NET存在,遍历所有实现了IRouteMessageHandler接口的类型,创建实例并添加到_routeMessageHandlers字典中 -#if FANTASY_NET - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IRouteMessageHandler))) - { - var obj = (IRouteMessageHandler) Activator.CreateInstance(type); - - if (obj == null) - { - throw new Exception($"message handle {type.Name} is null"); - } - - var key = obj.Type(); - _routeMessageHandlers.Add(key, obj); - _assemblyRouteMessageHandlers.Add(assemblyIdentity, new HandlerInfo() - { - Obj = obj, Type = key - }); - } - - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(ICustomRoute))) - { - var obj = (ICustomRoute) Activator.CreateInstance(type); - - if (obj == null) - { - throw new Exception($"message handle {type.Name} is null"); - } - - var opCode = obj.OpCode(); - _customRouteMap[opCode] = obj.RouteType; - _assemblyCustomRouteMap.Add(assemblyIdentity, opCode); - } -#endif - } - - public async FTask ReLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask OnUnLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - private void OnUnLoadInner(long assemblyIdentity) - { - // 移除程序集对应的ResponseType类型和OpCode信息 - if (_assemblyResponseTypes.TryGetValue(assemblyIdentity, out var removeResponseTypes)) - { - foreach (var removeResponseType in removeResponseTypes) - { - _responseTypes.Remove(removeResponseType); - } - - _assemblyResponseTypes.RemoveByKey(assemblyIdentity); - } - - if (_assemblyNetworkProtocols.TryGetValue(assemblyIdentity, out var removeNetworkProtocols)) - { - foreach (var removeNetworkProtocol in removeNetworkProtocols) - { - _networkProtocols.RemoveByKey(removeNetworkProtocol); - } - - _assemblyNetworkProtocols.RemoveByKey(assemblyIdentity); - } - - // 移除程序集对应的消息处理器信息 - if (_assemblyMessageHandlers.TryGetValue(assemblyIdentity, out var removeMessageHandlers)) - { - foreach (var removeMessageHandler in removeMessageHandlers) - { - _messageHandlers.Remove(removeMessageHandler.Type); - } - - _assemblyMessageHandlers.RemoveByKey(assemblyIdentity); - } - - // 如果编译符号FANTASY_NET存在,移除程序集对应的路由消息处理器信息 -#if FANTASY_NET - if (_assemblyRouteMessageHandlers.TryGetValue(assemblyIdentity, out var removeRouteMessageHandlers)) - { - foreach (var removeRouteMessageHandler in removeRouteMessageHandlers) - { - _routeMessageHandlers.Remove(removeRouteMessageHandler.Type); - } - - _assemblyRouteMessageHandlers.RemoveByKey(assemblyIdentity); - } - - if (_assemblyCustomRouteMap.TryGetValue(assemblyIdentity, out var removeCustomRouteMap)) - { - foreach (var removeCustom in removeCustomRouteMap) - { - _customRouteMap.Remove(removeCustom); - } - - _assemblyCustomRouteMap.RemoveByKey(assemblyIdentity); - } -#endif - } - -#if FANTASY_UNITY - /// - /// 手动注册一个消息处理器。 - /// - /// - /// - public void RegisterHandler(MessageDelegate @delegate) where T : IMessage - { - var type = typeof(T); - - if (!_messageDelegateHandlers.TryGetValue(type, out var messageDelegate)) - { - messageDelegate = new MessageDelegateHandler(); - _messageDelegateHandlers.Add(type,messageDelegate); - } - - messageDelegate.Register(@delegate); - } - - /// - /// 手动卸载一个消息处理器,必须是通过RegisterHandler方法注册的消息处理器。 - /// - /// - /// - public void UnRegisterHandler(MessageDelegate @delegate) where T : IMessage - { - var type = typeof(T); - - if (!_messageDelegateHandlers.TryGetValue(type, out var messageDelegate)) - { - return; - } - - if (messageDelegate.UnRegister(@delegate) != 0) - { - return; - } - - _messageDelegateHandlers.Remove(type); - } -#endif - #endregion - - /// - /// 处理普通消息,将消息分发给相应的消息处理器。 - /// - /// 会话对象 - /// 消息类型 - /// 消息对象 - /// RPC标识 - /// 协议码 - public void MessageHandler(Session session, Type type, object message, uint rpcId, uint protocolCode) - { -#if FANTASY_UNITY - if(_messageDelegateHandlers.TryGetValue(type,out var messageDelegateHandler)) - { - messageDelegateHandler.Handle(session, message); - return; - } -#endif - if (!_messageHandlers.TryGetValue(type, out var messageHandler)) - { - Log.Warning($"Scene:{session.Scene.Id} Found Unhandled Message: {message.GetType()}"); - return; - } - - // 调用消息处理器的Handle方法并启动协程执行处理逻辑 - messageHandler.Handle(session, rpcId, protocolCode, message).Coroutine(); - } - - // 如果编译符号FANTASY_NET存在,定义处理路由消息的方法 -#if FANTASY_NET - /// - /// 处理路由消息,将消息分发给相应的路由消息处理器。 - /// - /// 会话对象 - /// 消息类型 - /// 实体对象 - /// 消息对象 - /// RPC标识 - public async FTask RouteMessageHandler(Session session, Type type, Entity entity, object message, uint rpcId) - { - if (!_routeMessageHandlers.TryGetValue(type, out var routeMessageHandler)) - { - Log.Warning($"Scene:{session.Scene.Id} Found Unhandled RouteMessage: {message.GetType()}"); - - if (message is IRouteRequest request) - { - FailRouteResponse(session, request.GetType(), InnerErrorCode.ErrEntityNotFound, rpcId); - } - - return; - } - - var runtimeId = entity.RuntimeId; - var sessionRuntimeId = session.RuntimeId; - - if (entity is Scene) - { - // 如果是Scene的话、就不要加锁了、如果加锁很一不小心就可能会造成死锁 - await routeMessageHandler.Handle(session, entity, rpcId, message); - return; - } - - // 使用协程锁来确保多线程安全 - using (await _receiveRouteMessageLock.Wait(runtimeId)) - { - if (sessionRuntimeId != session.RuntimeId) - { - return; - } - - if (runtimeId != entity.RuntimeId) - { - if (message is IRouteRequest request) - { - FailRouteResponse(session, request.GetType(), InnerErrorCode.ErrEntityNotFound, rpcId); - } - - return; - } - - await routeMessageHandler.Handle(session, entity, rpcId, message); - } - } - - internal bool GetCustomRouteType(long protocolCode, out int routeType) - { - return _customRouteMap.TryGetValue(protocolCode, out routeType); - } -#endif - internal void FailRouteResponse(Session session, Type requestType, uint error, uint rpcId) - { - var response = CreateRouteResponse(requestType, error); - session.Send(response, rpcId); - } - - internal IResponse CreateResponse(Type requestType, uint error) - { - IResponse response; - - if (_responseTypes.TryGetValue(requestType, out var responseType)) - { - response = (IResponse) Activator.CreateInstance(responseType); - } - else - { - response = new Response(); - } - - response.ErrorCode = error; - return response; - } - - internal IRouteResponse CreateRouteResponse(Type requestType, uint error) - { - IRouteResponse response; - - if (_responseTypes.TryGetValue(requestType, out var responseType)) - { - response = (IRouteResponse) Activator.CreateInstance(responseType); - } - else - { - response = new RouteResponse(); - } - - response.ErrorCode = error; - return response; - } - - /// - /// 根据消息类型获取对应的OpCode。 - /// - /// 消息类型 - /// 消息对应的OpCode - public uint GetOpCode(Type type) - { - return _networkProtocols.GetKeyByValue(type); - } - - /// - /// 根据OpCode获取对应的消息类型。 - /// - /// OpCode - /// OpCode对应的消息类型 - public Type GetOpCodeType(uint code) - { - return _networkProtocols.GetValueByKey(code); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/IMessage.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/IMessage.cs deleted file mode 100644 index aea7d08..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/IMessage.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.Interface -{ - /// - /// 表示通用消息接口。 - /// - public interface IMessage - { - /// - /// 获取消息的操作代码。 - /// - /// 操作代码。 - uint OpCode(); - } - - /// - /// 表示请求消息接口。 - /// - public interface IRequest : IMessage - { - - } - - /// - /// 表示响应消息接口。 - /// - public interface IResponse : IMessage - { - /// - /// 获取或设置错误代码。 - /// - uint ErrorCode { get; set; } - } - // 普通路由消息 - /// - /// 表示普通路由消息的接口,继承自请求接口。 - /// - public interface IRouteMessage : IRequest - { - - } - - /// - /// 普通路由请求接口,继承自普通路由消息接口。 - /// - public interface IRouteRequest : IRouteMessage { } - /// - /// 普通路由响应接口,继承自响应接口。 - /// - public interface IRouteResponse : IResponse { } - // 可寻址协议 - /// - /// 表示可寻址协议的普通路由消息接口,继承自普通路由消息接口。 - /// - public interface IAddressableRouteMessage : IRouteMessage { } - /// - /// 可寻址协议的普通路由请求接口,继承自可寻址协议的普通路由消息接口。 - /// - public interface IAddressableRouteRequest : IRouteRequest { } - /// - /// 可寻址协议的普通路由响应接口,继承自普通路由响应接口。 - /// - public interface IAddressableRouteResponse : IRouteResponse { } - // 自定义Route协议 - public interface ICustomRoute : IMessage - { - int RouteType { get; } - } - /// - /// 表示自定义Route协议的普通路由消息接口,继承自普通路由消息接口。 - /// - public interface ICustomRouteMessage : IRouteMessage, ICustomRoute { } - /// - /// 自定义Route协议的普通路由请求接口,继承自自定义Route协议的普通路由消息接口。 - /// - public interface ICustomRouteRequest : IRouteRequest, ICustomRoute { } - /// - /// 自定义Route协议的普通路由响应接口,继承自普通路由响应接口。 - /// - public interface ICustomRouteResponse : IRouteResponse { } - /// - /// 表示漫游协议的普通路由消息接口,继承自普通路由消息接口。 - /// - public interface IRoamingMessage : IRouteMessage, ICustomRoute { } - /// - /// 漫游协议的普通路由请求接口,继承自自定义Route协议的普通路由消息接口。 - /// - public interface IRoamingRequest : IRoamingMessage { } - /// - /// 漫游协议的普通路由响应接口,继承自普通路由响应接口。 - /// - public interface IRoamingResponse : IRouteResponse { } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/InnerMessage.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/InnerMessage.cs deleted file mode 100644 index 643c92b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/InnerMessage.cs +++ /dev/null @@ -1,319 +0,0 @@ -using Fantasy.Network.Interface; -using Fantasy.Serialize; -using MongoDB.Bson.Serialization.Attributes; -using ProtoBuf; -#if FANTASY_NET -using Fantasy.Network.Roaming; -#endif -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// ReSharper disable InconsistentNaming -// ReSharper disable PropertyCanBeMadeInitOnly.Global -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.InnerMessage -{ - [ProtoContract] - public sealed partial class BenchmarkMessage : AMessage, IMessage - { - public uint OpCode() - { - return Fantasy.Network.OpCode.BenchmarkMessage; - } - } - [ProtoContract] - public partial class BenchmarkRequest : AMessage, IRequest - { - public uint OpCode() - { - return Fantasy.Network.OpCode.BenchmarkRequest; - } - [ProtoIgnore] - public BenchmarkResponse ResponseType { get; set; } - [ProtoMember(1)] - public long RpcId { get; set; } - } - - [ProtoContract] - public partial class BenchmarkResponse : AMessage, IResponse - { - public uint OpCode() - { - return Fantasy.Network.OpCode.BenchmarkResponse; - } - [ProtoMember(1)] - public long RpcId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - public sealed partial class Response : AMessage, IResponse - { - public uint OpCode() - { - return Fantasy.Network.OpCode.DefaultResponse; - } - [ProtoMember(1)] - public long RpcId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public sealed partial class RouteResponse : AMessage, IRouteResponse - { - public uint OpCode() - { - return Fantasy.Network.OpCode.DefaultRouteResponse; - } - [ProtoMember(1)] - public long RpcId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class PingRequest : AMessage, IRequest - { - public uint OpCode() - { - return Fantasy.Network.OpCode.PingRequest; - } - [ProtoIgnore] - public PingResponse ResponseType { get; set; } - [ProtoMember(1)] - public long RpcId { get; set; } - } - - [ProtoContract] - public partial class PingResponse : AMessage, IResponse - { - public uint OpCode() - { - return Fantasy.Network.OpCode.PingResponse; - } - [ProtoMember(1)] - public long RpcId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - [ProtoMember(3)] - public long Now; - } - [ProtoContract] - public partial class I_AddressableAdd_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableAdd_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableAddRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - [ProtoMember(2)] - public long RouteId { get; set; } - [ProtoMember(3)] - public bool IsLock { get; set; } - } - [ProtoContract] - public partial class I_AddressableAdd_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableAddResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class I_AddressableGet_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableGet_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableGetRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - } - [ProtoContract] - public partial class I_AddressableGet_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableGetResponse; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - [ProtoMember(1)] - public long RouteId { get; set; } - } - [ProtoContract] - public partial class I_AddressableRemove_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableRemove_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableRemoveRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - } - [ProtoContract] - public partial class I_AddressableRemove_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableRemoveResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class I_AddressableLock_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableLock_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableLockRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - } - [ProtoContract] - public partial class I_AddressableLock_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableLockResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class I_AddressableUnLock_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableUnLock_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableUnLockRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - [ProtoMember(2)] - public long RouteId { get; set; } - [ProtoMember(3)] - public string Source { get; set; } - } - [ProtoContract] - public partial class I_AddressableUnLock_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableUnLockResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } -#if FANTASY_NET - [ProtoContract] - public sealed class I_LinkRoamingRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_LinkRoamingResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.LinkRoamingRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long RoamingId { get; set; } - [ProtoMember(2)] - public int RoamingType { get; set; } - [ProtoMember(3)] - public long ForwardSessionRouteId { get; set; } - [ProtoMember(4)] - public long SceneRouteId { get; set; } - } - [ProtoContract] - public sealed class I_LinkRoamingResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.LinkRoamingResponse; } - [ProtoMember(1)] - public long TerminusId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public sealed class I_UnLinkRoamingRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_UnLinkRoamingResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.UnLinkRoamingRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long RoamingId { get; set; } - [ProtoMember(2)] - public bool DisposeRoaming { get; set; } - } - [ProtoContract] - public sealed class I_UnLinkRoamingResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.UnLinkRoamingResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class I_LockTerminusIdRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_LockTerminusIdResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.LockTerminusIdRequest; } - [ProtoMember(1)] - public long SessionRuntimeId { get; set; } - [ProtoMember(2)] - public int RoamingType { get; set; } - } - [ProtoContract] - public partial class I_LockTerminusIdResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.LockTerminusIdResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public sealed class I_UnLockTerminusIdRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_UnLockTerminusIdResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.UnLockTerminusIdRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long SessionRuntimeId { get; set; } - [ProtoMember(2)] - public int RoamingType { get; set; } - [ProtoMember(3)] - public long TerminusId { get; set; } - [ProtoMember(4)] - public long TargetSceneRouteId { get; set; } - } - [ProtoContract] - public sealed class I_UnLockTerminusIdResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.UnLockTerminusIdResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - /// - /// 漫游传送终端的请求 - /// - public partial class I_TransferTerminusRequest : AMessage, IRouteRequest - { - [BsonIgnore] - public I_TransferTerminusResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.TransferTerminusRequest; } - public Terminus Terminus { get; set; } - } - public partial class I_TransferTerminusResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.TransferTerminusResponse; } - public uint ErrorCode { get; set; } - } - /// - /// 用于服务器之间获取漫游的TerminusId。 - /// - [ProtoContract] - public partial class I_GetTerminusIdRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_GetTerminusIdResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.GetTerminusIdRequest; } - [ProtoMember(1)] - public int RoamingType { get; set; } - [ProtoMember(2)] - public long SessionRuntimeId { get; set; } - } - [ProtoContract] - public partial class I_GetTerminusIdResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.GetTerminusIdResponse; } - [ProtoMember(1)] - public long TerminusId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } -#endif -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/BufferPacketParser.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/BufferPacketParser.cs deleted file mode 100644 index b1c6c84..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/BufferPacketParser.cs +++ /dev/null @@ -1,392 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -namespace Fantasy.PacketParser -{ - /// - /// BufferPacketParser消息格式化器抽象类 - /// 这个不会用在TCP协议中、因此不用考虑分包和粘包的问题。 - /// 目前这个只会用在KCP协议中、因为KCP出来的就是一个完整的包、所以可以一次性全部解析出来。 - /// 如果是用在其他协议上可能会出现问题。 - /// - public abstract class BufferPacketParser : APacketParser - { - protected uint RpcId; - protected long RouteId; - protected uint ProtocolCode; - protected int MessagePacketLength; - public override void Dispose() - { - RpcId = 0; - RouteId = 0; - ProtocolCode = 0; - MessagePacketLength = 0; - base.Dispose(); - } - /// - /// 解包方法 - /// - /// buffer - /// count - /// packInfo - /// - public abstract bool UnPack(byte[] buffer, ref int count, out APackInfo packInfo); - } -#if FANTASY_NET - /// - /// 服务器之间专用的BufferPacketParser消息格式化器 - /// - public sealed class InnerBufferPacketParser : BufferPacketParser - { - /// - /// - /// - /// - /// - /// - /// - /// - public override unsafe bool UnPack(byte[] buffer, ref int count, out APackInfo packInfo) - { - packInfo = null; - - if (buffer.Length < count) - { - throw new ScanException($"The buffer length is less than the specified count. buffer.Length={buffer.Length} count={count}"); - } - - if (count < Packet.InnerPacketHeadLength) - { - // 如果内存资源中的数据长度小于内部消息头的长度,无法解析 - return false; - } - - var span = buffer.AsSpan(); - ref var bufferRef = ref MemoryMarshal.GetReference(span); - - MessagePacketLength = Unsafe.ReadUnaligned(ref bufferRef); - - if (MessagePacketLength > ProgramDefine.MaxMessageSize || count < MessagePacketLength) - { - // 检查消息体长度是否超出限制 - throw new ScanException($"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - ProtocolCode = Unsafe.ReadUnaligned(ref Unsafe.Add(ref bufferRef, Packet.PacketLength)); - RpcId = Unsafe.ReadUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRpcIdLocation)); - RouteId = Unsafe.ReadUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRouteRouteIdLocation)); - - packInfo = InnerPackInfo.Create(Network); - packInfo.RpcId = RpcId; - packInfo.RouteId = RouteId; - packInfo.ProtocolCode = ProtocolCode; - packInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, count).Write(buffer, 0, count); - return true; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, ref routeId, message) : Pack(ref rpcId, ref routeId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream) - { - var buffer = memoryStream.GetBuffer(); - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); - - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRpcIdLocation), rpcId); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRouteRouteIdLocation), routeId); - - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.Pack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.InnerPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > ProgramDefine.MaxMessageSize) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {ProgramDefine.MaxMessageSize} bytes"); - } - - var buffer = memoryStream.GetBuffer(); - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); - - Unsafe.WriteUnaligned(ref bufferRef, packetBodyCount); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.PacketLength), opCode); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRpcIdLocation), rpcId); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRouteRouteIdLocation), routeId); - - return memoryStream; - } - } -#endif - /// - /// 客户端和服务器之间专用的BufferPacketParser消息格式化器 - /// - public sealed class OuterBufferPacketParser : BufferPacketParser - { - /// - /// - /// - /// - /// - /// - /// - /// - public override bool UnPack(byte[] buffer, ref int count, out APackInfo packInfo) - { - packInfo = null; - - if (buffer.Length < count) - { - throw new ScanException($"The buffer length is less than the specified count. buffer.Length={buffer.Length} count={count}"); - } - - if (count < Packet.OuterPacketHeadLength) - { - // 如果内存资源中的数据长度小于内部消息头的长度,无法解析 - return false; - } - - var span = buffer.AsSpan(); - ref var bufferRef = ref MemoryMarshal.GetReference(span); - - MessagePacketLength = Unsafe.ReadUnaligned(ref bufferRef); - - if (MessagePacketLength > ProgramDefine.MaxMessageSize || count < MessagePacketLength) - { - // 检查消息体长度是否超出限制 - throw new ScanException($"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - ProtocolCode = Unsafe.ReadUnaligned(ref Unsafe.Add(ref bufferRef, Packet.PacketLength)); - RpcId = Unsafe.ReadUnaligned(ref Unsafe.Add(ref bufferRef, Packet.OuterPacketRpcIdLocation)); - - packInfo = OuterPackInfo.Create(Network); - packInfo.RpcId = RpcId; - packInfo.ProtocolCode = ProtocolCode; - packInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, count).Write(buffer, 0, count); - return true; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, message) : Pack(ref rpcId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, MemoryStreamBuffer memoryStream) - { - var buffer = memoryStream.GetBuffer(); -#if FANTASY_UNITY - ref var bufferRef = ref MemoryMarshal.GetReference(buffer.AsSpan()); -#else - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); -#endif - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRpcIdLocation), rpcId); - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.Pack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.OuterPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > ProgramDefine.MaxMessageSize) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {ProgramDefine.MaxMessageSize} bytes"); - } - - var buffer = memoryStream.GetBuffer(); -#if FANTASY_UNITY - ref var bufferRef = ref MemoryMarshal.GetReference(buffer.AsSpan()); -#else - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); -#endif - Unsafe.WriteUnaligned(ref bufferRef, packetBodyCount); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.PacketLength), opCode); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.OuterPacketRpcIdLocation), rpcId); - - return memoryStream; - } - } - /// - /// Webgl专用的客户端和服务器之间专用的BufferPacketParser消息格式化器 - /// - public sealed class OuterWebglBufferPacketParser : BufferPacketParser - { - /// - /// - /// - /// - /// - /// - /// - /// - public override bool UnPack(byte[] buffer, ref int count, out APackInfo packInfo) - { - packInfo = null; - - if (buffer.Length < count) - { - throw new ScanException($"The buffer length is less than the specified count. buffer.Length={buffer.Length} count={count}"); - } - - if (count < Packet.OuterPacketHeadLength) - { - // 如果内存资源中的数据长度小于内部消息头的长度,无法解析 - return false; - } - - var span = buffer.AsSpan(); - ref var bufferRef = ref MemoryMarshal.GetReference(span); - - MessagePacketLength = Unsafe.ReadUnaligned(ref bufferRef); - - if (MessagePacketLength > ProgramDefine.MaxMessageSize || count < MessagePacketLength) - { - // 检查消息体长度是否超出限制 - throw new ScanException($"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - ProtocolCode = Unsafe.ReadUnaligned(ref Unsafe.Add(ref bufferRef, Packet.PacketLength)); - RpcId = Unsafe.ReadUnaligned(ref Unsafe.Add(ref bufferRef, Packet.OuterPacketRpcIdLocation)); - - packInfo = OuterPackInfo.Create(Network); - packInfo.RpcId = RpcId; - packInfo.ProtocolCode = ProtocolCode; - packInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, count).Write(buffer, 0, count); - return true; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, message) : Pack(ref rpcId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, MemoryStreamBuffer memoryStream) - { - var buffer = memoryStream.GetBuffer().AsSpan(); -#if FANTASY_NET - MemoryMarshal.Write(buffer.Slice(Packet.OuterPacketRpcIdLocation, sizeof(uint)), in rpcId); -#endif -#if FANTASY_UNITY - MemoryMarshal.Write(buffer.Slice(Packet.OuterPacketRpcIdLocation, sizeof(uint)), ref rpcId); -#endif - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.UnPack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.OuterPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > ProgramDefine.MaxMessageSize) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {ProgramDefine.MaxMessageSize} bytes"); - } - - var buffer = memoryStream.GetBuffer(); -#if FANTASY_UNITY - ref var bufferRef = ref MemoryMarshal.GetReference(buffer.AsSpan()); -#else - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); -#endif - Unsafe.WriteUnaligned(ref bufferRef, packetBodyCount); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.PacketLength), opCode); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.OuterPacketRpcIdLocation), rpcId); - return memoryStream; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/CircularBufferPacketParser.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/CircularBufferPacketParser.cs deleted file mode 100644 index 24c368b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/CircularBufferPacketParser.cs +++ /dev/null @@ -1,170 +0,0 @@ -// using System.Runtime.CompilerServices; -// // ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// -// namespace Fantasy -// { -// // 这个对处理分包和粘包逻辑不完整、考虑现在没有任何地方使用了、就先不修改了。 -// // 后面用到了再修改、现在这个只是留做备份、万一以后用到了呢。 -// public abstract class CircularBufferPacketParser : APacketParser -// { -// protected uint RpcId; -// protected long RouteId; -// protected uint ProtocolCode; -// protected int MessagePacketLength; -// protected bool IsUnPackHead = true; -// protected readonly byte[] MessageHead = new byte[Packet.InnerPacketHeadLength]; -// public abstract bool UnPack(CircularBuffer buffer, out APackInfo packInfo); -// } -// -// #if FANTASY_NET -// public sealed class InnerCircularBufferPacketParser : CircularBufferPacketParser, IInnerPacketParser -// { -// public override bool UnPack(CircularBuffer buffer, out APackInfo packInfo) -// { -// packInfo = null; -// -// // 在对象没有被释放的情况下循环解析数据 -// while (!IsDisposed) -// { -// if (IsUnPackHead) -// { -// // 如果缓冲区中的数据长度小于内部消息头的长度,无法解析 -// if (buffer.Length < Packet.InnerPacketHeadLength) -// { -// return false; -// } -// -// // 从缓冲区中读取内部消息头的数据 -// _ = buffer.Read(MessageHead, 0, Packet.InnerPacketHeadLength); -// MessagePacketLength = BitConverter.ToInt32(MessageHead, 0); -// -// // 检查消息体长度是否超出限制 -// if (MessagePacketLength > Packet.PacketBodyMaxLength) -// { -// throw new ScanException( -// $"The received information exceeds the maximum limit = {MessagePacketLength}"); -// } -// -// // 解析协议编号、RPC ID 和 Route ID -// ProtocolCode = BitConverter.ToUInt32(MessageHead, Packet.PacketLength); -// RpcId = BitConverter.ToUInt32(MessageHead, Packet.InnerPacketRpcIdLocation); -// RouteId = BitConverter.ToInt64(MessageHead, Packet.InnerPacketRouteRouteIdLocation); -// IsUnPackHead = false; -// } -// -// try -// { -// // 如果缓冲区中的数据长度小于消息体的长度,无法解析 -// if (MessagePacketLength < 0 || buffer.Length < MessagePacketLength) -// { -// return false; -// } -// -// IsUnPackHead = true; -// packInfo = InnerPackInfo.Create(Network); -// var memoryStream = packInfo.RentMemoryStream(MessagePacketLength); -// memoryStream.SetLength(MessagePacketLength); -// buffer.Read(memoryStream, MessagePacketLength); -// packInfo.RpcId = RpcId; -// packInfo.RouteId = RouteId; -// packInfo.ProtocolCode = ProtocolCode; -// packInfo.MessagePacketLength = MessagePacketLength; -// return true; -// } -// catch (Exception e) -// { -// // 在发生异常时,释放 packInfo 并记录日志 -// packInfo?.Dispose(); -// Log.Error(e); -// return false; -// } -// } -// -// return false; -// } -// -// public override MemoryStream Pack(ref uint rpcId, ref long routeTypeOpCode, ref long routeId, -// MemoryStream memoryStream, object message) -// { -// return memoryStream == null -// ? Pack(ref rpcId, ref routeId, message) -// : Pack(ref rpcId, ref routeId, memoryStream); -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private unsafe MemoryStream Pack(ref uint rpcId, ref long routeId, MemoryStream memoryStream) -// { -// var buffer = memoryStream.GetBuffer(); -// -// fixed (byte* bufferPtr = buffer) -// { -// var rpcIdPtr = bufferPtr + Packet.InnerPacketRpcIdLocation; -// var routeIdPtr = bufferPtr + Packet.InnerPacketRouteRouteIdLocation; -// *(uint*)rpcIdPtr = rpcId; -// *(long*)routeIdPtr = routeId; -// } -// -// memoryStream.Seek(0, SeekOrigin.Begin); -// return memoryStream; -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private unsafe MemoryStream Pack(ref uint rpcId, ref long routeId, object message) -// { -// var memoryStream = Network.RentMemoryStream(); -// memoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); -// -// switch (message) -// { -// case IBsonMessage: -// { -// MongoHelper.SerializeTo(message, memoryStream); -// break; -// } -// default: -// { -// ProtoBuffHelper.ToStream(message, memoryStream); -// break; -// } -// } -// -// var opCode = Scene.MessageDispatcherComponent.GetOpCode(message.GetType()); -// var packetBodyCount = (int)(memoryStream.Position - Packet.InnerPacketHeadLength); -// -// if (packetBodyCount == 0) -// { -// // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 -// // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 -// packetBodyCount = -1; -// } -// -// // 检查消息体长度是否超出限制 -// if (packetBodyCount > Packet.PacketBodyMaxLength) -// { -// throw new Exception($"Message content exceeds {Packet.PacketBodyMaxLength} bytes"); -// } -// -// var buffer = memoryStream.GetBuffer(); -// -// fixed (byte* bufferPtr = buffer) -// { -// var opCodePtr = bufferPtr + Packet.PacketLength; -// var rpcIdPtr = bufferPtr + Packet.InnerPacketRpcIdLocation; -// var routeIdPtr = bufferPtr + Packet.InnerPacketRouteRouteIdLocation; -// *(int*)bufferPtr = packetBodyCount; -// *(uint*)opCodePtr = opCode; -// *(uint*)rpcIdPtr = rpcId; -// *(long*)routeIdPtr = routeId; -// } -// -// memoryStream.Seek(0, SeekOrigin.Begin); -// return memoryStream; -// } -// } -// #endif -// } -// -// -// -// diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/OuterBufferPacketParserHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/OuterBufferPacketParserHelper.cs deleted file mode 100644 index 0047c39..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/OuterBufferPacketParserHelper.cs +++ /dev/null @@ -1,73 +0,0 @@ -#if FANTASY_NET -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Serialize; - -namespace Fantasy.PacketParser -{ - /// - /// 打包Outer消息的帮助类 - /// - public static class OuterBufferPacketParserHelper - { - /// - /// 打包一个网络消息 - /// - /// scene - /// 如果是RPC消息需要传递一个rpcId - /// 打包的网络消息 - /// 序列化后流的长度 - /// 打包完成会返回一个MemoryStreamBuffer - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MemoryStreamBuffer Pack(Scene scene, uint rpcId, IMessage message, out int memoryStreamLength) - { - memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = new MemoryStreamBuffer(); - memoryStream.MemoryStreamBufferSource = MemoryStreamBufferSource.Pack; - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.OuterPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > ProgramDefine.MaxMessageSize) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {ProgramDefine.MaxMessageSize} bytes"); - } - - var buffer = memoryStream.GetBuffer(); - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); - - Unsafe.WriteUnaligned(ref bufferRef, packetBodyCount); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.PacketLength), opCode); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.OuterPacketRpcIdLocation), rpcId); - - return memoryStream; - } - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/ReadOnlyMemoryPacketParser.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/ReadOnlyMemoryPacketParser.cs deleted file mode 100644 index dc2203b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Handler/ReadOnlyMemoryPacketParser.cs +++ /dev/null @@ -1,376 +0,0 @@ -using System; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.PacketParser -{ - internal abstract class ReadOnlyMemoryPacketParser : APacketParser - { - /// - /// 一个网络消息包 - /// - protected APackInfo PackInfo; - - protected int Offset; - protected int MessageHeadOffset; - protected int MessageBodyOffset; - protected int MessagePacketLength; - protected bool IsUnPackHead = true; - protected readonly byte[] MessageHead = new byte[20]; - public ReadOnlyMemoryPacketParser() { } - - public abstract bool UnPack(ref ReadOnlyMemory buffer, out APackInfo packInfo); - - public override void Dispose() - { - Offset = 0; - MessageHeadOffset = 0; - MessageBodyOffset = 0; - MessagePacketLength = 0; - IsUnPackHead = true; - PackInfo = null; - Array.Clear(MessageHead, 0, 20); - base.Dispose(); - } - } - -#if FANTASY_NET - internal sealed class InnerReadOnlyMemoryPacketParser : ReadOnlyMemoryPacketParser - { - public override bool UnPack(ref ReadOnlyMemory buffer, out APackInfo packInfo) - { - packInfo = null; - var readOnlySpan = buffer.Span; - var bufferLength = buffer.Length - Offset; - - if (bufferLength == 0) - { - // 没有剩余的数据需要处理、等待下一个包再处理。 - Offset = 0; - return false; - } - - if (IsUnPackHead) - { - // 在当前buffer中拿到包头的数据 - var innerPacketHeadLength = Packet.InnerPacketHeadLength - MessageHeadOffset; - var copyLength = Math.Min(bufferLength, innerPacketHeadLength); - - readOnlySpan.Slice(Offset, copyLength).CopyTo(MessageHead.AsSpan(MessageHeadOffset, copyLength)); - - Offset += copyLength; - MessageHeadOffset += copyLength; - // 检查是否有完整包头 - if (MessageHeadOffset == Packet.InnerPacketHeadLength) - { - // 通过现代API直接读取协议编号、messagePacketLength protocolCode rpcId routeId - ref var messageRef = ref MemoryMarshal.GetArrayDataReference(MessageHead); - MessagePacketLength = Unsafe.ReadUnaligned(ref messageRef); - // 检查消息体长度是否超出限制 - if (MessagePacketLength > ProgramDefine.MaxMessageSize) - { - throw new ScanException( - $"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - PackInfo = InnerPackInfo.Create(Network); - var memoryStream = PackInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, - Packet.InnerPacketHeadLength + MessagePacketLength); - PackInfo.RpcId = - Unsafe.ReadUnaligned(ref Unsafe.Add(ref messageRef, Packet.InnerPacketRpcIdLocation)); - PackInfo.ProtocolCode = - Unsafe.ReadUnaligned(ref Unsafe.Add(ref messageRef, Packet.PacketLength)); - PackInfo.RouteId = - Unsafe.ReadUnaligned(ref Unsafe.Add(ref messageRef, - Packet.InnerPacketRouteRouteIdLocation)); - memoryStream.Write(MessageHead); - IsUnPackHead = false; - bufferLength -= copyLength; - MessageHeadOffset = 0; - } - else - { - Offset = 0; - return false; - } - } - - if (MessagePacketLength == -1) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packInfo = PackInfo; - PackInfo = null; - IsUnPackHead = true; - return true; - } - - if (bufferLength == 0) - { - // 没有剩余的数据需要处理、等待下一个包再处理。 - Offset = 0; - return false; - } - - // 处理包消息体 - var innerPacketBodyLength = MessagePacketLength - MessageBodyOffset; - var copyBodyLength = Math.Min(bufferLength, innerPacketBodyLength); - // 写入数据到消息体中 - PackInfo.MemoryStream.Write(readOnlySpan.Slice(Offset, copyBodyLength)); - Offset += copyBodyLength; - MessageBodyOffset += copyBodyLength; - // 检查是否是完整的消息体 - if (MessageBodyOffset == MessagePacketLength) - { - packInfo = PackInfo; - PackInfo = null; - IsUnPackHead = true; - MessageBodyOffset = 0; - return true; - } - - Offset = 0; - return false; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, ref routeId, message) : Pack(ref rpcId, ref routeId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream) - { - var buffer = memoryStream.GetBuffer(); - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); - - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRpcIdLocation), rpcId); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRouteRouteIdLocation), routeId); - - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.Pack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.InnerPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - // 其实可以不用设置-1、解包的时候判断如果是0也可以、但我仔细想了下,还是用-1代表更加清晰。 - packetBodyCount = -1; - } - - if (packetBodyCount > ProgramDefine.MaxMessageSize) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {ProgramDefine.MaxMessageSize} bytes"); - } - - var buffer = memoryStream.GetBuffer(); - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); - - Unsafe.WriteUnaligned(ref bufferRef, packetBodyCount); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.PacketLength), opCode); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRpcIdLocation), rpcId); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.InnerPacketRouteRouteIdLocation), routeId); - - return memoryStream; - } - } -#endif - internal sealed class OuterReadOnlyMemoryPacketParser : ReadOnlyMemoryPacketParser - { - public override bool UnPack(ref ReadOnlyMemory buffer, out APackInfo packInfo) - { - packInfo = null; - var readOnlySpan = buffer.Span; - var bufferLength = buffer.Length - Offset; - - if (bufferLength == 0) - { - // 没有剩余的数据需要处理、等待下一个包再处理。 - Offset = 0; - return false; - } - - if (IsUnPackHead) - { - // 在当前buffer中拿到包头的数据 - var outerPacketHeadLength = Packet.OuterPacketHeadLength - MessageHeadOffset; - var copyLength = Math.Min(bufferLength, outerPacketHeadLength); - - readOnlySpan.Slice(Offset, copyLength).CopyTo(MessageHead.AsSpan(MessageHeadOffset, copyLength)); - - Offset += copyLength; - MessageHeadOffset += copyLength; - // 检查是否有完整包头 - if (MessageHeadOffset == Packet.OuterPacketHeadLength) - { - // 通过现代API直接读取协议编号、messagePacketLength protocolCode rpcId routeId -#if FANTASY_UNITY - ref var messageRef = ref MemoryMarshal.GetReference(buffer.Span); -#else - ref var messageRef = ref MemoryMarshal.GetArrayDataReference(MessageHead); -#endif - MessagePacketLength = Unsafe.ReadUnaligned(ref messageRef); - // 检查消息体长度是否超出限制 - if (MessagePacketLength > ProgramDefine.MaxMessageSize) - { - throw new ScanException( - $"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - PackInfo = OuterPackInfo.Create(Network); - PackInfo.ProtocolCode = - Unsafe.ReadUnaligned(ref Unsafe.Add(ref messageRef, Packet.PacketLength)); - PackInfo.RpcId = - Unsafe.ReadUnaligned(ref Unsafe.Add(ref messageRef, Packet.OuterPacketRpcIdLocation)); - var memoryStream = PackInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, - Packet.OuterPacketHeadLength + MessagePacketLength); - memoryStream.Write(MessageHead); - IsUnPackHead = false; - bufferLength -= copyLength; - MessageHeadOffset = 0; - } - else - { - Offset = 0; - return false; - } - } - - if (MessagePacketLength == -1) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packInfo = PackInfo; - PackInfo = null; - IsUnPackHead = true; - return true; - } - - if (bufferLength == 0) - { - // 没有剩余的数据需要处理、等待下一个包再处理。 - Offset = 0; - return false; - } - // 处理包消息体 - var outerPacketBodyLength = MessagePacketLength - MessageBodyOffset; - var copyBodyLength = Math.Min(bufferLength, outerPacketBodyLength); - // 写入数据到消息体中 - PackInfo.MemoryStream.Write(readOnlySpan.Slice(Offset, copyBodyLength)); - Offset += copyBodyLength; - MessageBodyOffset += copyBodyLength; - // 检查是否是完整的消息体 - if (MessageBodyOffset == MessagePacketLength) - { - packInfo = PackInfo; - PackInfo = null; - IsUnPackHead = true; - MessageBodyOffset = 0; - return true; - } - - Offset = 0; - return false; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, message) : Pack(ref rpcId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, MemoryStreamBuffer memoryStream) - { - var buffer = memoryStream.GetBuffer(); -#if FANTASY_UNITY - ref var bufferRef = ref MemoryMarshal.GetReference(buffer.AsSpan()); -#else - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); -#endif - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.OuterPacketRpcIdLocation), rpcId); - - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe MemoryStreamBuffer Pack(ref uint rpcId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.Pack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.OuterPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > ProgramDefine.MaxMessageSize) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {ProgramDefine.MaxMessageSize} bytes"); - } - - var buffer = memoryStream.GetBuffer(); -#if FANTASY_UNITY - ref var bufferRef = ref MemoryMarshal.GetReference(buffer.AsSpan()); -#else - ref var bufferRef = ref MemoryMarshal.GetArrayDataReference(buffer); -#endif - Unsafe.WriteUnaligned(ref bufferRef, packetBodyCount); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.PacketLength), opCode); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref bufferRef, Packet.OuterPacketRpcIdLocation), rpcId); - - return memoryStream; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Interface/APackInfo.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Interface/APackInfo.cs deleted file mode 100644 index 1ea6d6b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Interface/APackInfo.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.IO; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.PacketParser.Interface -{ - public abstract class APackInfo : IDisposable - { - internal ANetwork Network; - - public uint RpcId; - public long RouteId; - public long PackInfoId; - public bool IsDisposed; - private uint _protocolCode; - - public uint ProtocolCode - { - get => _protocolCode; - set - { - _protocolCode = value; - OpCodeIdStruct = value; - } - } - public OpCodeIdStruct OpCodeIdStruct { get; private set; } - public MemoryStreamBuffer MemoryStream { get; protected set; } - public abstract object Deserialize(Type messageType); - public abstract MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0); - public virtual void Dispose() - { - if (IsDisposed) - { - return; - } - - RpcId = 0; - RouteId = 0; - PackInfoId = 0; - ProtocolCode = 0; - _protocolCode = 0; - OpCodeIdStruct = default; - - if (MemoryStream != null) - { - Network.MemoryStreamBufferPool.ReturnMemoryStream(MemoryStream); - MemoryStream = null; - } - - IsDisposed = true; - Network = null; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Interface/APacketParser.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Interface/APacketParser.cs deleted file mode 100644 index 579cf6f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Interface/APacketParser.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using Fantasy.Network.Interface; -using Fantasy.Serialize; - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.PacketParser.Interface -{ - /// - /// 抽象的包解析器基类,用于解析网络通信数据包。 - /// - public abstract class APacketParser : IDisposable - { - internal Scene Scene; - internal ANetwork Network; - internal MessageDispatcherComponent MessageDispatcherComponent; - protected bool IsDisposed { get; private set; } - public abstract MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message); - public virtual void Dispose() - { - IsDisposed = true; - Scene = null; - MessageDispatcherComponent = null; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/OpCode.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/OpCode.cs deleted file mode 100644 index 27c5dbb..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/OpCode.cs +++ /dev/null @@ -1,125 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network -{ - public struct OpCodeIdStruct - { - // OpCodeIdStruct:5 + 4 + 23 = 32 - // +-------------------------+-------------------------------------------+-----------------------------+ - // | protocol(5) 最多31种类型 | OpCodeProtocolType(4) 最多15种不同的网络协议 | Index(23) 最多8388607个协议 | - // +-------------------------+-------------------------------------------+-----------------------------+ - public uint OpCodeProtocolType { get; private set; } - public uint Protocol { get; private set; } - public uint Index { get; private set; } - - public OpCodeIdStruct(uint opCodeProtocolType, uint protocol, uint index) - { - OpCodeProtocolType = opCodeProtocolType; - Protocol = protocol; - Index = index; - } - - public static implicit operator uint(OpCodeIdStruct opCodeIdStruct) - { - var result = opCodeIdStruct.Index; - result |= opCodeIdStruct.OpCodeProtocolType << 23; - result |= opCodeIdStruct.Protocol << 27; - return result; - } - - public static implicit operator OpCodeIdStruct(uint opCodeId) - { - var opCodeIdStruct = new OpCodeIdStruct() - { - Index = opCodeId & 0x7FFFFF - }; - opCodeId >>= 23; - opCodeIdStruct.OpCodeProtocolType = opCodeId & 0xF; - opCodeId >>= 4; - opCodeIdStruct.Protocol = opCodeId & 0x1F; - return opCodeIdStruct; - } - } - - public static class OpCodeProtocolType - { - public const uint Bson = 1; - public const uint ProtoBuf = 0; - } - - public static class OpCodeType - { - public const uint OuterMessage = 1; - public const uint OuterRequest = 2; - public const uint OuterResponse = 3; - - public const uint InnerMessage = 4; - public const uint InnerRequest = 5; - public const uint InnerResponse = 6; - - public const uint InnerRouteMessage = 7; - public const uint InnerRouteRequest = 8; - public const uint InnerRouteResponse = 9; - - public const uint OuterAddressableMessage = 10; - public const uint OuterAddressableRequest = 11; - public const uint OuterAddressableResponse = 12; - - public const uint InnerAddressableMessage = 13; - public const uint InnerAddressableRequest = 14; - public const uint InnerAddressableResponse = 15; - - public const uint OuterCustomRouteMessage = 16; - public const uint OuterCustomRouteRequest = 17; - public const uint OuterCustomRouteResponse = 18; - - public const uint OuterRoamingMessage = 19; - public const uint OuterRoamingRequest = 20; - public const uint OuterRoamingResponse = 21; - - public const uint InnerRoamingMessage = 22; - public const uint InnerRoamingRequest = 23; - public const uint InnerRoamingResponse = 24; - - public const uint OuterPingRequest = 30; - public const uint OuterPingResponse = 31; - } - - public static class OpCode - { - public static readonly uint BenchmarkMessage = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterMessage, 8388607); - public static readonly uint BenchmarkRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterRequest, 8388607); - public static readonly uint BenchmarkResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterResponse, 8388607); - public static readonly uint PingRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterPingRequest, 1); - public static readonly uint PingResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterPingResponse, 1); - public static readonly uint DefaultResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerResponse, 1); - public static readonly uint DefaultRouteResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 7); - public static readonly uint AddressableAddRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 1); - public static readonly uint AddressableAddResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 1); - public static readonly uint AddressableGetRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 2); - public static readonly uint AddressableGetResponse = Create(OpCodeProtocolType.ProtoBuf,OpCodeType.InnerRouteResponse,2); - public static readonly uint AddressableRemoveRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 3); - public static readonly uint AddressableRemoveResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 3); - public static readonly uint AddressableLockRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 4); - public static readonly uint AddressableLockResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 4); - public static readonly uint AddressableUnLockRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 5); - public static readonly uint AddressableUnLockResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 5); - public static readonly uint LinkRoamingRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 6); - public static readonly uint LinkRoamingResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 6); - public static readonly uint UnLinkRoamingRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 8); - public static readonly uint UnLinkRoamingResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 8); - public static readonly uint LockTerminusIdRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 9); - public static readonly uint LockTerminusIdResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 9); - public static readonly uint UnLockTerminusIdRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 10); - public static readonly uint UnLockTerminusIdResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 10); - public static readonly uint GetTerminusIdRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 11); - public static readonly uint GetTerminusIdResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 11); - - public static readonly uint TransferTerminusRequest = Create(OpCodeProtocolType.Bson, OpCodeType.InnerRouteRequest, 1); - public static readonly uint TransferTerminusResponse = Create(OpCodeProtocolType.Bson, OpCodeType.InnerRouteResponse, 1); - - public static uint Create(uint opCodeProtocolType, uint protocol, uint index) - { - return new OpCodeIdStruct(opCodeProtocolType, protocol, index); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Pack/InnerPackInfo.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Pack/InnerPackInfo.cs deleted file mode 100644 index e9870e7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Pack/InnerPackInfo.cs +++ /dev/null @@ -1,79 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Pool; -using Fantasy.Serialize; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. -#if FANTASY_NET -namespace Fantasy.PacketParser -{ - public sealed class InnerPackInfo : APackInfo - { - private readonly Dictionary> _createInstances = new Dictionary>(); - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - var network = Network; - base.Dispose(); - network.ReturnInnerPackInfo(this); - } - - public static InnerPackInfo Create(ANetwork network) - { - var innerPackInfo = network.RentInnerPackInfo(); - innerPackInfo.Network = network; - innerPackInfo.IsDisposed = false; - return innerPackInfo; - } - - public override MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0) - { - return MemoryStream ??= Network.MemoryStreamBufferPool.RentMemoryStream(memoryStreamBufferSource, size); - } - - public override object Deserialize(Type messageType) - { - if (MemoryStream == null) - { - Log.Debug("Deserialize MemoryStream is null"); - return null; - } - - MemoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (MemoryStream.Length == 0) - { - if (_createInstances.TryGetValue(messageType, out var createInstance)) - { - return createInstance(); - } - - createInstance = CreateInstance.CreateObject(messageType); - _createInstances.Add(messageType, createInstance); - return createInstance(); - } - - if (SerializerManager.TryGetSerializer(OpCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - var obj = serializer.Deserialize(messageType, MemoryStream); - MemoryStream.Seek(0, SeekOrigin.Begin); - return obj; - } - - MemoryStream.Seek(0, SeekOrigin.Begin); - Log.Error($"protocolCode:{ProtocolCode} Does not support processing protocol"); - return null; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Pack/OuterPackInfo.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Pack/OuterPackInfo.cs deleted file mode 100644 index 8ce08b7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Pack/OuterPackInfo.cs +++ /dev/null @@ -1,73 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using System; -using System.IO; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Serialize; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -namespace Fantasy.PacketParser -{ - public sealed class OuterPackInfo : APackInfo - { - public override void Dispose() - { - if (IsDisposed) - { - return; - } - var network = Network; - base.Dispose(); - network.ReturnOuterPackInfo(this); - } - - public static OuterPackInfo Create(ANetwork network) - { - var outerPackInfo = network.RentOuterPackInfo(); - outerPackInfo.Network = network; - outerPackInfo.IsDisposed = false; - return outerPackInfo; - } - - public override MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0) - { - if (MemoryStream == null) - { - MemoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(memoryStreamBufferSource, size); - } - - return MemoryStream; - } - - /// - /// 将消息数据从内存反序列化为指定的消息类型实例。 - /// - /// 目标消息类型。 - /// 反序列化后的消息类型实例。 - public override object Deserialize(Type messageType) - { - if (MemoryStream == null) - { - Log.Debug("Deserialize MemoryStream is null"); - return null; - } - - MemoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(OpCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - var obj = serializer.Deserialize(messageType, MemoryStream); - MemoryStream.Seek(0, SeekOrigin.Begin); - return obj; - } - - MemoryStream.Seek(0, SeekOrigin.Begin); - Log.Error($"protocolCode:{ProtocolCode} Does not support processing protocol"); - return null; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Pack/ProcessPackInfo.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Pack/ProcessPackInfo.cs deleted file mode 100644 index fb28df6..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Pack/ProcessPackInfo.cs +++ /dev/null @@ -1,160 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Pool; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. -namespace Fantasy.PacketParser -{ - public sealed class ProcessPackInfo : APackInfo - { - private int _disposeCount; - public Type MessageType { get; private set; } - private static readonly ConcurrentQueue Caches = new ConcurrentQueue(); - private readonly ConcurrentDictionary> _createInstances = new ConcurrentDictionary>(); - - public override void Dispose() - { - if (--_disposeCount > 0 || IsDisposed) - { - return; - } - - _disposeCount = 0; - MessageType = null; - base.Dispose(); - - if (Caches.Count > 2000) - { - return; - } - - Caches.Enqueue(this); - } - - public static unsafe ProcessPackInfo Create(Scene scene, T message, int disposeCount, uint rpcId = 0, long routeId = 0) where T : IRouteMessage - { - if (!Caches.TryDequeue(out var packInfo)) - { - packInfo = new ProcessPackInfo(); - } - - var type = typeof(T); - var memoryStreamLength = 0; - packInfo._disposeCount = disposeCount; - packInfo.MessageType = type; - packInfo.IsDisposed = false; - var memoryStream = new MemoryStreamBuffer(); - memoryStream.MemoryStreamBufferSource = MemoryStreamBufferSource.Pack; - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(type, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{type} Does not support processing protocol"); - } - - var opCode = scene.MessageDispatcherComponent.GetOpCode(packInfo.MessageType); - var packetBodyCount = memoryStreamLength - Packet.InnerPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > ProgramDefine.MaxMessageSize) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {ProgramDefine.MaxMessageSize} bytes"); - } - - var buffer = memoryStream.GetBuffer(); - - fixed (byte* bufferPtr = buffer) - { - var opCodePtr = bufferPtr + Packet.PacketLength; - var rpcIdPtr = bufferPtr + Packet.InnerPacketRpcIdLocation; - var routeIdPtr = bufferPtr + Packet.InnerPacketRouteRouteIdLocation; - *(int*)bufferPtr = packetBodyCount; - *(uint*)opCodePtr = opCode; - *(uint*)rpcIdPtr = rpcId; - *(long*)routeIdPtr = routeId; - } - - memoryStream.Seek(0, SeekOrigin.Begin); - packInfo.MemoryStream = memoryStream; - return packInfo; - } - - public unsafe void Set(uint rpcId, long routeId) - { - var buffer = MemoryStream.GetBuffer(); - - fixed (byte* bufferPtr = buffer) - { - var rpcIdPtr = bufferPtr + Packet.InnerPacketRpcIdLocation; - var routeIdPtr = bufferPtr + Packet.InnerPacketRouteRouteIdLocation; - *(uint*)rpcIdPtr = rpcId; - *(long*)routeIdPtr = routeId; - } - - MemoryStream.Seek(0, SeekOrigin.Begin); - } - - public override MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0) - { - throw new NotImplementedException(); - } - - public override object Deserialize(Type messageType) - { - if (MemoryStream == null) - { - Log.Debug("Deserialize MemoryStream is null"); - return null; - } - - object obj = null; - MemoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (MemoryStream.Length == 0) - { - if (_createInstances.TryGetValue(messageType, out var createInstance)) - { - return createInstance(); - } - - createInstance = CreateInstance.CreateObject(messageType); - _createInstances.TryAdd(messageType, createInstance); - return createInstance(); - } - - if (SerializerManager.TryGetSerializer(OpCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - obj = serializer.Deserialize(messageType, MemoryStream); - MemoryStream.Seek(0, SeekOrigin.Begin); - return obj; - } - - MemoryStream.Seek(0, SeekOrigin.Begin); - Log.Error($"protocolCode:{ProtocolCode} Does not support processing protocol"); - return null; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Packet.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Packet.cs deleted file mode 100644 index 1067996..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/Packet.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace Fantasy.PacketParser -{ - /// - /// 提供关于消息包的常量定义。 - /// - public struct Packet - { - /// - /// 消息体长度在消息头占用的长度 - /// - public const int PacketLength = sizeof(int); - /// - /// 协议编号在消息头占用的长度 - /// - public const int ProtocolCodeLength = sizeof(uint); - /// - /// RouteId长度 - /// - public const int PacketRouteIdLength = sizeof(long); - /// - /// RpcId在消息头占用的长度 - /// - public const int RpcIdLength = sizeof(uint); - /// - /// OuterRPCId所在的位置 - /// - public const int OuterPacketRpcIdLocation = PacketLength + ProtocolCodeLength; - /// - /// InnerRPCId所在的位置 - /// - public const int InnerPacketRpcIdLocation = PacketLength + ProtocolCodeLength; - /// - /// RouteId所在的位置 - /// - public const int InnerPacketRouteRouteIdLocation = PacketLength + ProtocolCodeLength + RpcIdLength; - /// - /// 外网消息头长度(消息体长度在消息头占用的长度 + 协议编号在消息头占用的长度 + RPCId长度 + RouteId长度) - /// - public const int OuterPacketHeadLength = PacketLength + ProtocolCodeLength + RpcIdLength + PacketRouteIdLength; - /// - /// 内网消息头长度(消息体长度在消息头占用的长度 + 协议编号在消息头占用的长度 + RPCId长度 + RouteId长度) - /// - public const int InnerPacketHeadLength = PacketLength + ProtocolCodeLength + RpcIdLength + PacketRouteIdLength; - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/PacketParserFactory.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/PacketParserFactory.cs deleted file mode 100644 index 679f95d..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/PacketParser/PacketParserFactory.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; - -// ReSharper disable PossibleNullReferenceException -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. -namespace Fantasy.PacketParser -{ - internal static class PacketParserFactory - { -#if FANTASY_NET - internal static ReadOnlyMemoryPacketParser CreateServerReadOnlyMemoryPacket(ANetwork network) - { - ReadOnlyMemoryPacketParser readOnlyMemoryPacketParser = null; - - switch (network.NetworkTarget) - { - case NetworkTarget.Inner: - { - readOnlyMemoryPacketParser = new InnerReadOnlyMemoryPacketParser(); - break; - } - case NetworkTarget.Outer: - { - readOnlyMemoryPacketParser = new OuterReadOnlyMemoryPacketParser(); - break; - } - } - - readOnlyMemoryPacketParser.Scene = network.Scene; - readOnlyMemoryPacketParser.Network = network; - readOnlyMemoryPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return readOnlyMemoryPacketParser; - } - - public static BufferPacketParser CreateServerBufferPacket(ANetwork network) - { - BufferPacketParser bufferPacketParser = null; - - switch (network.NetworkTarget) - { - case NetworkTarget.Inner: - { - bufferPacketParser = new InnerBufferPacketParser(); - break; - } - case NetworkTarget.Outer: - { - bufferPacketParser = new OuterBufferPacketParser(); - break; - } - } - - bufferPacketParser.Scene = network.Scene; - bufferPacketParser.Network = network; - bufferPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return bufferPacketParser; - } -#endif - internal static ReadOnlyMemoryPacketParser CreateClientReadOnlyMemoryPacket(ANetwork network) - { - ReadOnlyMemoryPacketParser readOnlyMemoryPacketParser = null; - - switch (network.NetworkTarget) - { -#if FANTASY_NET - case NetworkTarget.Inner: - { - readOnlyMemoryPacketParser = new InnerReadOnlyMemoryPacketParser(); - break; - } -#endif - case NetworkTarget.Outer: - { - readOnlyMemoryPacketParser = new OuterReadOnlyMemoryPacketParser(); - break; - } - } - - readOnlyMemoryPacketParser.Scene = network.Scene; - readOnlyMemoryPacketParser.Network = network; - readOnlyMemoryPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return readOnlyMemoryPacketParser; - } - -#if !FANTASY_WEBGL - public static BufferPacketParser CreateClientBufferPacket(ANetwork network) - { - BufferPacketParser bufferPacketParser = null; - - switch (network.NetworkTarget) - { -#if FANTASY_NET - case NetworkTarget.Inner: - { - bufferPacketParser = new InnerBufferPacketParser(); - break; - } -#endif - case NetworkTarget.Outer: - { - bufferPacketParser = new OuterBufferPacketParser(); - break; - } - } - - bufferPacketParser.Scene = network.Scene; - bufferPacketParser.Network = network; - bufferPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return bufferPacketParser; - } -#endif - public static T CreateClient(ANetwork network) where T : APacketParser - { - var packetParserType = typeof(T); - - switch (network.NetworkTarget) - { -#if FANTASY_NET - case NetworkTarget.Inner: - { - APacketParser innerPacketParser = null; - - if (packetParserType == typeof(ReadOnlyMemoryPacketParser)) - { - innerPacketParser = new InnerReadOnlyMemoryPacketParser(); - } - else if (packetParserType == typeof(BufferPacketParser)) - { - innerPacketParser = new InnerBufferPacketParser(); - } - // else if(packetParserType == typeof(CircularBufferPacketParser)) - // { - // innerPacketParser = new InnerCircularBufferPacketParser(); - // } - - innerPacketParser.Scene = network.Scene; - innerPacketParser.Network = network; - innerPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return (T)innerPacketParser; - } -#endif - case NetworkTarget.Outer: - { - APacketParser outerPacketParser = null; - - if (packetParserType == typeof(ReadOnlyMemoryPacketParser)) - { - outerPacketParser = new OuterReadOnlyMemoryPacketParser(); - } - else if (packetParserType == typeof(BufferPacketParser)) - { -#if FANTASY_WEBGL - outerPacketParser = new OuterWebglBufferPacketParser(); -#else - outerPacketParser = new OuterBufferPacketParser(); -#endif - } - outerPacketParser.Scene = network.Scene; - outerPacketParser.Network = network; - outerPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return (T)outerPacketParser; - } - default: - throw new ArgumentOutOfRangeException(); - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/ClientMessageScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/ClientMessageScheduler.cs deleted file mode 100644 index baf981a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/ClientMessageScheduler.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Scheduler -{ -#if FANTASY_UNITY || FANTASY_CONSOLE - /// - /// 提供了一个用于客户端网络消息调度和处理的抽象基类。 - /// - public sealed class ClientMessageScheduler : ANetworkMessageScheduler - { - public ClientMessageScheduler(Scene scene) : base(scene) { } - - public override async FTask Scheduler(Session session, APackInfo packInfo) - { - await FTask.CompletedTask; - switch (packInfo.OpCodeIdStruct.Protocol) - { - case OpCodeType.OuterMessage: - case OpCodeType.OuterRequest: - case OpCodeType.OuterAddressableMessage: - case OpCodeType.OuterAddressableRequest: - case OpCodeType.OuterCustomRouteMessage: - case OpCodeType.OuterCustomRouteRequest: - case OpCodeType.OuterRoamingMessage: - case OpCodeType.OuterRoamingRequest: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var message = packInfo.Deserialize(messageType); - MessageDispatcherComponent.MessageHandler(session, messageType, message, packInfo.RpcId, packInfo.ProtocolCode); - } - - return; - } - case OpCodeType.OuterResponse: - case OpCodeType.OuterPingResponse: - case OpCodeType.OuterAddressableResponse: - case OpCodeType.OuterCustomRouteResponse: - case OpCodeType.OuterRoamingResponse: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - // 这个一般是客户端Session.Call发送时使用的、目前这个逻辑只有Unity客户端时使用 - - var aResponse = (IResponse)packInfo.Deserialize(messageType); - - if (!session.RequestCallback.Remove(packInfo.RpcId, out var action)) - { - Log.Error($"not found rpc {packInfo.RpcId}, response message: {aResponse.GetType().Name}"); - return; - } - - action.SetResult(aResponse); - } - - return; - } - default: - { - packInfo.Dispose(); - throw new NotSupportedException($"Received unsupported message protocolCode:{packInfo.ProtocolCode}"); - } - } - } - } -#endif -#if FANTASY_NET - internal sealed class ClientMessageScheduler(Scene scene) : ANetworkMessageScheduler(scene) - { - public override FTask Scheduler(Session session, APackInfo packInfo) - { - throw new NotSupportedException($"ClientMessageScheduler Received unsupported message protocolCode:{packInfo.ProtocolCode}"); - } - } -#endif -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/InnerMessageScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/InnerMessageScheduler.cs deleted file mode 100644 index b1b55f6..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/InnerMessageScheduler.cs +++ /dev/null @@ -1,211 +0,0 @@ -#if FANTASY_NET -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using System.Runtime.CompilerServices; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.PacketParser.Interface; -#pragma warning disable CS8604 // Possible null reference argument. - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Scheduler -{ - /// - /// 提供了一个机制来调度和处理内部网络消息。 - /// - internal sealed class InnerMessageScheduler(Scene scene) : ANetworkMessageScheduler(scene) - { - public override async FTask Scheduler(Session session, APackInfo packInfo) - { - var protocol = packInfo.OpCodeIdStruct.Protocol; - - switch (protocol) - { - case OpCodeType.InnerMessage: - case OpCodeType.InnerRequest: - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - try - { - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var message = packInfo.Deserialize(messageType); - MessageDispatcherComponent.MessageHandler(session, messageType, message, packInfo.RpcId, packInfo.ProtocolCode); - } - catch (Exception e) - { - Log.Error($"ANetworkMessageScheduler OuterResponse error messageProtocolCode:{packInfo.ProtocolCode} messageType:{messageType} SessionId {session.Id} IsDispose {session.IsDisposed} {e}"); - } - finally - { - packInfo.Dispose(); - } - - return; - } - case OpCodeType.InnerResponse: - case OpCodeType.InnerRouteResponse: - case OpCodeType.InnerAddressableResponse: - case OpCodeType.InnerRoamingResponse: - case OpCodeType.OuterAddressableResponse: - case OpCodeType.OuterCustomRouteResponse: - case OpCodeType.OuterRoamingResponse: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - NetworkMessagingComponent.ResponseHandler(packInfo.RpcId, (IResponse)packInfo.Deserialize(messageType)); - } - - return; - } - case OpCodeType.InnerRouteMessage: - case OpCodeType.InnerAddressableMessage: - case OpCodeType.InnerRoamingMessage: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"InnerMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - if (!Scene.TryGetEntity(packInfo.RouteId, out var entity)) - { - Scene.MessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, packInfo.RpcId); - return; - } - - var obj = packInfo.Deserialize(messageType); - await Scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, (IMessage)obj, packInfo.RpcId); - } - - return; - } - case OpCodeType.InnerRouteRequest: - case OpCodeType.InnerAddressableRequest: - case OpCodeType.InnerRoamingRequest: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"InnerMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - if (!Scene.TryGetEntity(packInfo.RouteId, out var entity)) - { - Scene.MessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, packInfo.RpcId); - return; - } - - var obj = packInfo.Deserialize(messageType); - await Scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, (IMessage)obj, packInfo.RpcId); - } - - return; - } - case OpCodeType.OuterCustomRouteRequest: - case OpCodeType.OuterAddressableRequest: - case OpCodeType.OuterAddressableMessage: - case OpCodeType.OuterCustomRouteMessage: - case OpCodeType.OuterRoamingMessage: - case OpCodeType.OuterRoamingRequest: - { - var entity = Scene.GetEntity(packInfo.RouteId); - - switch (entity) - { - case null: - { - // 执行到这里有两种情况: - using (packInfo) - { - switch (Scene.SceneConfig.SceneTypeString) - { - case "Gate": - { - // 1、当前是Gate进行,需要转发消息给客户端,但当前这个Session已经断开了。 - // 这种情况不需要做任何处理。 - return; - } - default: - { - // 2、当前是其他Scene、消息通过Gate发送到这个Scene上面,但这个Scene上面没有这个Entity。 - // 因为这个是Gate转发消息到这个Scene的,如果没有找到Entity要返回错误给Gate。 - // 出现这个情况一定要打印日志,因为出现这个问题肯定是上层逻辑导致的,不应该出现这样的问题。 - var packInfoRouteId = packInfo.RouteId; - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - switch (protocol) - { - case OpCodeType.OuterCustomRouteRequest: - case OpCodeType.OuterAddressableRequest: - case OpCodeType.OuterAddressableMessage: - { - Scene.MessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, packInfo.RpcId); - return; - } - } - - throw new Exception($"The Entity associated with RouteId = {packInfoRouteId} was not found! messageType = {messageType.FullName} protocol = {protocol}"); - } - } - } - } - case Session gateSession: - { - using (packInfo) - { - // 这里如果是Session只可能是Gate的Session、如果是的话、肯定是转发消息 - gateSession.Send(packInfo.MemoryStream, packInfo.RpcId); - } - - return; - } - default: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"InnerMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var obj = packInfo.Deserialize(messageType); - await Scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, (IMessage)obj, packInfo.RpcId); - } - - return; - } - } - } - default: - { - var infoProtocolCode = packInfo.ProtocolCode; - packInfo.Dispose(); - throw new NotSupportedException($"InnerMessageScheduler Received unsupported message protocolCode:{infoProtocolCode}"); - } - } - } - } -} -#endif - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/Interface/ANetworkMessageScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/Interface/ANetworkMessageScheduler.cs deleted file mode 100644 index b296cff..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/Interface/ANetworkMessageScheduler.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.IO; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -// ReSharper disable UnassignedField.Global -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -namespace Fantasy.Scheduler -{ - public abstract class ANetworkMessageScheduler - { - protected readonly Scene Scene; - protected readonly MessageDispatcherComponent MessageDispatcherComponent; -#if FANTASY_NET - protected readonly NetworkMessagingComponent NetworkMessagingComponent; -#endif - protected ANetworkMessageScheduler(Scene scene) - { - Scene = scene; - MessageDispatcherComponent = scene.MessageDispatcherComponent; -#if FANTASY_NET - NetworkMessagingComponent = scene.NetworkMessagingComponent; -#endif - } - public abstract FTask Scheduler(Session session, APackInfo packInfo); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/MessageHelper/MessageSender.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/MessageHelper/MessageSender.cs deleted file mode 100644 index c645183..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/MessageHelper/MessageSender.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Network.Interface; - -#pragma warning disable CS8625 -#pragma warning disable CS8618 - -namespace Fantasy.Scheduler -{ - /// - /// 网络消息发送者的类。 - /// - public struct MessageSender : IDisposable - { - /// - /// 获取或设置 RPC ID。 - /// - public uint RpcId { get; private set; } - /// - /// 获取或设置路由 ID。 - /// - public long RouteId { get; private set; } - /// - /// 获取或设置创建时间。 - /// - public long CreateTime { get; private set; } - /// - /// 获取或设置消息类型。 - /// - public Type MessageType { get; private set; } - /// - /// 获取或设置请求消息。 - /// - public IMessage Request { get; private set; } - /// - /// 获取或设置任务。 - /// - public FTask Tcs { get; private set; } - - /// - /// 释放资源。 - /// - public void Dispose() - { - RpcId = 0; - RouteId = 0; - CreateTime = 0; - Tcs = null; - Request = null; - MessageType = null; - } - - /// - /// 创建一个 实例。 - /// - /// RPC ID。 - /// 请求消息类型。 - /// 任务。 - /// 创建的 实例。 - public static MessageSender Create(uint rpcId, Type requestType, FTask tcs) - { - var routeMessageSender = new MessageSender(); - routeMessageSender.Tcs = tcs; - routeMessageSender.RpcId = rpcId; - routeMessageSender.MessageType = requestType; - routeMessageSender.CreateTime = TimeHelper.Now; - return routeMessageSender; - } - - /// - /// 创建一个 实例。 - /// - /// RPC ID。 - /// 请求消息。 - /// 任务。 - /// 创建的 实例。 - public static MessageSender Create(uint rpcId, IRequest request, FTask tcs) - { - var routeMessageSender = new MessageSender(); - routeMessageSender.Tcs = tcs; - routeMessageSender.RpcId = rpcId; - routeMessageSender.Request = request; - routeMessageSender.CreateTime = TimeHelper.Now; - return routeMessageSender; - } - - /// - /// 创建一个 实例。 - /// - /// RPC ID。 - /// 路由 ID。 - /// 路由消息请求。 - /// 任务。 - /// 创建的 实例。 - public static MessageSender Create(uint rpcId, long routeId, IRouteMessage request, FTask tcs) - { - var routeMessageSender = new MessageSender(); - routeMessageSender.Tcs = tcs; - routeMessageSender.RpcId = rpcId; - routeMessageSender.RouteId = routeId; - routeMessageSender.Request = request; - routeMessageSender.CreateTime = TimeHelper.Now; - return routeMessageSender; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/MessageHelper/NetworkMessagingComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/MessageHelper/NetworkMessagingComponent.cs deleted file mode 100644 index 7580dd9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/MessageHelper/NetworkMessagingComponent.cs +++ /dev/null @@ -1,273 +0,0 @@ -#if FANTASY_NET -using Fantasy.Entitas; -using System.Runtime.CompilerServices; -using Fantasy.Async; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Network.Route; -using Fantasy.PacketParser; -using Fantasy.PacketParser.Interface; -using Fantasy.Timer; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Scheduler -{ - public struct NetworkMessageUpdate - { - public NetworkMessagingComponent NetworkMessagingComponent; - } - - public class NetworkMessagingComponentAwakeSystem : AwakeSystem - { - protected override void Awake(NetworkMessagingComponent self) - { - var selfScene = self.Scene; - self.TimerComponent = selfScene.TimerComponent; - self.MessageDispatcherComponent = selfScene.MessageDispatcherComponent; - self.AddressableRouteMessageLock = selfScene.CoroutineLockComponent.Create(self.GetType().TypeHandle.Value.ToInt64()); - - self.TimerId = self.TimerComponent.Net.RepeatedTimer(10000, new NetworkMessageUpdate() - { - NetworkMessagingComponent = self - }); - } - } - - public class NetworkMessagingComponentDestroySystem : DestroySystem - { - protected override void Destroy(NetworkMessagingComponent self) - { - if (self.TimerId != 0) - { - self.TimerComponent.Net.Remove(ref self.TimerId); - } - - foreach (var (rpcId, messageSender) in self.RequestCallback.ToDictionary()) - { - self.ReturnMessageSender(rpcId, messageSender); - } - - self.AddressableRouteMessageLock.Dispose(); - - self.RequestCallback.Clear(); - self.TimeoutRouteMessageSenders.Clear(); - self.TimerComponent = null; - self.MessageDispatcherComponent = null; - self.AddressableRouteMessageLock = null; - } - } - public sealed class NetworkMessagingComponent : Entity - { - public long TimerId; - private uint _rpcId; - public CoroutineLock AddressableRouteMessageLock; - public TimerComponent TimerComponent; - public MessageDispatcherComponent MessageDispatcherComponent; - public readonly SortedDictionary RequestCallback = new(); - public readonly Dictionary TimeoutRouteMessageSenders = new(); - - public void SendInnerRoute(long routeId, IRouteMessage message) - { - if (routeId == 0) - { - Log.Error($"SendInnerRoute appId == 0"); - return; - } - - Scene.GetSession(routeId).Send(message, 0, routeId); - } - - internal void SendInnerRoute(long routeId, Type messageType, APackInfo packInfo) - { - if (routeId == 0) - { - Log.Error($"SendInnerRoute routeId == 0"); - return; - } - - Scene.GetSession(routeId).Send(0, routeId, messageType, packInfo); - } - - public void SendInnerRoute(ICollection routeIdCollection, IRouteMessage message) - { - if (routeIdCollection.Count <= 0) - { - Log.Error("SendInnerRoute routeIdCollection.Count <= 0"); - return; - } - - using var processPackInfo = ProcessPackInfo.Create(Scene, message, routeIdCollection.Count); - foreach (var routeId in routeIdCollection) - { - processPackInfo.Set(0, routeId); - Scene.GetSession(routeId).Send(processPackInfo, 0, routeId); - } - } - - public async FTask SendAddressable(long addressableId, IRouteMessage message) - { - await CallAddressable(addressableId, message); - } - - internal async FTask CallInnerRoute(long routeId, Type requestType, APackInfo packInfo) - { - if (routeId == 0) - { - Log.Error($"CallInnerRoute routeId == 0"); - return null; - } - - var rpcId = ++_rpcId; - var session = Scene.GetSession(routeId); - var requestCallback = FTask.Create(false); - RequestCallback.Add(rpcId, MessageSender.Create(rpcId, requestType, requestCallback)); - session.Send(rpcId, routeId, requestType, packInfo); - return await requestCallback; - } - - public async FTask CallInnerRouteBySession(Session session, long routeId, IRouteMessage request) - { - var rpcId = ++_rpcId; - var requestCallback = FTask.Create(false); - RequestCallback.Add(rpcId, MessageSender.Create(rpcId, request, requestCallback)); - session.Send(request, rpcId, routeId); - return await requestCallback; - } - - public async FTask CallInnerRoute(long routeId, IRouteMessage request) - { - if (routeId == 0) - { - Log.Error($"CallInnerRoute routeId == 0"); - return null; - } - - var rpcId = ++_rpcId; - var session = Scene.GetSession(routeId); - var requestCallback = FTask.Create(false); - RequestCallback.Add(rpcId, MessageSender.Create(rpcId, request, requestCallback)); - session.Send(request, rpcId, routeId); - return await requestCallback; - } - - public async FTask CallAddressable(long addressableId, IRouteMessage request) - { - var failCount = 0; - - using (await AddressableRouteMessageLock.Wait(addressableId, "CallAddressable")) - { - var addressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, addressableId); - - while (true) - { - if (addressableRouteId == 0) - { - addressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, addressableId); - } - - if (addressableRouteId == 0) - { - return MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoute); - } - - var iRouteResponse = await CallInnerRoute(addressableRouteId, request); - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrNotFoundRoute: - { - if (++failCount > 20) - { - Log.Error($"AddressableComponent.Call failCount > 20 route send message fail, routeId: {addressableRouteId} AddressableMessageComponent:{addressableId}"); - return iRouteResponse; - } - - await TimerComponent.Net.WaitAsync(500); - addressableRouteId = 0; - continue; - } - case InnerErrorCode.ErrRouteTimeout: - { - Log.Error($"CallAddressableRoute ErrorCode.ErrRouteTimeout Error:{iRouteResponse.ErrorCode} Message:{request}"); - return iRouteResponse; - } - default: - { - return iRouteResponse; - } - } - } - } - } - - public void ResponseHandler(uint rpcId, IResponse response) - { - if (!RequestCallback.Remove(rpcId, out var routeMessageSender)) - { - throw new Exception($"not found rpc, response.RpcId:{rpcId} response message: {response.GetType().Name} Process:{Scene.Process.Id} Scene:{Scene.SceneConfigId}"); - } - - ResponseHandler(routeMessageSender, response); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void ResponseHandler(MessageSender messageSender, IResponse response) - { - if (response.ErrorCode == InnerErrorCode.ErrRouteTimeout) - { -#if FANTASY_DEVELOP - messageSender.Tcs.SetException(new Exception($"Rpc error: request, 注意RouteId消息超时,请注意查看是否死锁或者没有reply: RouteId: {messageSender.RouteId} {messageSender.Request.ToJson()}, response: {response}")); -#else - messageSender.Tcs.SetException(new Exception($"Rpc error: request, 注意RouteId消息超时,请注意查看是否死锁或者没有reply: RouteId: {messageSender.RouteId} {messageSender.Request}, response: {response}")); -#endif - messageSender.Dispose(); - return; - } - - messageSender.Tcs.SetResult(response); - messageSender.Dispose(); - } - - public void ReturnMessageSender(uint rpcId, MessageSender messageSender) - { - try - { - switch (messageSender.Request) - { - case IRouteMessage iRouteMessage: - { - // IRouteMessage是个特殊的RPC协议、这里不处理就可以了。 - break; - } - case IRequest iRequest: - { - var response = MessageDispatcherComponent.CreateResponse(iRequest.GetType(), InnerErrorCode.ErrRpcFail); - var responseRpcId = messageSender.RpcId; - ResponseHandler(responseRpcId, response); - Log.Warning($"timeout rpcId:{rpcId} responseRpcId:{responseRpcId} {iRequest.ToJson()}"); - break; - } - default: - { - Log.Error(messageSender.Request != null - ? $"Unsupported protocol type {messageSender.Request.GetType()} rpcId:{rpcId} messageSender.Request != null" - : $"Unsupported protocol type:{messageSender.MessageType.FullName} rpcId:{rpcId}"); - RequestCallback.Remove(rpcId); - break; - } - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/MessageHelper/OnNetworkMessageUpdateCheckTimeout.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/MessageHelper/OnNetworkMessageUpdateCheckTimeout.cs deleted file mode 100644 index 7dd2ea3..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/MessageHelper/OnNetworkMessageUpdateCheckTimeout.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Fantasy.Helper; -using Fantasy.Timer; - -#if FANTASY_NET -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -namespace Fantasy.Scheduler -{ - /// - /// 网络消息更新检查超时。 - /// - public sealed class OnNetworkMessageUpdateCheckTimeout : TimerHandler - { - /// - /// 超时时间(毫秒)。 - /// - private const long Timeout = 40000; - - /// - /// 处理网络消息更新检查超时。 - /// - /// - /// - protected override void Handler(NetworkMessageUpdate self) - { - var timeNow = TimeHelper.Now; - var selfNetworkMessagingComponent = self.NetworkMessagingComponent; - - // 遍历请求回调字典,检查是否有超时的请求,将超时请求添加到超时消息发送列表中。 - - foreach (var (rpcId, value) in selfNetworkMessagingComponent.RequestCallback) - { - if (timeNow < value.CreateTime + Timeout) - { - break; - } - - selfNetworkMessagingComponent.TimeoutRouteMessageSenders.Add(rpcId, value); - } - - // 如果没有超时的请求,直接返回。 - - if (selfNetworkMessagingComponent.TimeoutRouteMessageSenders.Count == 0) - { - return; - } - - // 处理超时的请求,根据请求类型生成相应的响应消息,并进行处理。 - - foreach (var (rpcId, routeMessageSender) in selfNetworkMessagingComponent.TimeoutRouteMessageSenders) - { - selfNetworkMessagingComponent.ReturnMessageSender(rpcId, routeMessageSender); - } - - // 清空超时消息发送列表。 - - selfNetworkMessagingComponent.TimeoutRouteMessageSenders.Clear(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/OuterMessageScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/OuterMessageScheduler.cs deleted file mode 100644 index 2c963ff..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Message/Scheduler/OuterMessageScheduler.cs +++ /dev/null @@ -1,366 +0,0 @@ -using System; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.PacketParser.Interface; -#if FANTASY_NET -using System.Text; -using Fantasy.Network.Interface; -using Fantasy.Network.Route; -using Fantasy.PacketParser; -using Fantasy.Helper; -using Fantasy.InnerMessage; -using Fantasy.Roaming; -#endif - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -namespace Fantasy.Scheduler -{ - /// - /// 提供了一个机制来调度和处理外部网络消息。 - /// -#if FANTASY_UNITY - public sealed class OuterMessageScheduler : ANetworkMessageScheduler - { - public OuterMessageScheduler(Scene scene) : base(scene) { } - - /// - /// 在Unity环境下,处理外部消息的方法。 - /// - /// 网络会话。 - /// 消息封包信息。 - public override FTask Scheduler(Session session, APackInfo packInfo) - { - throw new NotSupportedException($"Received unsupported message protocolCode:{packInfo.ProtocolCode}"); - } - } -#endif -#if FANTASY_NET - internal sealed class OuterMessageScheduler(Scene scene) : ANetworkMessageScheduler(scene) - { - private readonly PingResponse _pingResponse = new PingResponse(); - public override async FTask Scheduler(Session session, APackInfo packInfo) - { - if (session.IsDisposed) - { - return; - } - - switch (packInfo.OpCodeIdStruct.Protocol) - { - case OpCodeType.OuterPingRequest: - { - // 注意心跳目前只有外网才才会有、内网之间不需要心跳。 - - session.LastReceiveTime = TimeHelper.Now; - _pingResponse.Now = session.LastReceiveTime; - - using (packInfo) - { - session.Send(_pingResponse, packInfo.RpcId); - } - - return; - } - case OpCodeType.OuterMessage: - case OpCodeType.OuterRequest: - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - try - { - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var message = packInfo.Deserialize(messageType); - MessageDispatcherComponent.MessageHandler(session, messageType, message, packInfo.RpcId, packInfo.ProtocolCode); - } - catch (Exception e) - { - Log.Error($"ANetworkMessageScheduler OuterResponse error messageProtocolCode:{packInfo.ProtocolCode} messageType:{messageType} SessionId {session.Id} IsDispose {session.IsDisposed} {e}"); - } - finally - { - packInfo.Dispose(); - } - - return; - } - case OpCodeType.OuterResponse: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - NetworkMessagingComponent.ResponseHandler(packInfo.RpcId, (IResponse)packInfo.Deserialize(messageType)); - } - - return; - } - case OpCodeType.OuterAddressableMessage: - { - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var addressableRouteComponent = session.AddressableRouteComponent; - - if (addressableRouteComponent == null) - { - throw new Exception("OuterMessageScheduler error session does not have an AddressableRouteComponent component"); - } - - await addressableRouteComponent.Send(messageType, packInfo); - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterAddressableRequest: - { - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var addressableRouteComponent = session.AddressableRouteComponent; - - if (addressableRouteComponent == null) - { - throw new Exception("OuterMessageScheduler error session does not have an AddressableRouteComponent component"); - } - - var rpcId = packInfo.RpcId; - var runtimeId = session.RuntimeId; - var response = await addressableRouteComponent.Call(messageType, packInfo); - // session可能已经断开了,所以这里需要判断 - if (session.RuntimeId == runtimeId) - { - session.Send(response, rpcId); - } - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterCustomRouteMessage: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - if (!MessageDispatcherComponent.GetCustomRouteType(packInfoProtocolCode, out var routeType)) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var routeComponent = session.RouteComponent; - - if (routeComponent == null) - { - throw new Exception($"OuterMessageScheduler CustomRouteType session does not have an routeComponent component messageType:{messageType.FullName} ProtocolCode:{packInfo.ProtocolCode}"); - } - - if (!routeComponent.TryGetRouteId(routeType, out var routeId)) - { - throw new Exception($"OuterMessageScheduler RouteComponent cannot find RouteId with RouteType {routeType}"); - } - - NetworkMessagingComponent.SendInnerRoute(routeId, messageType, packInfo); - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterCustomRouteRequest: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - if (!MessageDispatcherComponent.GetCustomRouteType(packInfoProtocolCode, out var routeType)) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var routeComponent = session.RouteComponent; - - if (routeComponent == null) - { - throw new Exception("OuterMessageScheduler CustomRouteType session does not have an routeComponent component"); - } - - if (!routeComponent.TryGetRouteId(routeType, out var routeId)) - { - throw new Exception($"OuterMessageScheduler RouteComponent cannot find RouteId with RouteType {routeType}"); - } - - var rpcId = packInfo.RpcId; - var runtimeId = session.RuntimeId; - var response = await NetworkMessagingComponent.CallInnerRoute(routeId, messageType, packInfo); - // session可能已经断开了,所以这里需要判断 - if (session.RuntimeId == runtimeId) - { - session.Send(response, rpcId); - } - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterRoamingMessage: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - if (!MessageDispatcherComponent.GetCustomRouteType(packInfoProtocolCode, out var routeType)) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var sessionRoamingComponent = session.SessionRoamingComponent; - - if (sessionRoamingComponent == null) - { - throw new Exception($"OuterMessageScheduler Roaming session does not have an sessionRoamingComponent component messageType:{messageType.FullName} ProtocolCode:{packInfo.ProtocolCode}"); - } - - await sessionRoamingComponent.Send(routeType, messageType, packInfo); - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterRoamingRequest: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - if (!MessageDispatcherComponent.GetCustomRouteType(packInfoProtocolCode, out var routeType)) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var sessionRoamingComponent = session.SessionRoamingComponent; - - if (sessionRoamingComponent == null) - { - throw new Exception("OuterMessageScheduler Roaming session does not have an sessionRoamingComponent component"); - } - - var rpcId = packInfo.RpcId; - var runtimeId = session.RuntimeId; - var response = await sessionRoamingComponent.Call(routeType, messageType, packInfo); - // session可能已经断开了,所以这里需要判断 - if (session.RuntimeId == runtimeId) - { - session.Send(response, rpcId); - } - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - default: - { - var ipAddress = session.IsDisposed ? "null" : session.RemoteEndPoint.ToString(); - packInfo.Dispose(); - throw new NotSupportedException($"OuterMessageScheduler Received unsupported message protocolCode:{packInfo.ProtocolCode}\n1、请检查该协议所在的程序集是否在框架初始化的时候添加到框架中。\n2、如果看到这个消息表示你有可能用的老版本的导出工具,请更换为最新的导出工具。\n IP地址:{ipAddress}"); - } - } - } - } -#endif -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Exception/ScanException.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Exception/ScanException.cs deleted file mode 100644 index 43c695a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Exception/ScanException.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace Fantasy.Network -{ - /// - /// 在扫描过程中发生的异常。 - /// - public class ScanException : Exception - { - /// - /// 初始化 类的新实例。 - /// - public ScanException() { } - - /// - /// 使用指定的错误消息初始化 类的新实例。 - /// - /// 错误消息。 - public ScanException(string msg) : base(msg) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/HTTP/HTTPServerNetwork.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/HTTP/HTTPServerNetwork.cs deleted file mode 100644 index b3806fa..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/HTTP/HTTPServerNetwork.cs +++ /dev/null @@ -1,101 +0,0 @@ -#if FANTASY_NET -using System.IO; -using System.Net; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.Network.Interface; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; - -#pragma warning disable CS8604 // Possible null reference argument. - -// ReSharper disable PossibleMultipleEnumeration - -namespace Fantasy.Network.HTTP -{ - /// - /// HTTP服务器 - /// - public sealed class HTTPServerNetwork : ANetwork - { - /// - /// 初始化入口 - /// - /// - /// - /// - public void Initialize(NetworkTarget networkTarget, string bindIp, int port) - { - base.Initialize(NetworkType.Server, NetworkProtocolType.HTTP, networkTarget); - - try - { - StartAsync(bindIp, port); - } - catch (HttpListenerException e) - { - if (e.ErrorCode == 5) - { - var sb = new StringBuilder(); - sb.AppendLine("CMD管理员中输入下面命令:"); - sb.AppendLine($"netsh http add urlacl url=http://{bindIp}:{port}/ user=Everyone"); - throw new Exception(sb.ToString(), e); - } - - Log.Error(e); - } - catch (Exception e) - { - Log.Error(e); - } - } - - private void StartAsync(string bindIp, int port) - { - var builder = WebApplication.CreateBuilder(); - builder.Logging.ClearProviders(); - // 将Scene注册到 DI 容器中,传递给控制器 - builder.Services.AddSingleton(Scene); - // 注册Scene同步过滤器 - builder.Services.AddScoped(); - // 注册控制器服务 - var addControllers = builder.Services.AddControllers() - .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = null; }); - foreach (var assembly in AssemblySystem.ForEachAssembly) - { - addControllers.AddApplicationPart(assembly); - } - var app = builder.Build(); - var listenUrl = $"http://{bindIp}:{port}/";; - app.Urls.Add(listenUrl); - // 启用开发者工具 - if (app.Environment.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - // 路由注册 - app.MapControllers(); - // 开启监听 - app.RunAsync(); - Log.Info($"SceneConfigId = {Scene.SceneConfigId} HTTPServer Listen {listenUrl}"); - } - - /// - /// 移除Channel - /// - /// - /// - public override void RemoveChannel(uint channelId) - { - throw new NotImplementedException(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/HTTP/SceneContextFilter.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/HTTP/SceneContextFilter.cs deleted file mode 100644 index 2688bdc..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/HTTP/SceneContextFilter.cs +++ /dev/null @@ -1,54 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Microsoft.AspNetCore.Mvc.Filters; - -namespace Fantasy.Network.HTTP; - -/// -/// 让所有实现SceneContextFilter的控制器,都在执行的Scene下执行 -/// -public sealed class SceneContextFilter : IAsyncActionFilter -{ - private readonly Scene _scene; - - /// - /// 构造函数 - /// - /// - public SceneContextFilter(Scene scene) - { - _scene = scene; - } - - /// - /// OnActionExecutionAsync - /// - /// - /// - /// - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) - { - var tcs = FTask.Create(); - - _scene.ThreadSynchronizationContext.Post(() => - { - Action().Coroutine(); - }); - - await tcs; - return; - - async FTask Action() - { - try - { - await next(); - } - finally - { - tcs.SetResult(); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/AClientNetwork.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/AClientNetwork.cs deleted file mode 100644 index 322c811..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/AClientNetwork.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.IO; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.Interface -{ - /// - /// 抽象客户端网络基类。 - /// - public abstract class AClientNetwork : ANetwork, INetworkChannel - { - protected bool IsInit; - public Session Session { get; protected set; } - public abstract Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000); - public abstract void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message); - public override void Dispose() - { - IsInit = false; - - if (Session != null) - { - if (!Session.IsDisposed) - { - Session.Dispose(); - } - - Session = null; - } - - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/ANetwork.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/ANetwork.cs deleted file mode 100644 index fdb85f2..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/ANetwork.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using Fantasy.Entitas; -using Fantasy.PacketParser; -using Fantasy.Scheduler; -using Fantasy.Serialize; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.Interface -{ - /// - /// 抽象网络基类。 - /// - public abstract class ANetwork : Entity - { - private long _outerPackInfoId; - private Queue _outerPackInfoPool; - public readonly MemoryStreamBufferPool MemoryStreamBufferPool = new MemoryStreamBufferPool(); - - public NetworkType NetworkType { get; private set; } - public NetworkTarget NetworkTarget { get; private set; } - public NetworkProtocolType NetworkProtocolType { get; private set; } - public ANetworkMessageScheduler NetworkMessageScheduler { get; private set; } - - protected void Initialize(NetworkType networkType, NetworkProtocolType networkProtocolType, NetworkTarget networkTarget) - { - NetworkType = networkType; - NetworkTarget = networkTarget; - NetworkProtocolType = networkProtocolType; -#if FANTASY_NET - if (networkProtocolType == NetworkProtocolType.HTTP) - { - return; - } - if (networkTarget == NetworkTarget.Inner) - { - _innerPackInfoPool = new Queue(); - NetworkMessageScheduler = new InnerMessageScheduler(Scene); - return; - } -#endif - switch (networkType) - { - case NetworkType.Client: - { - _outerPackInfoPool = new Queue(); - NetworkMessageScheduler = new ClientMessageScheduler(Scene); - break; - } -#if FANTASY_NET - case NetworkType.Server: - { - _outerPackInfoPool = new Queue(); - NetworkMessageScheduler = new OuterMessageScheduler(Scene); - break; - } -#endif - } - } - - public abstract void RemoveChannel(uint channelId); - public OuterPackInfo RentOuterPackInfo() - { - if (_outerPackInfoPool.Count == 0) - { - return new OuterPackInfo() - { - PackInfoId = ++_outerPackInfoId - }; - } - - if (!_outerPackInfoPool.TryDequeue(out var outerPackInfo)) - { - return new OuterPackInfo() - { - PackInfoId = ++_outerPackInfoId - }; - } - - outerPackInfo.PackInfoId = ++_outerPackInfoId; - return outerPackInfo; - } - - public void ReturnOuterPackInfo(OuterPackInfo outerPackInfo) - { - if (_outerPackInfoPool.Count > 512) - { - // 池子里最多缓存256个、其实这样设置有点多了、其实用不了512个。 - // 反而设置越大内存会占用越多。 - return; - } - - _outerPackInfoPool.Enqueue(outerPackInfo); - } -#if FANTASY_NET - private long _innerPackInfoId; - private Queue _innerPackInfoPool; - public InnerPackInfo RentInnerPackInfo() - { - if (_innerPackInfoPool.Count == 0) - { - return new InnerPackInfo() - { - PackInfoId = ++_innerPackInfoId - }; - } - - if (!_innerPackInfoPool.TryDequeue(out var innerPackInfo)) - { - return new InnerPackInfo() - { - PackInfoId = ++_innerPackInfoId - }; - } - - innerPackInfo.PackInfoId = ++_innerPackInfoId; - return innerPackInfo; - } - - public void ReturnInnerPackInfo(InnerPackInfo innerPackInfo) - { - if (_innerPackInfoPool.Count > 256) - { - // 池子里最多缓存256个、其实这样设置有点多了、其实用不了256个。 - // 反而设置越大内存会占用越多。 - return; - } - - _innerPackInfoPool.Enqueue(innerPackInfo); - } -#endif - public override void Dispose() - { - NetworkType = NetworkType.None; - NetworkTarget = NetworkTarget.None; - NetworkProtocolType = NetworkProtocolType.None; - MemoryStreamBufferPool.Dispose(); - _outerPackInfoPool?.Clear(); -#if FANTASY_NET - _innerPackInfoPool?.Clear(); -#endif - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/ANetworkServerChannel.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/ANetworkServerChannel.cs deleted file mode 100644 index 788a235..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/ANetworkServerChannel.cs +++ /dev/null @@ -1,55 +0,0 @@ -#if FANTASY_NET -using System.IO; -using System.Net; -using Fantasy.Serialize; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.Interface -{ - public abstract class ANetworkServerChannel : INetworkChannel - { - /// - /// 获取通道的唯一标识 ID。 - /// - public readonly uint Id; - /// - /// 获取通道的远程终端点。 - /// - public readonly EndPoint RemoteEndPoint; - /// - /// 获取或设置通道所属的场景。 - /// - public Scene Scene { get; protected set; } - /// - /// 获取或设置通道所属的会话。 - /// - public Session Session { get; protected set; } - /// - /// 获取通道是否已经被释放。 - /// - public bool IsDisposed { get; protected set; } - - protected ANetworkServerChannel(ANetwork network, uint id, EndPoint remoteEndPoint) - { - Id = id; - Scene = network.Scene; - RemoteEndPoint = remoteEndPoint; - Session = Session.Create(network.NetworkMessageScheduler, this, network.NetworkTarget); - } - - public virtual void Dispose() - { - IsDisposed = true; - - if (!Session.IsDisposed) - { - Session.Dispose(); - } - } - - public abstract void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/INetworkChannel.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/INetworkChannel.cs deleted file mode 100644 index 52f341a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/Interface/INetworkChannel.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.IO; -using Fantasy.Serialize; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network.Interface -{ - public interface INetworkChannel : IDisposable - { - public Session Session { get;} - public bool IsDisposed { get;} - public void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/Kcp.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/Kcp.cs deleted file mode 100644 index 47316cb..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/Kcp.cs +++ /dev/null @@ -1,451 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Threading; -using kcp; -using static kcp.KCP; - -#pragma warning disable CS8601 -#pragma warning disable CS8602 -#pragma warning disable CS8625 - -// ReSharper disable ALL - -namespace KCP -{ - /// - /// Kcp callback - /// - /// KCP output destination - /// KCP output size (excluding reserved) - internal delegate void KcpCallback(byte[] buffer, int length); - - /// - /// Kcp - /// - internal sealed unsafe class Kcp : IDisposable - { - /// - /// Kcp - /// - private IKCPCB* _kcp; - - /// - /// Output function - /// - private KcpCallback _output; - - /// - /// Buffer - /// - private byte[] _buffer; - - /// - /// Reserved overhead - /// - private int _reserved; - - /// - /// Disposed - /// - private int _disposed; - - /// - /// Structure - /// - /// ConversationId - /// Output - /// Reserved overhead - public Kcp(uint conv, KcpCallback output, int reserved) - { - _kcp = ikcp_create(conv, reserved, ref _buffer); - _output = output; - _reserved = reserved; - } - - /// - /// Set - /// - public bool IsSet => _kcp != null; - - /// - /// Conversation id - /// - public uint ConversationId => _kcp->conv; - - /// - /// Maximum transmission unit - /// - public uint MaximumTransmissionUnit => _kcp->mtu; - - /// - /// Maximum segment size - /// - public uint MaximumSegmentSize => _kcp->mss; - - /// - /// Connection state - /// - public uint State => _kcp->state; - - /// - /// The sequence number of the first unacknowledged packet - /// - public uint SendUna => _kcp->snd_una; - - /// - /// The sequence number for the next packet to be sent - /// - public uint SendNext => _kcp->snd_nxt; - - /// - /// The sequence number for the next packet expected to be received - /// - public uint ReceiveNext => _kcp->rcv_nxt; - - /// - /// Slow start threshold for congestion control - /// - public uint SlowStartThreshold => _kcp->ssthresh; - - /// - /// Round-trip time variance - /// - public int RxRttval => _kcp->rx_rttval; - - /// - /// Smoothed round-trip time - /// - public int RxSrtt => _kcp->rx_srtt; - - /// - /// Retransmission timeout - /// - public int RxRto => _kcp->rx_rto; - - /// - /// Minimum retransmission timeout - /// - public int RxMinrto => _kcp->rx_minrto; - - /// - /// Send window size - /// - public uint SendWindowSize => _kcp->snd_wnd; - - /// - /// Receive window size - /// - public uint ReceiveWindowSize => _kcp->rcv_wnd; - - /// - /// Remote window size - /// - public uint RemoteWindowSize => _kcp->rmt_wnd; - - /// - /// Congestion window size - /// - public uint CongestionWindowSize => _kcp->cwnd; - - /// - /// Probe variable for fast recovery - /// - public uint Probe => _kcp->probe; - - /// - /// Current timestamp - /// - public uint Current => _kcp->current; - - /// - /// Flush interval - /// - public uint Interval => _kcp->interval; - - /// - /// Timestamp for the next flush - /// - public uint TimestampFlush => _kcp->ts_flush; - - /// - /// Number of retransmissions - /// - public uint Transmissions => _kcp->xmit; - - /// - /// Number of packets in the receive buffer - /// - public uint ReceiveBufferCount => _kcp->nrcv_buf; - - /// - /// Number of packets in the receive queue - /// - public uint ReceiveQueueCount => _kcp->nrcv_que; - - /// - /// Number of packets wait to receive - /// - public uint WaitReceiveCount => _kcp->nrcv_buf + _kcp->nrcv_que; - - /// - /// Number of packets in the send buffer - /// - public uint SendBufferCount => _kcp->nsnd_buf; - - /// - /// Number of packets in the send queue - /// - public uint SendQueueCount => _kcp->nsnd_que; - - /// - /// Number of packets wait to send - /// - public uint WaitSendCount => _kcp->nsnd_buf + _kcp->nsnd_que; - - /// - /// Whether Nagle's algorithm is disabled - /// - public uint NoDelay => _kcp->nodelay; - - /// - /// Whether the KCP connection has been updated - /// - public uint Updated => _kcp->updated; - - /// - /// Timestamp for the next probe - /// - public uint TimestampProbe => _kcp->ts_probe; - - /// - /// Probe wait time - /// - public uint ProbeWait => _kcp->probe_wait; - - /// - /// Incremental increase - /// - public uint Increment => _kcp->incr; - - /// - /// Pointer to the acknowledge list - /// - public uint* AckList => _kcp->acklist; - - /// - /// Count of acknowledges - /// - public uint AckCount => _kcp->ackcount; - - /// - /// Number of acknowledge blocks - /// - public uint AckBlock => _kcp->ackblock; - - /// - /// Buffer - /// - public byte[] Buffer => _buffer; - - /// - /// Fast resend trigger count - /// - public int FastResend => _kcp->fastresend; - - /// - /// Fast resend limit - /// - public int FastResendLimit => _kcp->fastlimit; - - /// - /// Whether congestion control is disabled - /// - public int NoCongestionWindow => _kcp->nocwnd; - - /// - /// Whether stream mode is enabled - /// - public int StreamMode => _kcp->stream; - - /// - /// Output function pointer - /// - public KcpCallback Output => _output; - - /// - /// Reserved overhead - /// - public int Reserved => _reserved; - - /// - /// Dispose - /// - public void Dispose() - { - if (Interlocked.CompareExchange(ref _disposed, 1, 0) != 0) - return; - ikcp_release(_kcp); - _kcp = null; - _output = null; - _buffer = null; - GC.SuppressFinalize(this); - } - - /// - /// Set output - /// - /// Output - public void SetOutput(KcpCallback output) => _output = output; - - /// - /// Destructure - /// - ~Kcp() => Dispose(); - - /// - /// Send - /// - /// Buffer - /// Sent bytes - public int Send(ReadOnlySpan buffer) - { - fixed (byte* pinnedBuffer = &MemoryMarshal.GetReference(buffer)) - { - return ikcp_send(_kcp, pinnedBuffer, buffer.Length); - } - } - - /// - /// Send - /// - /// Buffer - /// Length - /// Sent bytes - public int Send(byte* buffer, int length) => ikcp_send(_kcp, buffer, length); - - /// - /// Input - /// - /// Buffer - /// Input bytes - public int Input(ReadOnlySpan buffer) - { - fixed (byte* pinnedBuffer = &MemoryMarshal.GetReference(buffer)) - { - return ikcp_input(_kcp, pinnedBuffer, buffer.Length); - } - } - - /// - /// Input - /// - /// Buffer - /// Length - /// Input bytes - public int Input(byte* buffer, int length) => ikcp_input(_kcp, buffer, length); - - /// - /// Peek size - /// - /// Peeked size - public int PeekSize() => ikcp_peeksize(_kcp); - - /// - /// Receive - /// - /// Buffer - /// Received bytes - public int Receive(Span buffer) - { - fixed (byte* pinnedBuffer = &MemoryMarshal.GetReference(buffer)) - { - return ikcp_recv(_kcp, pinnedBuffer, buffer.Length); - } - } - - /// - /// Receive - /// - /// Buffer - /// Length - /// Received bytes - public int Receive(byte* buffer, int length) => ikcp_recv(_kcp, buffer, length); - - /// - /// Update - /// - /// Timestamp - public void Update(uint current) - { - fixed (byte* ptr = &_buffer[_reserved]) - { - ikcp_update(_kcp, current, ptr, _buffer, _output); - } - } - - /// - /// Check - /// - /// Timestamp - /// Next flush timestamp - public uint Check(uint current) => ikcp_check(_kcp, current); - - /// - /// Flush - /// - public void Flush() - { - fixed (byte* ptr = &_buffer[_reserved]) - { - ikcp_flush(_kcp, ptr, _buffer, _output); - } - } - - /// - /// Set maximum transmission unit - /// - /// Maximum transmission unit - /// Set - public int SetMtu(int mtu) => ikcp_setmtu(_kcp, mtu, _reserved, ref _buffer); - - /// - /// Set flush interval - /// - /// Flush interval - public void SetInterval(int interval) => ikcp_interval(_kcp, interval); - - /// - /// Set no delay - /// - /// Whether Nagle's algorithm is disabled - /// Flush interval - /// Fast resend trigger count - /// No congestion window - public void SetNoDelay(int nodelay, int interval, int resend, int nc) => ikcp_nodelay(_kcp, nodelay, interval, resend, nc); - - /// - /// Set window size - /// - /// Send window size - /// Receive window size - public void SetWindowSize(int sndwnd, int rcvwnd) => ikcp_wndsize(_kcp, sndwnd, rcvwnd); - - /// - /// Set fast resend limit - /// - /// Fast resend limit - public void SetFastResendLimit(int fastlimit) => _kcp->fastlimit = Math.Clamp(fastlimit, 0, 5); - - /// - /// Set whether stream mode is enabled - /// - /// Whether stream mode is enabled - public void SetStreamMode(int stream) => _kcp->stream = stream == 1 ? 1 : 0; - - /// - /// Set minimum retransmission timeout - /// - /// Minimum retransmission timeout - public void SetMinrto(int minrto) => _kcp->rx_minrto = (int)Math.Clamp(minrto, 1, IKCP_RTO_MAX); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/c/kcp.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/c/kcp.cs deleted file mode 100644 index c5c36f0..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/c/kcp.cs +++ /dev/null @@ -1,1367 +0,0 @@ -#if NET6_0_OR_GREATER -using System.Numerics; -#endif -using System.Runtime.CompilerServices; -using KCP; - -#pragma warning disable CA2211 -#pragma warning disable CS1591 -#pragma warning disable CS8602 -#pragma warning disable CS8632 - -// ReSharper disable ALL - -namespace kcp -{ - /// - /// https://github.com/skywind3000/kcp - /// - internal static unsafe partial class KCP - { - //===================================================================== - // KCP BASIC - //===================================================================== - public const uint IKCP_RTO_NDL = 30; // no delay min rto - public const uint IKCP_RTO_MIN = 100; // normal min rto - public const uint IKCP_RTO_DEF = 200; - public const uint IKCP_RTO_MAX = 60000; - public const uint IKCP_CMD_PUSH = 81; // cmd: push data - public const uint IKCP_CMD_ACK = 82; // cmd: ack - public const uint IKCP_CMD_WASK = 83; // cmd: window probe (ask) - public const uint IKCP_CMD_WINS = 84; // cmd: window size (tell) - public const uint IKCP_ASK_SEND = 1; // need to send IKCP_CMD_WASK - public const uint IKCP_ASK_TELL = 2; // need to send IKCP_CMD_WINS - public const uint IKCP_WND_SND = 32; - public const uint IKCP_WND_RCV = 128; // must >= max fragment size - public const uint IKCP_MTU_DEF = 1400; - public const uint IKCP_ACK_FAST = 3; - public const uint IKCP_INTERVAL = 100; - public const uint IKCP_OVERHEAD = 24; - public const uint IKCP_DEADLINK = 20; - public const uint IKCP_THRESH_INIT = 2; - public const uint IKCP_THRESH_MIN = 2; - public const uint IKCP_PROBE_INIT = 7000; // 7 secs to probe window size - public const uint IKCP_PROBE_LIMIT = 120000; // up to 120 secs to probe window - public const uint IKCP_FASTACK_LIMIT = 5; // max times to trigger fastack - - //--------------------------------------------------------------------- - // encode / decode - //--------------------------------------------------------------------- - - /* encode 8 bits unsigned int */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_encode8u(byte* p, byte c) - { - *(byte*)p++ = c; - return p; - } - - /* decode 8 bits unsigned int */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_decode8u(byte* p, byte* c) - { - *c = *(byte*)p++; - return p; - } - - /* encode 16 bits unsigned int (lsb) */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_encode16u(byte* p, ushort w) - { -#if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN - *(byte*)(p + 0) = (byte)(w & 255); - *(byte*)(p + 1) = (byte)(w >> 8); -#else - memcpy(p, &w, (nuint)2); -#endif - p += 2; - return p; - } - - /* decode 16 bits unsigned int (lsb) */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_decode16u(byte* p, ushort* w) - { -#if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN - *w = *(byte*)(p + 1); - *w = (ushort)(*(byte*)(p + 0) + (*w << 8)); -#else - memcpy(w, p, (nuint)2); -#endif - p += 2; - return p; - } - - /* encode 32 bits unsigned int (lsb) */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_encode32u(byte* p, uint l) - { -#if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN - *(byte*)(p + 0) = (byte)((l >> 0) & 0xff); - *(byte*)(p + 1) = (byte)((l >> 8) & 0xff); - *(byte*)(p + 2) = (byte)((l >> 16) & 0xff); - *(byte*)(p + 3) = (byte)((l >> 24) & 0xff); -#else - memcpy(p, &l, (nuint)4); -#endif - p += 4; - return p; - } - - /* decode 32 bits unsigned int (lsb) */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_decode32u(byte* p, uint* l) - { -#if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN - *l = *(byte*)(p + 3); - *l = *(byte*)(p + 2) + (*l << 8); - *l = *(byte*)(p + 1) + (*l << 8); - *l = *(byte*)(p + 0) + (*l << 8); -#else - memcpy(l, p, (nuint)4); -#endif - p += 4; - return p; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint _imin_(uint a, uint b) - { - return a <= b ? a : b; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint _imax_(uint a, uint b) - { - return a >= b ? a : b; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint _ibound_(uint lower, uint middle, uint upper) - { - return _imin_(_imax_(lower, middle), upper); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint _iceilpow2_(uint x) - { -#if NET6_0_OR_GREATER - return BitOperations.RoundUpToPowerOf2(x); -#else - --x; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - ++x; - return x; -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long _itimediff(uint later, uint earlier) - { - return ((int)(later - earlier)); - } - - // //--------------------------------------------------------------------- - // // manage segment - // //--------------------------------------------------------------------- - // public static delegate* managed ikcp_malloc_hook = null; - // public static delegate* managed ikcp_free_hook = null; - - // // internal malloc - // public static void* ikcp_malloc(nuint size) - // { - // if (ikcp_malloc_hook != null) - // return ikcp_malloc_hook(size); - // return malloc(size); - // } - - // // internal free - // public static void ikcp_free(void* ptr) - // { - // if (ikcp_free_hook != null) - // { - // ikcp_free_hook(ptr); - // } - // else - // { - // free(ptr); - // } - // } - - // // redefine allocator - // public static void ikcp_allocator(delegate* managed new_malloc, delegate* managed new_free) - // { - // ikcp_malloc_hook = new_malloc; - // ikcp_free_hook = new_free; - // } - - // allocate a new kcp segment - public static IKCPSEG* ikcp_segment_new(IKCPCB* kcp, int size) - { - return (IKCPSEG*)malloc((nuint)(sizeof(IKCPSEG) + size)); - } - - // delete a segment - public static void ikcp_segment_delete(IKCPCB* kcp, IKCPSEG* seg) - { - free(seg); - } - - // output segment - public static void ikcp_output(IKCPCB* kcp, int size, byte[] destination, KcpCallback output) - { - assert(kcp != null); - assert(output != null); - - if (size == 0) return; - output(destination, size); - } - - //--------------------------------------------------------------------- - // create a new kcpcb - //--------------------------------------------------------------------- - public static IKCPCB* ikcp_create(uint conv, int reserved, ref byte[] buffer) - { - IKCPCB* kcp = (IKCPCB*)malloc((nuint)sizeof(IKCPCB)); - if (kcp == null) return null; - kcp->conv = conv; - kcp->snd_una = 0; - kcp->snd_nxt = 0; - kcp->rcv_nxt = 0; - kcp->ts_recent = 0; - kcp->ts_lastack = 0; - kcp->ts_probe = 0; - kcp->probe_wait = 0; - kcp->snd_wnd = IKCP_WND_SND; - kcp->rcv_wnd = IKCP_WND_RCV; - kcp->rmt_wnd = IKCP_WND_RCV; - kcp->cwnd = 0; - kcp->incr = 0; - kcp->probe = 0; - kcp->mtu = IKCP_MTU_DEF; - kcp->mss = kcp->mtu - IKCP_OVERHEAD; - kcp->stream = 0; - - buffer = new byte[(reserved + kcp->mtu + IKCP_OVERHEAD) * 3]; - - iqueue_init(&kcp->snd_queue); - iqueue_init(&kcp->rcv_queue); - iqueue_init(&kcp->snd_buf); - iqueue_init(&kcp->rcv_buf); - kcp->nrcv_buf = 0; - kcp->nsnd_buf = 0; - kcp->nrcv_que = 0; - kcp->nsnd_que = 0; - kcp->state = 0; - kcp->acklist = null; - kcp->ackblock = 0; - kcp->ackcount = 0; - kcp->rx_srtt = 0; - kcp->rx_rttval = 0; - kcp->rx_rto = (int)IKCP_RTO_DEF; - kcp->rx_minrto = (int)IKCP_RTO_MIN; - kcp->current = 0; - kcp->interval = IKCP_INTERVAL; - kcp->ts_flush = IKCP_INTERVAL; - kcp->nodelay = 0; - kcp->updated = 0; - kcp->ssthresh = IKCP_THRESH_INIT; - kcp->fastresend = 0; - kcp->fastlimit = (int)IKCP_FASTACK_LIMIT; - kcp->nocwnd = 0; - kcp->xmit = 0; - kcp->dead_link = IKCP_DEADLINK; - - return kcp; - } - - //--------------------------------------------------------------------- - // release a new kcpcb - //--------------------------------------------------------------------- - public static void ikcp_release(IKCPCB* kcp) - { - assert(kcp != null); - if (kcp != null) - { - IKCPSEG* seg; - while (!iqueue_is_empty(&kcp->snd_buf)) - { - seg = iqueue_entry(kcp->snd_buf.next); - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - } - - while (!iqueue_is_empty(&kcp->rcv_buf)) - { - seg = iqueue_entry(kcp->rcv_buf.next); - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - } - - while (!iqueue_is_empty(&kcp->snd_queue)) - { - seg = iqueue_entry(kcp->snd_queue.next); - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - } - - while (!iqueue_is_empty(&kcp->rcv_queue)) - { - seg = iqueue_entry(kcp->rcv_queue.next); - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - } - - if (kcp->acklist != null) - { - free(kcp->acklist); - } - - kcp->nrcv_buf = 0; - kcp->nsnd_buf = 0; - kcp->nrcv_que = 0; - kcp->nsnd_que = 0; - kcp->ackcount = 0; - kcp->acklist = null; - free(kcp); - } - } - - //--------------------------------------------------------------------- - // user/upper level recv: returns size, returns below zero for EAGAIN - //--------------------------------------------------------------------- - public static int ikcp_recv(IKCPCB* kcp, byte* buffer, int len) - { - IQUEUEHEAD* p; - int ispeek = (len < 0) ? 1 : 0; - int peeksize; - int recover = 0; - IKCPSEG* seg; - assert(kcp != null); - - if (iqueue_is_empty(&kcp->rcv_queue)) - return -1; - - if (len < 0) len = -len; - - peeksize = ikcp_peeksize(kcp); - - if (peeksize < 0) - return -2; - - if (peeksize > len) - return -3; - - if (kcp->nrcv_que >= kcp->rcv_wnd) - recover = 1; - - // merge fragment - for (len = 0, p = kcp->rcv_queue.next; p != &kcp->rcv_queue;) - { - int fragment; - seg = iqueue_entry(p); - p = p->next; - - if (buffer != null) - { - memcpy(buffer, seg->data, (nuint)seg->len); - buffer += seg->len; - } - - len += (int)seg->len; - fragment = (int)seg->frg; - - if (ispeek == 0) - { - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - kcp->nrcv_que--; - } - - if (fragment == 0) - break; - } - - assert(len == peeksize); - - // move available data from rcv_buf -> rcv_queue - while (!iqueue_is_empty(&kcp->rcv_buf)) - { - seg = iqueue_entry(kcp->rcv_buf.next); - if (seg->sn == kcp->rcv_nxt && kcp->nrcv_que < kcp->rcv_wnd) - { - iqueue_del(&seg->node); - kcp->nrcv_buf--; - iqueue_add_tail(&seg->node, &kcp->rcv_queue); - kcp->nrcv_que++; - kcp->rcv_nxt++; - } - else - { - break; - } - } - - // fast recover - if (kcp->nrcv_que < kcp->rcv_wnd && (recover != 0)) - { - // ready to send back IKCP_CMD_WINS in ikcp_flush - // tell remote my window size - kcp->probe |= IKCP_ASK_TELL; - } - - return len; - } - - //--------------------------------------------------------------------- - // peek data size - //--------------------------------------------------------------------- - public static int ikcp_peeksize(IKCPCB* kcp) - { - IQUEUEHEAD* p; - IKCPSEG* seg; - int length = 0; - - assert(kcp != null); - - if (iqueue_is_empty(&kcp->rcv_queue)) return -1; - - seg = iqueue_entry(kcp->rcv_queue.next); - if (seg->frg == 0) return (int)seg->len; - - if (kcp->nrcv_que < seg->frg + 1) return -1; - - for (p = kcp->rcv_queue.next; p != &kcp->rcv_queue; p = p->next) - { - seg = iqueue_entry(p); - length += (int)seg->len; - if (seg->frg == 0) break; - } - - return length; - } - - //--------------------------------------------------------------------- - // user/upper level send, returns below zero for error - //--------------------------------------------------------------------- - public static int ikcp_send(IKCPCB* kcp, byte* buffer, int len) - { - IKCPSEG* seg; - int count, i; - int sent = 0; - - assert(kcp->mss > 0); - if (len < 0) return -1; - - // append to previous segment in streaming mode (if possible) - if (kcp->stream != 0) - { - if (!iqueue_is_empty(&kcp->snd_queue)) - { - IKCPSEG* old = iqueue_entry(kcp->snd_queue.prev); - if (old->len < kcp->mss) - { - int capacity = (int)(kcp->mss - old->len); - int extend = (len < capacity) ? len : capacity; - seg = ikcp_segment_new(kcp, (int)(old->len + extend)); - assert(seg != null); - if (seg == null) - { - return -2; - } - - iqueue_add_tail(&seg->node, &kcp->snd_queue); - memcpy(seg->data, old->data, (nuint)old->len); - if (buffer != null) - { - memcpy(seg->data + old->len, buffer, (nuint)extend); - buffer += extend; - } - - seg->len = (uint)(old->len + extend); - seg->frg = 0; - len -= extend; - iqueue_del_init(&old->node); - ikcp_segment_delete(kcp, old); - sent = extend; - } - } - - if (len <= 0) - { - return sent; - } - } - - if (len <= (int)kcp->mss) count = 1; - else count = (int)((len + kcp->mss - 1) / kcp->mss); - - if (kcp->stream == 0 && count > 255) return -2; - - if (count >= (int)kcp->rcv_wnd) - { - if (kcp->stream != 0 && sent > 0) - return sent; - return -2; - } - - if (count == 0) count = 1; - - // fragment - for (i = 0; i < count; i++) - { - int size = len > (int)kcp->mss ? (int)kcp->mss : len; - seg = ikcp_segment_new(kcp, size); - assert(seg != null); - if (seg == null) - { - return -2; - } - - if ((buffer != null) && len > 0) - { - memcpy(seg->data, buffer, (nuint)size); - } - - seg->len = (uint)size; - seg->frg = (uint)((kcp->stream == 0) ? (count - i - 1) : 0); - iqueue_init(&seg->node); - iqueue_add_tail(&seg->node, &kcp->snd_queue); - kcp->nsnd_que++; - if (buffer != null) - { - buffer += size; - } - - len -= size; - sent += size; - } - - return sent; - } - - //--------------------------------------------------------------------- - // parse ack - //--------------------------------------------------------------------- - public static void ikcp_update_ack(IKCPCB* kcp, int rtt) - { - int rto = 0; - if (kcp->rx_srtt == 0) - { - kcp->rx_srtt = rtt; - kcp->rx_rttval = rtt / 2; - } - else - { - long delta = rtt - kcp->rx_srtt; - if (delta < 0) delta = -delta; - kcp->rx_rttval = (int)((3 * kcp->rx_rttval + delta) / 4); - kcp->rx_srtt = (7 * kcp->rx_srtt + rtt) / 8; - if (kcp->rx_srtt < 1) kcp->rx_srtt = 1; - } - - rto = (int)(kcp->rx_srtt + _imax_(kcp->interval, (uint)(4 * kcp->rx_rttval))); - kcp->rx_rto = (int)_ibound_((uint)kcp->rx_minrto, (uint)rto, IKCP_RTO_MAX); - } - - public static void ikcp_shrink_buf(IKCPCB* kcp) - { - IQUEUEHEAD* p = kcp->snd_buf.next; - if (p != &kcp->snd_buf) - { - IKCPSEG* seg = iqueue_entry(p); - kcp->snd_una = seg->sn; - } - else - { - kcp->snd_una = kcp->snd_nxt; - } - } - - public static void ikcp_parse_ack(IKCPCB* kcp, uint sn) - { - IQUEUEHEAD* p, next; - - if (_itimediff(sn, kcp->snd_una) < 0 || _itimediff(sn, kcp->snd_nxt) >= 0) - return; - - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) - { - IKCPSEG* seg = iqueue_entry(p); - next = p->next; - if (sn == seg->sn) - { - iqueue_del(p); - ikcp_segment_delete(kcp, seg); - kcp->nsnd_buf--; - break; - } - - if (_itimediff(sn, seg->sn) < 0) - { - break; - } - } - } - - public static void ikcp_parse_una(IKCPCB* kcp, uint una) - { - IQUEUEHEAD* p, next; - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) - { - IKCPSEG* seg = iqueue_entry(p); - next = p->next; - if (_itimediff(una, seg->sn) > 0) - { - iqueue_del(p); - ikcp_segment_delete(kcp, seg); - kcp->nsnd_buf--; - } - else - { - break; - } - } - } - - public static void ikcp_parse_fastack(IKCPCB* kcp, uint sn, uint ts) - { - IQUEUEHEAD* p, next; - - if (_itimediff(sn, kcp->snd_una) < 0 || _itimediff(sn, kcp->snd_nxt) >= 0) - return; - - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) - { - IKCPSEG* seg = iqueue_entry(p); - next = p->next; - if (_itimediff(sn, seg->sn) < 0) - { - break; - } - else if (sn != seg->sn) - { -#if !IKCP_FASTACK_CONSERVE - seg->fastack++; -#else - if (_itimediff(ts, seg->ts) >= 0) - seg->fastack++; -#endif - } - } - } - - //--------------------------------------------------------------------- - // ack append - //--------------------------------------------------------------------- - public static void ikcp_ack_push(IKCPCB* kcp, uint sn, uint ts) - { - uint newsize = kcp->ackcount + 1; - uint* ptr; - - if (newsize > kcp->ackblock) - { - uint* acklist; - uint newblock; - - newblock = newsize <= 8 ? 8 : _iceilpow2_(newsize); - acklist = (uint*)malloc((nuint)(newblock * sizeof(uint) * 2)); - - if (acklist == null) - { - assert(acklist != null); - abort(); - } - - if (kcp->acklist != null) - { - uint x; - for (x = 0; x < kcp->ackcount; x++) - { - acklist[x * 2 + 0] = kcp->acklist[x * 2 + 0]; - acklist[x * 2 + 1] = kcp->acklist[x * 2 + 1]; - } - - free(kcp->acklist); - } - - kcp->acklist = acklist; - kcp->ackblock = newblock; - } - - ptr = &kcp->acklist[kcp->ackcount * 2]; - ptr[0] = sn; - ptr[1] = ts; - kcp->ackcount++; - } - - public static void ikcp_ack_get(IKCPCB* kcp, int p, uint* sn, uint* ts) - { - if (sn != null) sn[0] = kcp->acklist[p * 2 + 0]; - if (ts != null) ts[0] = kcp->acklist[p * 2 + 1]; - } - - //--------------------------------------------------------------------- - // parse data - //--------------------------------------------------------------------- - public static void ikcp_parse_data(IKCPCB* kcp, IKCPSEG* newseg) - { - IQUEUEHEAD* p, prev; - uint sn = newseg->sn; - int repeat = 0; - - if (_itimediff(sn, kcp->rcv_nxt + kcp->rcv_wnd) >= 0 || - _itimediff(sn, kcp->rcv_nxt) < 0) - { - ikcp_segment_delete(kcp, newseg); - return; - } - - for (p = kcp->rcv_buf.prev; p != &kcp->rcv_buf; p = prev) - { - IKCPSEG* seg = iqueue_entry(p); - prev = p->prev; - if (seg->sn == sn) - { - repeat = 1; - break; - } - - if (_itimediff(sn, seg->sn) > 0) - { - break; - } - } - - if (repeat == 0) - { - iqueue_init(&newseg->node); - iqueue_add(&newseg->node, p); - kcp->nrcv_buf++; - } - else - { - ikcp_segment_delete(kcp, newseg); - } - - // move available data from rcv_buf -> rcv_queue - while (!iqueue_is_empty(&kcp->rcv_buf)) - { - IKCPSEG* seg = iqueue_entry(kcp->rcv_buf.next); - if (seg->sn == kcp->rcv_nxt && kcp->nrcv_que < kcp->rcv_wnd) - { - iqueue_del(&seg->node); - kcp->nrcv_buf--; - iqueue_add_tail(&seg->node, &kcp->rcv_queue); - kcp->nrcv_que++; - kcp->rcv_nxt++; - } - else - { - break; - } - } - } - - //--------------------------------------------------------------------- - // input data - //--------------------------------------------------------------------- - public static int ikcp_input(IKCPCB* kcp, byte* data, long size) - { - uint prev_una = kcp->snd_una; - uint maxack = 0, latest_ts = 0; - int flag = 0; - - if (data == null || (int)size < (int)IKCP_OVERHEAD) return -1; - - while (true) - { - uint ts, sn, len, una, conv; - ushort wnd; - byte cmd, frg; - IKCPSEG* seg; - - if (size < (int)IKCP_OVERHEAD) break; - - data = ikcp_decode32u(data, &conv); - if (conv != kcp->conv) return -1; - - data = ikcp_decode8u(data, &cmd); - data = ikcp_decode8u(data, &frg); - data = ikcp_decode16u(data, &wnd); - data = ikcp_decode32u(data, &ts); - data = ikcp_decode32u(data, &sn); - data = ikcp_decode32u(data, &una); - data = ikcp_decode32u(data, &len); - - size -= IKCP_OVERHEAD; - - if ((long)size < (long)len || (int)len < 0) return -2; - - if (cmd != IKCP_CMD_PUSH && cmd != IKCP_CMD_ACK && - cmd != IKCP_CMD_WASK && cmd != IKCP_CMD_WINS) - return -3; - - kcp->rmt_wnd = wnd; - ikcp_parse_una(kcp, una); - ikcp_shrink_buf(kcp); - - if (cmd == IKCP_CMD_ACK) - { - if (_itimediff(kcp->current, ts) >= 0) - { - ikcp_update_ack(kcp, (int)_itimediff(kcp->current, ts)); - } - - ikcp_parse_ack(kcp, sn); - ikcp_shrink_buf(kcp); - if (flag == 0) - { - flag = 1; - maxack = sn; - latest_ts = ts; - } - else - { - if (_itimediff(sn, maxack) > 0) - { -#if !IKCP_FASTACK_CONSERVE - maxack = sn; - latest_ts = ts; -#else - if (_itimediff(ts, latest_ts) > 0) - { - maxack = sn; - latest_ts = ts; - } -#endif - } - } - } - else if (cmd == IKCP_CMD_PUSH) - { - if (_itimediff(sn, kcp->rcv_nxt + kcp->rcv_wnd) < 0) - { - ikcp_ack_push(kcp, sn, ts); - if (_itimediff(sn, kcp->rcv_nxt) >= 0) - { - seg = ikcp_segment_new(kcp, (int)len); - seg->conv = conv; - seg->cmd = cmd; - seg->frg = frg; - seg->wnd = wnd; - seg->ts = ts; - seg->sn = sn; - seg->una = una; - seg->len = len; - - if (len > 0) - { - memcpy(seg->data, data, (nuint)len); - } - - ikcp_parse_data(kcp, seg); - } - } - } - else if (cmd == IKCP_CMD_WASK) - { - // ready to send back IKCP_CMD_WINS in ikcp_flush - // tell remote my window size - kcp->probe |= IKCP_ASK_TELL; - } - else if (cmd == IKCP_CMD_WINS) - { - // do nothing - } - else - { - return -3; - } - - data += len; - size -= len; - } - - if (flag != 0) - { - ikcp_parse_fastack(kcp, maxack, latest_ts); - } - - if (_itimediff(kcp->snd_una, prev_una) > 0) - { - if (kcp->cwnd < kcp->rmt_wnd) - { - uint mss = kcp->mss; - if (kcp->cwnd < kcp->ssthresh) - { - kcp->cwnd++; - kcp->incr += mss; - } - else - { - if (kcp->incr < mss) kcp->incr = mss; - kcp->incr += (mss * mss) / kcp->incr + (mss / 16); - if ((kcp->cwnd + 1) * mss <= kcp->incr) - { - kcp->cwnd = (kcp->incr + mss - 1) / ((mss > 0) ? mss : 1); - } - } - - if (kcp->cwnd > kcp->rmt_wnd) - { - kcp->cwnd = kcp->rmt_wnd; - kcp->incr = kcp->rmt_wnd * mss; - } - } - } - - return 0; - } - - //--------------------------------------------------------------------- - // ikcp_encode_seg - //--------------------------------------------------------------------- - public static byte* ikcp_encode_seg(byte* ptr, IKCPSEG* seg) - { - ptr = ikcp_encode32u(ptr, seg->conv); - ptr = ikcp_encode8u(ptr, (byte)seg->cmd); - ptr = ikcp_encode8u(ptr, (byte)seg->frg); - ptr = ikcp_encode16u(ptr, (ushort)seg->wnd); - ptr = ikcp_encode32u(ptr, seg->ts); - ptr = ikcp_encode32u(ptr, seg->sn); - ptr = ikcp_encode32u(ptr, seg->una); - ptr = ikcp_encode32u(ptr, seg->len); - return ptr; - } - - public static int ikcp_wnd_unused(IKCPCB* kcp) - { - if (kcp->nrcv_que < kcp->rcv_wnd) - { - return (int)(kcp->rcv_wnd - kcp->nrcv_que); - } - - return 0; - } - - //--------------------------------------------------------------------- - // ikcp_flush - //--------------------------------------------------------------------- - public static void ikcp_flush(IKCPCB* kcp, byte* buffer, byte[] destination, KcpCallback output) - { - uint current = kcp->current; - byte* ptr = buffer; - int count, size, i; - uint resent, cwnd; - uint rtomin; - IQUEUEHEAD* p; - int change = 0; - int lost = 0; - IKCPSEG seg; - - // 'ikcp_update' haven't been called. - if (kcp->updated == 0) return; - - seg.conv = kcp->conv; - seg.cmd = IKCP_CMD_ACK; - seg.frg = 0; - seg.wnd = (uint)ikcp_wnd_unused(kcp); - seg.una = kcp->rcv_nxt; - seg.len = 0; - seg.sn = 0; - seg.ts = 0; - - // flush acknowledges - count = (int)kcp->ackcount; - for (i = 0; i < count; i++) - { - size = (int)(ptr - buffer); - if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) - { - ikcp_output(kcp, size, destination, output); - ptr = buffer; - } - - ikcp_ack_get(kcp, i, &seg.sn, &seg.ts); - ptr = ikcp_encode_seg(ptr, &seg); - } - - kcp->ackcount = 0; - - // probe window size (if remote window size equals zero) - if (kcp->rmt_wnd == 0) - { - if (kcp->probe_wait == 0) - { - kcp->probe_wait = IKCP_PROBE_INIT; - kcp->ts_probe = kcp->current + kcp->probe_wait; - } - else - { - if (_itimediff(kcp->current, kcp->ts_probe) >= 0) - { - if (kcp->probe_wait < IKCP_PROBE_INIT) - kcp->probe_wait = IKCP_PROBE_INIT; - kcp->probe_wait += kcp->probe_wait / 2; - if (kcp->probe_wait > IKCP_PROBE_LIMIT) - kcp->probe_wait = IKCP_PROBE_LIMIT; - kcp->ts_probe = kcp->current + kcp->probe_wait; - kcp->probe |= IKCP_ASK_SEND; - } - } - } - else - { - kcp->ts_probe = 0; - kcp->probe_wait = 0; - } - - // flush window probing commands - if ((kcp->probe & IKCP_ASK_SEND) != 0) - { - seg.cmd = IKCP_CMD_WASK; - size = (int)(ptr - buffer); - if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) - { - ikcp_output(kcp, size, destination, output); - ptr = buffer; - } - - ptr = ikcp_encode_seg(ptr, &seg); - } - - // flush window probing commands - if ((kcp->probe & IKCP_ASK_TELL) != 0) - { - seg.cmd = IKCP_CMD_WINS; - size = (int)(ptr - buffer); - if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) - { - ikcp_output(kcp, size, destination, output); - ptr = buffer; - } - - ptr = ikcp_encode_seg(ptr, &seg); - } - - kcp->probe = 0; - - // calculate window size - cwnd = _imin_(kcp->snd_wnd, kcp->rmt_wnd); - if (kcp->nocwnd == 0) cwnd = _imin_(kcp->cwnd, cwnd); - - // move data from snd_queue to snd_buf - while (_itimediff(kcp->snd_nxt, kcp->snd_una + cwnd) < 0) - { - IKCPSEG* newseg; - if (iqueue_is_empty(&kcp->snd_queue)) break; - - newseg = iqueue_entry(kcp->snd_queue.next); - - iqueue_del(&newseg->node); - iqueue_add_tail(&newseg->node, &kcp->snd_buf); - kcp->nsnd_que--; - kcp->nsnd_buf++; - - newseg->conv = kcp->conv; - newseg->cmd = IKCP_CMD_PUSH; - newseg->wnd = seg.wnd; - newseg->ts = current; - newseg->sn = kcp->snd_nxt++; - newseg->una = kcp->rcv_nxt; - newseg->resendts = current; - newseg->rto = (uint)kcp->rx_rto; - newseg->fastack = 0; - newseg->xmit = 0; - } - - // calculate resent - resent = (kcp->fastresend > 0) ? (uint)kcp->fastresend : 0xffffffff; - rtomin = (uint)((kcp->nodelay == 0) ? (kcp->rx_rto >> 3) : 0); - - // flush data segments - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = p->next) - { - IKCPSEG* segment = iqueue_entry(p); - int needsend = 0; - if (segment->xmit == 0) - { - needsend = 1; - segment->xmit++; - segment->rto = (uint)kcp->rx_rto; - segment->resendts = current + segment->rto + rtomin; - } - else if (_itimediff(current, segment->resendts) >= 0) - { - needsend = 1; - segment->xmit++; - kcp->xmit++; - if (kcp->nodelay == 0) - { - segment->rto += _imax_(segment->rto, (uint)kcp->rx_rto); - } - else - { - int step = (kcp->nodelay < 2) ? ((int)(segment->rto)) : kcp->rx_rto; - segment->rto += (uint)(step / 2); - } - - segment->resendts = current + segment->rto; - lost = 1; - } - else if (segment->fastack >= resent) - { - if ((int)segment->xmit <= kcp->fastlimit || - kcp->fastlimit <= 0) - { - needsend = 1; - segment->xmit++; - segment->fastack = 0; - segment->resendts = current + segment->rto; - change++; - } - } - - if (needsend != 0) - { - int need; - segment->ts = current; - segment->wnd = seg.wnd; - segment->una = kcp->rcv_nxt; - - size = (int)(ptr - buffer); - need = (int)(IKCP_OVERHEAD + segment->len); - - if (size + need > (int)kcp->mtu) - { - ikcp_output(kcp, size, destination, output); - ptr = buffer; - } - - ptr = ikcp_encode_seg(ptr, segment); - - if (segment->len > 0) - { - memcpy(ptr, segment->data, (nuint)segment->len); - ptr += segment->len; - } - - if (segment->xmit >= kcp->dead_link) - { - kcp->state = unchecked((uint)(-1)); - } - } - } - - // flash remain segments - size = (int)(ptr - buffer); - if (size > 0) - { - ikcp_output(kcp, size, destination, output); - } - - // update ssthresh - if (change != 0) - { - uint inflight = kcp->snd_nxt - kcp->snd_una; - kcp->ssthresh = inflight / 2; - if (kcp->ssthresh < IKCP_THRESH_MIN) - kcp->ssthresh = IKCP_THRESH_MIN; - kcp->cwnd = kcp->ssthresh + resent; - kcp->incr = kcp->cwnd * kcp->mss; - } - - if (lost != 0) - { - kcp->ssthresh = cwnd / 2; - if (kcp->ssthresh < IKCP_THRESH_MIN) - kcp->ssthresh = IKCP_THRESH_MIN; - kcp->cwnd = 1; - kcp->incr = kcp->mss; - } - - if (kcp->cwnd < 1) - { - kcp->cwnd = 1; - kcp->incr = kcp->mss; - } - } - - public static void ikcp_update(IKCPCB* kcp, uint current, byte* buffer, byte[] destination, KcpCallback output) - { - int slap; - - kcp->current = current; - - if (kcp->updated == 0) - { - kcp->updated = 1; - kcp->ts_flush = kcp->current; - } - - slap = (int)_itimediff(kcp->current, kcp->ts_flush); - - if (slap >= 10000 || slap < -10000) - { - kcp->ts_flush = kcp->current; - slap = 0; - } - - if (slap >= 0) - { - kcp->ts_flush += kcp->interval; - if (_itimediff(kcp->current, kcp->ts_flush) >= 0) - { - kcp->ts_flush = kcp->current + kcp->interval; - } - - ikcp_flush(kcp, buffer, destination, output); - } - } - - //--------------------------------------------------------------------- - // Determine when should you invoke ikcp_update: - // returns when you should invoke ikcp_update in millisec, if there - // is no ikcp_input/_send calling. you can call ikcp_update in that - // time, instead of call update repeatly. - // Important to reduce unnacessary ikcp_update invoking. use it to - // schedule ikcp_update (eg. implementing an epoll-like mechanism, - // or optimize ikcp_update when handling massive kcp connections) - //--------------------------------------------------------------------- - public static uint ikcp_check(IKCPCB* kcp, uint current) - { - uint ts_flush = kcp->ts_flush; - int tm_flush = 0x7fffffff; - int tm_packet = 0x7fffffff; - uint minimal = 0; - IQUEUEHEAD* p; - - if (kcp->updated == 0) - { - return current; - } - - if (_itimediff(current, ts_flush) >= 10000 || - _itimediff(current, ts_flush) < -10000) - { - ts_flush = current; - } - - if (_itimediff(current, ts_flush) >= 0) - { - return current; - } - - tm_flush = (int)_itimediff(ts_flush, current); - - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = p->next) - { - IKCPSEG* seg = iqueue_entry(p); - int diff = (int)_itimediff(seg->resendts, current); - if (diff <= 0) - { - return current; - } - - if (diff < tm_packet) tm_packet = diff; - } - - minimal = (uint)(tm_packet < tm_flush ? tm_packet : tm_flush); - if (minimal >= kcp->interval) minimal = kcp->interval; - - return current + minimal; - } - - public static int ikcp_setmtu(IKCPCB* kcp, int mtu, int reserved, ref byte[] buffer) - { - if (mtu < 50 || mtu < (int)IKCP_OVERHEAD) - return -1; - buffer = new byte[(reserved + mtu + IKCP_OVERHEAD) * 3]; - if (buffer == null) - return -2; - kcp->mtu = (uint)mtu; - kcp->mss = kcp->mtu - IKCP_OVERHEAD; - return 0; - } - - public static int ikcp_interval(IKCPCB* kcp, int interval) - { - if (interval > 5000) interval = 5000; - else if (interval < 10) interval = 10; - kcp->interval = (uint)interval; - return 0; - } - - public static int ikcp_nodelay(IKCPCB* kcp, int nodelay, int interval, int resend, int nc) - { - if (nodelay >= 0) - { - kcp->nodelay = (uint)nodelay; - if (nodelay != 0) - { - kcp->rx_minrto = (int)IKCP_RTO_NDL; - } - else - { - kcp->rx_minrto = (int)IKCP_RTO_MIN; - } - } - - if (interval >= 0) - { - if (interval > 5000) interval = 5000; - else if (interval < 10) interval = 10; - kcp->interval = (uint)interval; - } - - if (resend >= 0) - { - kcp->fastresend = resend; - } - - if (nc >= 0) - { - kcp->nocwnd = nc; - } - - return 0; - } - - public static int ikcp_wndsize(IKCPCB* kcp, int sndwnd, int rcvwnd) - { - if (kcp != null) - { - if (sndwnd > 0) - { - kcp->snd_wnd = (uint)sndwnd; - } - - if (rcvwnd > 0) - { - // must >= max fragment size - kcp->rcv_wnd = _imax_((uint)rcvwnd, IKCP_WND_RCV); - } - } - - return 0; - } - - public static int ikcp_waitsnd(IKCPCB* kcp) - { - return (int)(kcp->nsnd_buf + kcp->nsnd_que); - } - - // read conv - public static uint ikcp_getconv(void* ptr) - { - uint conv; - ikcp_decode32u((byte*)ptr, &conv); - return conv; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/define/system.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/define/system.cs deleted file mode 100644 index fec2d37..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/define/system.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -#pragma warning disable CS1591 - -// ReSharper disable ALL - -namespace kcp -{ - internal static unsafe partial class KCP - { - private static void* malloc(nuint size) - { -#if NET6_0_OR_GREATER - return NativeMemory.Alloc((nuint)size); -#else - return (void*)Marshal.AllocHGlobal((nint)size); -#endif - } - - private static void free(void* memory) - { -#if NET6_0_OR_GREATER - NativeMemory.Free(memory); -#else - Marshal.FreeHGlobal((nint)memory); -#endif - } - - private static void memcpy(void* dst, void* src, nuint size) => Unsafe.CopyBlockUnaligned(dst, src, (uint)size); - - private static void memset(void* dst, byte val, nuint size) => Unsafe.InitBlockUnaligned(dst, val, (uint)size); - - [Conditional("DEBUG")] - private static void assert(bool condition) => Debug.Assert(condition); - - private static void abort() => Environment.Exit(-1); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/include/kcp.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/include/kcp.cs deleted file mode 100644 index 838cc09..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Base/include/kcp.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -#pragma warning disable CS1591 - -// ReSharper disable ALL - -namespace kcp -{ - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct IQUEUEHEAD - { - public IQUEUEHEAD* next; - public IQUEUEHEAD* prev; - } - - internal static unsafe partial class KCP - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_init(IQUEUEHEAD* head) - { - head->next = head; - head->prev = head; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T* iqueue_entry(IQUEUEHEAD* ptr) where T : unmanaged => ((T*)(((byte*)((T*)ptr)))); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_add(IQUEUEHEAD* node, IQUEUEHEAD* head) - { - node->prev = head; - node->next = head->next; - head->next->prev = node; - head->next = node; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_add_tail(IQUEUEHEAD* node, IQUEUEHEAD* head) - { - node->prev = head->prev; - node->next = head; - head->prev->next = node; - head->prev = node; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_del(IQUEUEHEAD* entry) - { - entry->next->prev = entry->prev; - entry->prev->next = entry->next; - entry->next = (IQUEUEHEAD*)0; - entry->prev = (IQUEUEHEAD*)0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_del_init(IQUEUEHEAD* entry) - { - iqueue_del(entry); - iqueue_init(entry); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool iqueue_is_empty(IQUEUEHEAD* entry) => entry == entry->next; - } - - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct IKCPSEG - { - public IQUEUEHEAD node; - public uint conv; - public uint cmd; - public uint frg; - public uint wnd; - public uint ts; - public uint sn; - public uint una; - public uint len; - public uint resendts; - public uint rto; - public uint fastack; - public uint xmit; - public fixed byte data[1]; - } - - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct IKCPCB - { - public uint conv, mtu, mss, state; - public uint snd_una, snd_nxt, rcv_nxt; - public uint ts_recent, ts_lastack, ssthresh; - public int rx_rttval, rx_srtt, rx_rto, rx_minrto; - public uint snd_wnd, rcv_wnd, rmt_wnd, cwnd, probe; - public uint current, interval, ts_flush, xmit; - public uint nrcv_buf, nsnd_buf; - public uint nrcv_que, nsnd_que; - public uint nodelay, updated; - public uint ts_probe, probe_wait; - public uint dead_link, incr; - public IQUEUEHEAD snd_queue; - public IQUEUEHEAD rcv_queue; - public IQUEUEHEAD snd_buf; - public IQUEUEHEAD rcv_buf; - public uint* acklist; - public uint ackcount; - public uint ackblock; - public int fastresend; - public int fastlimit; - public int nocwnd, stream; - } - - internal static partial class KCP - { - public const uint IKCP_LOG_OUTPUT = 1; - public const uint IKCP_LOG_INPUT = 2; - public const uint IKCP_LOG_SEND = 4; - public const uint IKCP_LOG_RECV = 8; - public const uint IKCP_LOG_IN_DATA = 16; - public const uint IKCP_LOG_IN_ACK = 32; - public const uint IKCP_LOG_IN_PROBE = 64; - public const uint IKCP_LOG_IN_WINS = 128; - public const uint IKCP_LOG_OUT_DATA = 256; - public const uint IKCP_LOG_OUT_ACK = 512; - public const uint IKCP_LOG_OUT_PROBE = 1024; - public const uint IKCP_LOG_OUT_WINS = 2048; - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Client/KCPClientNetwork.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Client/KCPClientNetwork.cs deleted file mode 100644 index f0f8868..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Client/KCPClientNetwork.cs +++ /dev/null @@ -1,697 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Buffers; -using System.Collections.Generic; -using System.IO; -using System.IO.Pipelines; -using System.Net; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Threading; -using Fantasy.Async; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -using KCP; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable PossibleNullReferenceException -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). - -#pragma warning disable CS8602 // Dereference of a possibly null reference. -namespace Fantasy.Network.KCP -{ - internal sealed class KCPClientNetworkUpdateSystem : UpdateSystem - { - protected override void Update(KCPClientNetwork self) - { - self.CheckUpdate(); - } - } - internal sealed class KCPClientNetwork : AClientNetwork - { - private Kcp _kcp; - private Socket _socket; - private int _maxSndWnd; - private long _startTime; - private bool _isConnected; - private bool _isDisconnect; - private uint _updateMinTime; - private bool _isInnerDispose; - private long _connectTimeoutId; - private bool _allowWraparound = true; - private IPEndPoint _remoteAddress; - private BufferPacketParser _packetParser; - private readonly Pipe _pipe = new Pipe(); - private readonly byte[] _sendBuff = new byte[5]; - private readonly byte[] _receiveBuffer = new byte[ProgramDefine.MaxMessageSize + 20]; - private readonly List _updateTimeOutTime = new List(); - private readonly SortedSet _updateTimer = new SortedSet(); - private readonly SocketAsyncEventArgs _connectEventArgs = new SocketAsyncEventArgs(); - private readonly Queue _messageCache = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); -#if FANTASY_UNITY - private readonly EndPoint _ipEndPoint = new IPEndPoint(IPAddress.Any, 0); -#endif - private event Action OnConnectFail; - private event Action OnConnectComplete; - private event Action OnConnectDisconnect; - public uint ChannelId { get; private set; } - private uint TimeNow => (uint) (TimeHelper.Now - _startTime); - - public void Initialize(NetworkTarget networkTarget) - { - base.Initialize(NetworkType.Client, NetworkProtocolType.KCP, networkTarget); - _packetParser = PacketParserFactory.CreateClientBufferPacket(this); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isInnerDispose = true; - - if (!_isDisconnect) - { - SendDisconnect(); - } - - ClearConnectTimeout(); - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - OnConnectDisconnect?.Invoke(); - _kcp.Dispose(); - - if (_socket.Connected) - { - _socket.Close(); - } - - _packetParser.Dispose(); - ChannelId = 0; - _isConnected = false; - _messageCache.Clear(); - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - #region Connect - - public override Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - if (IsInit) - { - throw new NotSupportedException($"KCPClientNetwork Has already been initialized. If you want to call Connect again, please re instantiate it."); - } - - IsInit = true; - _startTime = TimeHelper.Now; - ChannelId = CreateChannelId(); - _remoteAddress = NetworkHelper.GetIPEndPoint(remoteAddress); - OnConnectFail = onConnectFail; - OnConnectComplete = onConnectComplete; - OnConnectDisconnect = onConnectDisconnect; - _connectEventArgs.Completed += OnConnectSocketCompleted; - _connectTimeoutId = Scene.TimerComponent.Net.OnceTimer(connectTimeout, () => - { - OnConnectFail?.Invoke(); - Dispose(); - }); - _connectEventArgs.RemoteEndPoint = _remoteAddress; - _socket = new Socket(_remoteAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp); - _socket.Blocking = false; - _socket.SetSocketBufferToOsLimit(); - _socket.SetSioUdpConnReset(); - _socket.Bind(new IPEndPoint(IPAddress.Any, 0)); - _kcp = KCPFactory.Create(NetworkTarget, ChannelId, KcpSpanCallback, out var kcpSettings); - _maxSndWnd = kcpSettings.MaxSendWindowSize; - - if (!_socket.ConnectAsync(_connectEventArgs)) - { - try - { - OnReceiveSocketComplete(); - } - catch (Exception e) - { - Log.Error(e); - OnConnectFail?.Invoke(); - } - } - - Session = Session.Create(this, _remoteAddress); - return Session; - } - - private void OnConnectSocketCompleted(object sender, SocketAsyncEventArgs asyncEventArgs) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - if (asyncEventArgs.LastOperation == SocketAsyncOperation.Connect) - { - if (asyncEventArgs.SocketError == SocketError.Success) - { - Scene.ThreadSynchronizationContext.Post(OnReceiveSocketComplete); - } - else - { - Scene.ThreadSynchronizationContext.Post(() => - { - OnConnectFail?.Invoke(); - Dispose(); - }); - } - } - } - - private void OnReceiveSocketComplete() - { - SendRequestConnection(); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - } - - #endregion - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); -#if FANTASY_UNITY - MemoryMarshal.TryGetArray(memory, out ArraySegment arraySegment); - var result = await _socket.ReceiveFromAsync(arraySegment, SocketFlags.None, _ipEndPoint); - _pipe.Writer.Advance(result.ReceivedBytes); - await _pipe.Writer.FlushAsync(); -#else - var result = await _socket.ReceiveAsync(memory, SocketFlags.None, _cancellationTokenSource.Token); - _pipe.Writer.Advance(result); - await _pipe.Writer.FlushAsync(); -#endif - } - catch (SocketException) - { - Dispose(); - break; - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (Exception ex) - { - Log.Error($"Unexpected exception: {ex.Message}"); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var header, out var channelId, out var message)) - { - ReceiveData(ref header, ref channelId, ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - } - - private unsafe bool TryReadMessage(ref ReadOnlySequence buffer, out KcpHeader header, out uint channelId, out ReadOnlyMemory message) - { - if (buffer.Length < 5) - { - channelId = 0; - message = default; - header = KcpHeader.None; - if (buffer.Length > 0) - { - buffer = buffer.Slice(buffer.Length); - } - return false; - } - - var readOnlyMemory = buffer.First; - - if (MemoryMarshal.TryGetArray(readOnlyMemory, out var arraySegment)) - { - fixed (byte* bytePointer = &arraySegment.Array[arraySegment.Offset]) - { - header = (KcpHeader)bytePointer[0]; - channelId = Unsafe.ReadUnaligned(ref bytePointer[1]); - } - } - else - { - // 如果无法获取数组段,回退到安全代码来执行。这种情况几乎不会发生、为了保险还是写一下了。 - var firstSpan = readOnlyMemory.Span; - header = (KcpHeader)firstSpan[0]; - channelId = MemoryMarshal.Read(firstSpan.Slice(1, 4)); - - } - - message = readOnlyMemory.Slice(5); - buffer = buffer.Slice(readOnlyMemory.Length); - return true; - } - - private void ReceiveData(ref KcpHeader header, ref uint channelId, ref ReadOnlyMemory buffer) - { - switch (header) - { - // 发送握手给服务器 - case KcpHeader.RepeatChannelId: - { - // 到这里是客户端的channelId再服务器上已经存在、需要重新生成一个再次尝试连接 - ChannelId = CreateChannelId(); - SendRequestConnection(); - break; - } - // 收到服务器发送会来的确认握手 - case KcpHeader.WaitConfirmConnection: - { - if (channelId != ChannelId) - { - break; - } - - ClearConnectTimeout(); - SendConfirmConnection(); - OnConnectComplete?.Invoke(); - _isConnected = true; - while (_messageCache.TryDequeue(out var memoryStream)) - { - SendMemoryStream(memoryStream); - } - break; - } - // 收到服务器发送的消息 - case KcpHeader.ReceiveData: - { - if (buffer.Length == 5) - { - Log.Warning($"KCP Server KcpHeader.Data buffer.Length == 5"); - break; - } - - if (channelId != ChannelId) - { - break; - } - - Input(buffer); - break; - } - // 接收到服务器的断开连接消息 - case KcpHeader.Disconnect: - { - if (channelId != ChannelId) - { - break; - } - - _isDisconnect = true; - Dispose(); - break; - } - } - } - - private void Input(ReadOnlyMemory buffer) - { - _kcp.Input(buffer.Span); - AddToUpdate(0); - - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var peekSize = _kcp.PeekSize(); - - if (peekSize < 0) - { - return; - } - - var receiveCount = _kcp.Receive(_receiveBuffer.AsSpan(0, peekSize)); - - if (receiveCount != peekSize) - { - return; - } - - if (!_packetParser.UnPack(_receiveBuffer, ref receiveCount, out var packInfo)) - { - continue; - } - - Session.Receive(packInfo); - } - catch (ScanException e) - { - Log.Debug($"RemoteAddress:{_remoteAddress} \n{e}"); - Dispose(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - #endregion - - #region Update - - public void CheckUpdate() - { - var nowTime = TimeNow; - _allowWraparound = nowTime < _updateMinTime; - - if (IsTimeGreaterThan(nowTime, _updateMinTime) && _updateTimer.Count > 0) - { - foreach (var timeId in _updateTimer) - { - if (IsTimeGreaterThan(timeId, nowTime)) - { - _updateMinTime = timeId; - break; - } - - _updateTimeOutTime.Add(timeId); - } - - foreach (var timeId in _updateTimeOutTime) - { - _updateTimer.Remove(timeId); - KcpUpdate(); - } - - _updateTimeOutTime.Clear(); - } - - _allowWraparound = true; - } - - private void AddToUpdate(uint tillTime) - { - if (tillTime == 0) - { - KcpUpdate(); - return; - } - - if (IsTimeGreaterThan(_updateMinTime, tillTime) || _updateMinTime == 0) - { - _updateMinTime = tillTime; - } - - _updateTimer.Add(tillTime); - } - - private void KcpUpdate() - { - var nowTime = TimeNow; - - try - { - _kcp.Update(nowTime); - } - catch (Exception e) - { - Log.Error(e); - } - - AddToUpdate(_kcp.Check(nowTime)); - } - - private const uint HalfMaxUint = uint.MaxValue / 2; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool IsTimeGreaterThan(uint timeId, uint nowTime) - { - if (!_allowWraparound) - { - return timeId > nowTime; - } - var diff = timeId - nowTime; - // 如果 diff 的值在 [0, HalfMaxUint] 范围内,说明 timeId 是在 nowTime 之后或相等。 - // 如果 diff 的值在 (HalfMaxUint, uint.MaxValue] 范围内,说明 timeId 是在 nowTime 之前(时间回绕的情况)。 - return diff < HalfMaxUint || diff == HalfMaxUint; - } - - #endregion - - #region Send - - private const byte KcpHeaderDisconnect = (byte)KcpHeader.Disconnect; - private const byte KcpHeaderReceiveData = (byte)KcpHeader.ReceiveData; - private const byte KcpHeaderRequestConnection = (byte)KcpHeader.RequestConnection; - private const byte KcpHeaderConfirmConnection = (byte)KcpHeader.ConfirmConnection; - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - var buffer = _packetParser.Pack(ref rpcId, ref routeId, memoryStream, message); - - if (!_isConnected) - { - _messageCache.Enqueue(buffer); - return; - } - - SendMemoryStream(buffer); - } - - private void SendMemoryStream(MemoryStreamBuffer memoryStream) - { - if (_kcp.WaitSendCount > _maxSndWnd) - { - // 检查等待发送的消息,如果超出两倍窗口大小,KCP作者给的建议是要断开连接 - Log.Warning($"ERR_KcpWaitSendSizeTooLarge {_kcp.WaitSendCount} > {_maxSndWnd}"); - Dispose(); - return; - } - - try - { - _kcp.Send(memoryStream.GetBuffer().AsSpan(0, (int)memoryStream.Position)); - AddToUpdate(0); - } - finally - { - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - } - - private unsafe void SendRequestConnection() - { - try - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderRequestConnection; - *(uint*)(p + 1) = ChannelId; - } - - SendAsync(_sendBuff, 0, 5); - } - catch (Exception e) - { - Log.Error(e); - } - } - - private unsafe void SendConfirmConnection() - { - try - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderConfirmConnection; - *(uint*)(p + 1) = ChannelId; - } - - SendAsync(_sendBuff, 0, 5); - } - catch (Exception e) - { - Log.Error(e); - } - } - - private unsafe void SendDisconnect() - { - try - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderDisconnect; - *(uint*)(p + 1) = ChannelId; - } - - SendAsync(_sendBuff, 0, 5); - } - catch (Exception e) - { - Log.Error(e); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SendAsync(byte[] buffer, int offset, int count) - { - try - { - _socket.Send(new ArraySegment(buffer, offset, count), SocketFlags.None); - } - catch (ArgumentException ex) - { - Log.Error($"ArgumentException: {ex.Message}"); // 处理参数错误 - } - catch (SocketException) - { - //Log.Error($"SocketException: {ex.Message}"); // 处理网络错误 - Dispose(); - } - catch (ObjectDisposedException ex) - { - Log.Error($"ObjectDisposedException: {ex.Message}"); // 处理套接字已关闭的情况 - Dispose(); - } - catch (InvalidOperationException ex) - { - Log.Error($"InvalidOperationException: {ex.Message}"); // 处理无效操作 - } - catch (Exception ex) - { - Log.Error($"Exception: {ex.Message}"); // 捕获其他异常 - } - } - - private unsafe void KcpSpanCallback(byte[] buffer, int count) - { - if (IsDisposed) - { - return; - } - - if (count == 0) - { - throw new Exception("KcpOutput count 0"); - } - - fixed (byte* p = buffer) - { - p[0] = KcpHeaderReceiveData; - *(uint*)(p + 1) = ChannelId; - } - - SendAsync(buffer, 0, count + 5); - } - - #endregion - - public override void RemoveChannel(uint channelId) - { - Dispose(); - } - - private void ClearConnectTimeout() - { - if (_connectTimeoutId == 0) - { - return; - } - - Scene?.TimerComponent?.Net.Remove(ref _connectTimeoutId); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe uint CreateChannelId() - { - uint value; - RandomNumberGenerator.Fill(MemoryMarshal.CreateSpan(ref *(byte*)&value, 4)); - return 0xC0000000 | (value & int.MaxValue); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/KCPSettings.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/KCPSettings.cs deleted file mode 100644 index d7ca536..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/KCPSettings.cs +++ /dev/null @@ -1,91 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using KCP; - -#pragma warning disable CS1591 -namespace Fantasy.Network.KCP -{ - public class KCPSettings - { - public int Mtu { get; private set; } - public int SendWindowSize { get; private set; } - public int ReceiveWindowSize { get; private set; } - public int MaxSendWindowSize { get; private set; } - - public static KCPSettings Create(NetworkTarget networkTarget) - { - var settings = new KCPSettings(); - - switch (networkTarget) - { - case NetworkTarget.Outer: - { - // 外网设置470的原因: - // 1、mtu设置过大有可能路由器过滤掉 - // 2、降低 mtu 到 470,同样数据虽然会发更多的包,但是小包在路由层优先级更高 - settings.Mtu = 470; -#if FANTASY_NET - settings.SendWindowSize = 8192; - settings.ReceiveWindowSize = 8192; - settings.MaxSendWindowSize = 8192 * 8192 * 7; -#endif -#if FANTASY_UNITY || FANTASY_CONSOLE - settings.SendWindowSize = 512; - settings.ReceiveWindowSize = 512; - settings.MaxSendWindowSize = 512 * 512 * 7; -#endif - - break; - } -#if FANTASY_NET - case NetworkTarget.Inner: - { - // 内网设置1400的原因 - // 1、一般都是同一台服务器来运行多个进程来处理 - // 2、内网每个进程跟其他进程只有一个通道进行发送、所以发送的数量会比较大 - // 3、如果不把窗口设置大点、会出现消息滞后。 - // 4、因为内网发送的可不只是外网转发数据、还有可能是其他进程的通讯 - settings.Mtu = 1200; - settings.SendWindowSize = 8192; - settings.ReceiveWindowSize = 8192; - settings.MaxSendWindowSize = 8192 * 8192 * 7; - break; - } -#endif - default: - { - throw new NotSupportedException($"KCPServerNetwork NotSupported NetworkType:{networkTarget}"); - } - } - - return settings; - } - } - - internal static class KCPFactory - { - public const int FANTASY_KCP_RESERVED_HEAD = 5; - - public static Kcp Create(NetworkTarget networkTarget, uint conv, KcpCallback output, out KCPSettings kcpSettings) - { - var kcp = new Kcp(conv, output, FANTASY_KCP_RESERVED_HEAD); - kcpSettings = KCPSettings.Create(networkTarget); - kcp.SetNoDelay(1, 5, 2, 1); - kcp.SetWindowSize(kcpSettings.SendWindowSize, kcpSettings.ReceiveWindowSize); - kcp.SetMtu(kcpSettings.Mtu); - kcp.SetMinrto(30); - return kcp; - } - - public static Kcp Create(KCPSettings kcpSettings, uint conv, KcpCallback output) - { - var kcp = new Kcp(conv, output, FANTASY_KCP_RESERVED_HEAD); - kcp.SetNoDelay(1, 5, 2, 1); - kcp.SetWindowSize(kcpSettings.SendWindowSize, kcpSettings.ReceiveWindowSize); - kcp.SetMtu(kcpSettings.Mtu); - kcp.SetMinrto(30); - return kcp; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/KcpHeader.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/KcpHeader.cs deleted file mode 100644 index 5ad606e..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/KcpHeader.cs +++ /dev/null @@ -1,14 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network.KCP -{ - internal enum KcpHeader : byte - { - None = 0x00, - RequestConnection = 0x01, - WaitConfirmConnection = 0x02, - ConfirmConnection = 0x03, - RepeatChannelId = 0x04, - ReceiveData = 0x06, - Disconnect = 0x07 - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByArrayPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByArrayPool.cs deleted file mode 100644 index 0fb4e29..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByArrayPool.cs +++ /dev/null @@ -1,575 +0,0 @@ -// #if FANTASY_NET -// using System.Buffers; -// using System.Net; -// using System.Net.Sockets; -// using System.Runtime.CompilerServices; -// using System.Runtime.InteropServices; -// using Fantasy.Async; -// using Fantasy.DataStructure.Collection; -// using Fantasy.Entitas.Interface; -// using Fantasy.Helper; -// using Fantasy.Network.Interface; -// #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -// -// // ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// #pragma warning disable CS8604 // Possible null reference argument. -// #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -// #pragma warning disable CS8602 // Dereference of a possibly null reference. -// -// #pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). -// -// namespace Fantasy.Network.KCP -// { -// public sealed class KCPServerNetworkUpdateSystem : UpdateSystem -// { -// protected override void Update(KCPServerNetwork self) -// { -// self.Update(); -// } -// } -// -// public struct PendingConnection -// { -// public readonly uint ChannelId; -// public readonly uint TimeOutId; -// public readonly IPEndPoint RemoteEndPoint; -// -// public PendingConnection(uint channelId, IPEndPoint remoteEndPoint, uint time) -// { -// ChannelId = channelId; -// RemoteEndPoint = remoteEndPoint; -// TimeOutId = time + 10 * 1000; // 设置10秒超时,如果10秒内没有确认连接则删除。 -// } -// } -// -// public sealed class KCPServerNetwork : ANetwork -// { -// private Socket _socket; -// private Thread _thread; -// private long _startTime; -// private uint _updateMinTime; -// private uint _pendingMinTime; -// private bool _allowWraparound = true; -// -// private readonly byte[] _sendBuff = new byte[5]; -// private readonly List _pendingTimeOutTime = new List(); -// private readonly HashSet _updateChannels = new HashSet(); -// private readonly List _updateTimeOutTime = new List(); -// private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); -// private readonly SortedOneToManyList _updateTimer = new SortedOneToManyList(); -// -// private readonly Dictionary _pendingConnection = new Dictionary(); -// private readonly SortedOneToManyList _pendingConnectionTimeOut = new SortedOneToManyList(); -// private readonly Dictionary _connectionChannel = new Dictionary(); -// -// public KCPSettings Settings { get; private set; } -// -// private uint TimeNow => (uint)(TimeHelper.Now - _startTime); -// -// public void Initialize(NetworkTarget networkTarget, IPEndPoint address) -// { -// _startTime = TimeHelper.Now; -// Settings = KCPSettings.Create(networkTarget); -// base.Initialize(NetworkType.Server, NetworkProtocolType.KCP, networkTarget); -// _socket = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); -// _socket.Blocking = false; -// _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); -// if (address.AddressFamily == AddressFamily.InterNetworkV6) -// { -// _socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); -// } -// -// _socket.Blocking = false; -// _socket.Bind(address); -// _socket.SetSocketBufferToOsLimit(); -// _socket.SetSioUdpConnReset(); -// _thread = new Thread(() => -// { -// ReceiveSocketAsync().Coroutine(); -// }); -// _thread.Start(); -// Log.Info($"SceneConfigId = {Scene.SceneConfigId} networkTarget = {networkTarget.ToString()} KCPServer Listen {address}"); -// } -// -// public override void Dispose() -// { -// if (IsDisposed) -// { -// return; -// } -// -// try -// { -// if (!_cancellationTokenSource.IsCancellationRequested) -// { -// try -// { -// _cancellationTokenSource.Cancel(); -// } -// catch (OperationCanceledException) -// { -// // 通常情况下,此处的异常可以忽略 -// } -// } -// -// foreach (var (_, channel) in _connectionChannel.ToArray()) -// { -// channel.Dispose(); -// } -// -// _connectionChannel.Clear(); -// _pendingConnection.Clear(); -// -// if (_socket != null) -// { -// _socket.Dispose(); -// _socket = null; -// } -// } -// catch (Exception e) -// { -// Log.Error(e); -// } -// finally -// { -// base.Dispose(); -// } -// } -// -// #region ReceiveSocket -// -// private const int BufferSize = 8192; -// private static readonly ArrayPool BufferPool = ArrayPool.Shared; -// private async FTask ReceiveSocketAsync() -// { -// var sceneThreadSynchronizationContext = Scene.ThreadSynchronizationContext; -// var remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); -// -// while (!_cancellationTokenSource.IsCancellationRequested) -// { -// try -// { -// IPEndPoint receiveRemoteEndPoint = null; -// var buffer = BufferPool.Rent(BufferSize); -// var socketReceiveFromResult = await _socket.ReceiveFromAsync(buffer, SocketFlags.None, remoteEndPoint, _cancellationTokenSource.Token); -// var receivedBytes = socketReceiveFromResult.ReceivedBytes; -// -// switch (receivedBytes) -// { -// case 5: -// { -// switch ((KcpHeader)buffer[0]) -// { -// case KcpHeader.RequestConnection: -// case KcpHeader.ConfirmConnection: -// { -// receiveRemoteEndPoint = socketReceiveFromResult.RemoteEndPoint.Clone(); -// break; -// } -// } -// -// break; -// } -// case < 5: -// { -// continue; -// } -// } -// -// sceneThreadSynchronizationContext.Post(() => -// { -// ReceiveDataAsync(buffer, receivedBytes, receiveRemoteEndPoint); -// }); -// } -// catch (SocketException ex) -// { -// Log.Error($"Socket exception: {ex.Message}"); -// Dispose(); -// break; -// } -// catch (OperationCanceledException) -// { -// break; -// } -// catch (ObjectDisposedException) -// { -// Dispose(); -// break; -// } -// catch (Exception ex) -// { -// Log.Error($"Unexpected exception: {ex.Message}"); -// } -// } -// } -// -// #endregion -// -// #region ReceivePipeData -// -// private void ReceiveDataAsync(byte[] buffer, int receivedBytes, IPEndPoint remoteEndPoint) -// { -// try -// { -// var header = (KcpHeader)buffer[0]; -// var channelId = BitConverter.ToUInt32(buffer, 1); -// -// switch (header) -// { -// // 客户端请求建立KCP连接 -// case KcpHeader.RequestConnection: -// { -// if (_pendingConnection.TryGetValue(channelId, out var pendingConnection)) -// { -// if (!remoteEndPoint.IPEndPointEquals(pendingConnection.RemoteEndPoint)) -// { -// // 重复通道ID,向客户端发送重复通道ID消息 -// SendRepeatChannelId(ref channelId, remoteEndPoint); -// } -// -// break; -// } -// -// if (_connectionChannel.ContainsKey(channelId)) -// { -// // 已存在的通道ID,向客户端发送重复通道ID消息 -// SendRepeatChannelId(ref channelId, remoteEndPoint); -// break; -// } -// -// AddPendingConnection(ref channelId, remoteEndPoint); -// break; -// } -// // 客户端确认建立KCP连接 -// case KcpHeader.ConfirmConnection: -// { -// if (!ConfirmPendingConnection(ref channelId, remoteEndPoint)) -// { -// break; -// } -// -// AddConnection(ref channelId, remoteEndPoint); -// break; -// } -// // 接收KCP的数据 -// case KcpHeader.ReceiveData: -// { -// if (buffer.Length == 5) -// { -// Log.Warning($"KCP Server KcpHeader.Data buffer.Length == 5"); -// break; -// } -// -// if (_connectionChannel.TryGetValue(channelId, out var channel)) -// { -// channel.Input(buffer.AsMemory().Slice(5, receivedBytes - 5)); -// } -// -// break; -// } -// // 断开KCP连接 -// case KcpHeader.Disconnect: -// { -// // 断开不需要清楚PendingConnection让ClearPendingConnection自动清楚就可以了,并且不一定有Pending。 -// RemoveChannel(channelId); -// break; -// } -// } -// } -// finally -// { -// BufferPool.Return(buffer); -// } -// } -// -// #endregion -// -// #region Update -// -// public void Update() -// { -// var timeNow = TimeNow; -// _allowWraparound = timeNow < _updateMinTime; -// CheckUpdateTimerOut(ref timeNow); -// UpdateChannel(ref timeNow); -// PendingTimerOut(ref timeNow); -// _allowWraparound = true; -// } -// -// private void CheckUpdateTimerOut(ref uint nowTime) -// { -// if (_updateTimer.Count == 0) -// { -// return; -// } -// -// if (IsTimeGreaterThan(_updateMinTime, nowTime)) -// { -// return; -// } -// -// _updateTimeOutTime.Clear(); -// -// foreach (var kv in _updateTimer) -// { -// var timeId = kv.Key; -// -// if (IsTimeGreaterThan(timeId, nowTime)) -// { -// _updateMinTime = timeId; -// break; -// } -// -// _updateTimeOutTime.Add(timeId); -// } -// -// foreach (var timeId in _updateTimeOutTime) -// { -// foreach (var channelId in _updateTimer[timeId]) -// { -// _updateChannels.Add(channelId); -// } -// -// _updateTimer.RemoveKey(timeId); -// } -// } -// -// private void UpdateChannel(ref uint timeNow) -// { -// foreach (var channelId in _updateChannels) -// { -// if (!_connectionChannel.TryGetValue(channelId, out var channel)) -// { -// continue; -// } -// -// if (channel.IsDisposed) -// { -// _connectionChannel.Remove(channelId); -// continue; -// } -// -// channel.Kcp.Update(timeNow); -// AddUpdateChannel(channelId, channel.Kcp.Check(timeNow)); -// } -// -// _updateChannels.Clear(); -// } -// -// private void PendingTimerOut(ref uint timeNow) -// { -// if (_pendingConnectionTimeOut.Count == 0) -// { -// return; -// } -// -// if (IsTimeGreaterThan(_pendingMinTime, timeNow)) -// { -// return; -// } -// -// _pendingTimeOutTime.Clear(); -// -// foreach (var kv in _pendingConnectionTimeOut) -// { -// var timeId = kv.Key; -// -// if (IsTimeGreaterThan(timeId, timeNow)) -// { -// _pendingMinTime = timeId; -// break; -// } -// -// _pendingTimeOutTime.Add(timeId); -// } -// -// foreach (var timeId in _pendingTimeOutTime) -// { -// foreach (var channelId in _pendingConnectionTimeOut[timeId]) -// { -// _pendingConnection.Remove(channelId); -// } -// -// _pendingConnectionTimeOut.RemoveKey(timeId); -// } -// } -// -// public void AddUpdateChannel(uint channelId, uint tillTime) -// { -// if (tillTime == 0) -// { -// _updateChannels.Add(channelId); -// return; -// } -// -// if (IsTimeGreaterThan(_updateMinTime, tillTime)) -// { -// _updateMinTime = tillTime; -// } -// -// _updateTimer.Add(tillTime, channelId); -// } -// -// private const uint HalfMaxUint = uint.MaxValue / 2; -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private bool IsTimeGreaterThan(uint timeId, uint nowTime) -// { -// if (!_allowWraparound) -// { -// return timeId > nowTime; -// } -// -// var diff = timeId - nowTime; -// // 如果 diff 的值在 [0, HalfMaxUint] 范围内,说明 timeId 是在 nowTime 之后或相等。 -// // 如果 diff 的值在 (HalfMaxUint, uint.MaxValue] 范围内,说明 timeId 是在 nowTime 之前(时间回绕的情况)。 -// return diff < HalfMaxUint || diff == HalfMaxUint; -// } -// -// #endregion -// -// #region Pending -// -// private void AddPendingConnection(ref uint channelId, IPEndPoint ipEndPoint) -// { -// var now = TimeNow; -// var pendingConnection = new PendingConnection(channelId, ipEndPoint, now); -// -// if (IsTimeGreaterThan(_pendingMinTime, pendingConnection.TimeOutId) || _pendingMinTime == 0) -// { -// _pendingMinTime = pendingConnection.TimeOutId; -// } -// -// _pendingConnection.Add(channelId, pendingConnection); -// _pendingConnectionTimeOut.Add(pendingConnection.TimeOutId, channelId); -// SendWaitConfirmConnection(ref channelId, ipEndPoint); -// } -// -// private bool ConfirmPendingConnection(ref uint channelId, EndPoint ipEndPoint) -// { -// if (!_pendingConnection.TryGetValue(channelId, out var pendingConnection)) -// { -// return false; -// } -// -// if (!ipEndPoint.IPEndPointEquals(pendingConnection.RemoteEndPoint)) -// { -// Log.Error($"KCPSocket syn address diff: {channelId} {pendingConnection.RemoteEndPoint} {ipEndPoint}"); -// return false; -// } -// -// _pendingConnection.Remove(channelId); -// _pendingConnectionTimeOut.RemoveValue(pendingConnection.TimeOutId, pendingConnection.ChannelId); -// #if FANTASY_DEVELOP -// Log.Debug($"KCPSocket _pendingConnection:{_pendingConnection.Count} _pendingConnectionTimer:{_pendingConnectionTimeOut.Count}"); -// #endif -// return true; -// } -// -// #endregion -// -// #region Connection -// -// private void AddConnection(ref uint channelId, IPEndPoint ipEndPoint) -// { -// var eventArgs = new KCPServerNetworkChannel(this, channelId, ipEndPoint); -// _connectionChannel.Add(channelId, eventArgs); -// #if FANTASY_DEVELOP -// Log.Debug($"AddConnection _connectionChannel:{_connectionChannel.Count()}"); -// #endif -// } -// -// public override void RemoveChannel(uint channelId) -// { -// if (!_connectionChannel.Remove(channelId, out var channel)) -// { -// return; -// } -// -// if (!channel.IsDisposed) -// { -// SendDisconnect(ref channelId, channel.RemoteEndPoint); -// channel.Dispose(); -// } -// #if FANTASY_DEVELOP -// Log.Debug($"RemoveChannel _connectionChannel:{_connectionChannel.Count()}"); -// #endif -// } -// -// #endregion -// -// #region Send -// -// private const byte KcpHeaderDisconnect = (byte)KcpHeader.Disconnect; -// private const byte KcpHeaderRepeatChannelId = (byte)KcpHeader.RepeatChannelId; -// private const byte KcpHeaderWaitConfirmConnection = (byte)KcpHeader.WaitConfirmConnection; -// -// private unsafe void SendDisconnect(ref uint channelId, EndPoint clientEndPoint) -// { -// fixed (byte* p = _sendBuff) -// { -// p[0] = KcpHeaderDisconnect; -// *(uint*)(p + 1) = channelId; -// } -// -// SendAsync(_sendBuff, 0, 5, clientEndPoint); -// } -// -// private unsafe void SendRepeatChannelId(ref uint channelId, EndPoint clientEndPoint) -// { -// fixed (byte* p = _sendBuff) -// { -// p[0] = KcpHeaderRepeatChannelId; -// *(uint*)(p + 1) = channelId; -// } -// -// SendAsync(_sendBuff, 0, 5, clientEndPoint); -// } -// -// private unsafe void SendWaitConfirmConnection(ref uint channelId, EndPoint clientEndPoint) -// { -// fixed (byte* p = _sendBuff) -// { -// p[0] = KcpHeaderWaitConfirmConnection; -// *(uint*)(p + 1) = channelId; -// } -// -// SendAsync(_sendBuff, 0, 5, clientEndPoint); -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// public void SendAsync(byte[] buffer, int offset, int count, EndPoint endPoint) -// { -// try -// { -// _socket.SendTo(new ArraySegment(buffer, offset, count), SocketFlags.None, endPoint); -// } -// catch (ArgumentException ex) -// { -// Log.Error($"ArgumentException: {ex.Message}"); // 处理参数错误 -// } -// catch (SocketException) -// { -// //Log.Error($"SocketException: {ex.Message}"); // 处理网络错误 -// } -// catch (ObjectDisposedException) -// { -// // 处理套接字已关闭的情况 -// } -// catch (InvalidOperationException ex) -// { -// Log.Error($"InvalidOperationException: {ex.Message}"); // 处理无效操作 -// } -// catch (Exception ex) -// { -// Log.Error($"Exception: {ex.Message}"); // 捕获其他异常 -// } -// } -// -// #endregion -// } -// } -// -// #endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByPipe.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByPipe.cs deleted file mode 100644 index 407e8c9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByPipe.cs +++ /dev/null @@ -1,619 +0,0 @@ -#if FANTASY_NET -using System.Buffers; -using System.IO.Pipelines; -using System.Net; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8602 // Dereference of a possibly null reference. - -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). - -namespace Fantasy.Network.KCP -{ - internal sealed class KCPServerNetworkUpdateSystem : UpdateSystem - { - protected override void Update(KCPServerNetwork self) - { - self.Update(); - } - } - - internal struct PendingConnection - { - public readonly uint ChannelId; - public readonly uint TimeOutId; - public readonly IPEndPoint RemoteEndPoint; - - public PendingConnection(uint channelId, IPEndPoint remoteEndPoint, uint time) - { - ChannelId = channelId; - RemoteEndPoint = remoteEndPoint; - TimeOutId = time + 10 * 1000; // 设置10秒超时,如果10秒内没有确认连接则删除。 - } - } - - public sealed class KCPServerNetwork : ANetwork - { - private Socket _socket; - private long _startTime; - private uint _updateMinTime; - private uint _pendingMinTime; - private bool _allowWraparound = true; - private readonly Pipe _pipe = new Pipe(); - private readonly byte[] _sendBuff = new byte[5]; - private readonly List _pendingTimeOutTime = new List(); - private readonly HashSet _updateChannels = new HashSet(); - private readonly List _updateTimeOutTime = new List(); - private readonly Queue _endPoint = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - private readonly SortedOneToManyList _updateTimer = new SortedOneToManyList(); - - private readonly Dictionary _pendingConnection = new Dictionary(); - private readonly SortedOneToManyList _pendingConnectionTimeOut = new SortedOneToManyList(); - private readonly Dictionary _connectionChannel = new Dictionary(); - - public KCPSettings Settings { get; private set; } - - private uint TimeNow => (uint)(TimeHelper.Now - _startTime); - - public void Initialize(NetworkTarget networkTarget, IPEndPoint address) - { - _startTime = TimeHelper.Now; - Settings = KCPSettings.Create(networkTarget); - base.Initialize(NetworkType.Server, NetworkProtocolType.KCP, networkTarget); - _socket = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); - _socket.Blocking = false; - _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); - if (address.AddressFamily == AddressFamily.InterNetworkV6) - { - _socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); - } - - _socket.Blocking = false; - _socket.Bind(address); - _socket.SetSocketBufferToOsLimit(); - _socket.SetSioUdpConnReset(); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - Log.Info($"SceneConfigId = {Scene.SceneConfigId} networkTarget = {networkTarget.ToString()} KCPServer Listen {address}"); - } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - foreach (var (_, channel) in _connectionChannel.ToArray()) - { - channel.Dispose(); - } - - _connectionChannel.Clear(); - _pendingConnection.Clear(); - - if (_socket != null) - { - _socket.Dispose(); - _socket = null; - } - - base.Dispose(); - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); - var socketReceiveFromResult = await _socket.ReceiveFromAsync(memory, SocketFlags.None, remoteEndPoint, _cancellationTokenSource.Token); - var receivedBytes = socketReceiveFromResult.ReceivedBytes; - - if (receivedBytes == 5) - { - switch ((KcpHeader)memory.Span[0]) - { - case KcpHeader.RequestConnection: - case KcpHeader.ConfirmConnection: - { - _endPoint.Enqueue(socketReceiveFromResult.RemoteEndPoint.Clone()); - break; - } - } - } - - _pipe.Writer.Advance(receivedBytes); - await _pipe.Writer.FlushAsync(); - } - catch (SocketException ex) - { - Log.Error($"Socket exception: {ex.Message}"); - Dispose(); - break; - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (Exception ex) - { - Log.Error($"Unexpected exception: {ex.Message}"); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var header, out var channelId, out var message)) - { - ReceiveData(ref header, ref channelId, ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private unsafe bool TryReadMessage(ref ReadOnlySequence buffer, out KcpHeader header, out uint channelId, out ReadOnlyMemory message) - { - if (buffer.Length < 5) - { - channelId = 0; - message = default; - header = KcpHeader.None; - if (buffer.Length > 0) - { - buffer = buffer.Slice(buffer.Length); - } - return false; - } - - var readOnlyMemory = buffer.First; - - if (MemoryMarshal.TryGetArray(readOnlyMemory, out var arraySegment)) - { - fixed (byte* bytePointer = &arraySegment.Array[arraySegment.Offset]) - { - header = (KcpHeader)bytePointer[0]; - channelId = Unsafe.ReadUnaligned(ref bytePointer[1]); - } - } - else - { - // 如果无法获取数组段,回退到安全代码来执行。这种情况几乎不会发生、为了保险还是写一下了。 - var firstSpan = readOnlyMemory.Span; - header = (KcpHeader)firstSpan[0]; - channelId = MemoryMarshal.Read(firstSpan.Slice(1, 4)); - } - - message = readOnlyMemory.Slice(5); - buffer = buffer.Slice(readOnlyMemory.Length); - return true; - } - - private void ReceiveData(ref KcpHeader header, ref uint channelId, ref ReadOnlyMemory buffer) - { - switch (header) - { - // 客户端请求建立KCP连接 - case KcpHeader.RequestConnection: - { - _endPoint.TryDequeue(out var ipEndPoint); - - if (_pendingConnection.TryGetValue(channelId, out var pendingConnection)) - { - if (!ipEndPoint.IPEndPointEquals(pendingConnection.RemoteEndPoint)) - { - // 重复通道ID,向客户端发送重复通道ID消息 - SendRepeatChannelId(ref channelId, ipEndPoint); - } - - break; - } - - if (_connectionChannel.ContainsKey(channelId)) - { - // 已存在的通道ID,向客户端发送重复通道ID消息 - SendRepeatChannelId(ref channelId, ipEndPoint); - break; - } - - AddPendingConnection(ref channelId, ipEndPoint); - break; - } - // 客户端确认建立KCP连接 - case KcpHeader.ConfirmConnection: - { - _endPoint.TryDequeue(out var ipEndPoint); - if (!ConfirmPendingConnection(ref channelId, ipEndPoint)) - { - break; - } - - AddConnection(ref channelId, ipEndPoint.Clone()); - break; - } - // 接收KCP的数据 - case KcpHeader.ReceiveData: - { - if (buffer.Length == 5) - { - Log.Warning($"KCP Server KcpHeader.Data buffer.Length == 5"); - break; - } - - if (_connectionChannel.TryGetValue(channelId, out var channel)) - { - channel.Input(buffer); - } - - break; - } - // 断开KCP连接 - case KcpHeader.Disconnect: - { - // 断开不需要清楚PendingConnection让ClearPendingConnection自动清楚就可以了,并且不一定有Pending。 - RemoveChannel(channelId); - break; - } - } - } - - #endregion - - #region Update - - public void Update() - { - var timeNow = TimeNow; - _allowWraparound = timeNow < _updateMinTime; - CheckUpdateTimerOut(ref timeNow); - UpdateChannel(ref timeNow); - PendingTimerOut(ref timeNow); - _allowWraparound = true; - } - - private void CheckUpdateTimerOut(ref uint nowTime) - { - if (_updateTimer.Count == 0) - { - return; - } - - if (IsTimeGreaterThan(_updateMinTime, nowTime)) - { - return; - } - - _updateTimeOutTime.Clear(); - - foreach (var kv in _updateTimer) - { - var timeId = kv.Key; - - if (IsTimeGreaterThan(timeId, nowTime)) - { - _updateMinTime = timeId; - break; - } - - _updateTimeOutTime.Add(timeId); - } - - foreach (var timeId in _updateTimeOutTime) - { - foreach (var channelId in _updateTimer[timeId]) - { - _updateChannels.Add(channelId); - } - - _updateTimer.RemoveKey(timeId); - } - } - - private void UpdateChannel(ref uint timeNow) - { - foreach (var channelId in _updateChannels) - { - if (!_connectionChannel.TryGetValue(channelId, out var channel)) - { - continue; - } - - if (channel.IsDisposed) - { - _connectionChannel.Remove(channelId); - continue; - } - - channel.Kcp.Update(timeNow); - AddUpdateChannel(channelId, channel.Kcp.Check(timeNow)); - } - - _updateChannels.Clear(); - } - - private void PendingTimerOut(ref uint timeNow) - { - if (_pendingConnectionTimeOut.Count == 0) - { - return; - } - - if (IsTimeGreaterThan(_pendingMinTime, timeNow)) - { - return; - } - - _pendingTimeOutTime.Clear(); - - foreach (var kv in _pendingConnectionTimeOut) - { - var timeId = kv.Key; - - if (IsTimeGreaterThan(timeId, timeNow)) - { - _pendingMinTime = timeId; - break; - } - - _pendingTimeOutTime.Add(timeId); - } - - foreach (var timeId in _pendingTimeOutTime) - { - foreach (var channelId in _pendingConnectionTimeOut[timeId]) - { - _pendingConnection.Remove(channelId); - } - - _pendingConnectionTimeOut.RemoveKey(timeId); - } - } - - public void AddUpdateChannel(uint channelId, uint tillTime) - { - if (tillTime == 0) - { - _updateChannels.Add(channelId); - return; - } - - if (IsTimeGreaterThan(_updateMinTime, tillTime)) - { - _updateMinTime = tillTime; - } - - _updateTimer.Add(tillTime, channelId); - } - - private const uint HalfMaxUint = uint.MaxValue / 2; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool IsTimeGreaterThan(uint timeId, uint nowTime) - { - if (!_allowWraparound) - { - return timeId > nowTime; - } - - var diff = timeId - nowTime; - // 如果 diff 的值在 [0, HalfMaxUint] 范围内,说明 timeId 是在 nowTime 之后或相等。 - // 如果 diff 的值在 (HalfMaxUint, uint.MaxValue] 范围内,说明 timeId 是在 nowTime 之前(时间回绕的情况)。 - return diff < HalfMaxUint || diff == HalfMaxUint; - } - - #endregion - - #region Pending - - private void AddPendingConnection(ref uint channelId, IPEndPoint ipEndPoint) - { - var now = TimeNow; - var pendingConnection = new PendingConnection(channelId, ipEndPoint, now); - - if (IsTimeGreaterThan(_pendingMinTime, pendingConnection.TimeOutId) || _pendingMinTime == 0) - { - _pendingMinTime = pendingConnection.TimeOutId; - } - - _pendingConnection.Add(channelId, pendingConnection); - _pendingConnectionTimeOut.Add(pendingConnection.TimeOutId, channelId); - SendWaitConfirmConnection(ref channelId, ipEndPoint); - } - - private bool ConfirmPendingConnection(ref uint channelId, EndPoint ipEndPoint) - { - if (!_pendingConnection.TryGetValue(channelId, out var pendingConnection)) - { - return false; - } - - if (!ipEndPoint.IPEndPointEquals(pendingConnection.RemoteEndPoint)) - { - Log.Error($"KCPSocket syn address diff: {channelId} {pendingConnection.RemoteEndPoint} {ipEndPoint}"); - return false; - } - - _pendingConnection.Remove(channelId); - _pendingConnectionTimeOut.RemoveValue(pendingConnection.TimeOutId, pendingConnection.ChannelId); -#if FANTASY_DEVELOP - Log.Debug($"KCPSocket _pendingConnection:{_pendingConnection.Count} _pendingConnectionTimer:{_pendingConnectionTimeOut.Count}"); -#endif - return true; - } - - #endregion - - #region Connection - - private void AddConnection(ref uint channelId, IPEndPoint ipEndPoint) - { - var eventArgs = new KCPServerNetworkChannel(this, channelId, ipEndPoint); - _connectionChannel.Add(channelId, eventArgs); -#if FANTASY_DEVELOP - Log.Debug($"AddConnection _connectionChannel:{_connectionChannel.Count()}"); -#endif - } - - public override void RemoveChannel(uint channelId) - { - if (!_connectionChannel.Remove(channelId, out var channel)) - { - return; - } - - if (!channel.IsDisposed) - { - SendDisconnect(ref channelId, channel.RemoteEndPoint); - channel.Dispose(); - } -#if FANTASY_DEVELOP - Log.Debug($"RemoveChannel _connectionChannel:{_connectionChannel.Count()}"); -#endif - } - - #endregion - - #region Send - - private const byte KcpHeaderDisconnect = (byte)KcpHeader.Disconnect; - private const byte KcpHeaderRepeatChannelId = (byte)KcpHeader.RepeatChannelId; - private const byte KcpHeaderWaitConfirmConnection = (byte)KcpHeader.WaitConfirmConnection; - - private unsafe void SendDisconnect(ref uint channelId, EndPoint clientEndPoint) - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderDisconnect; - *(uint*)(p + 1) = channelId; - } - - SendAsync(_sendBuff, 0, 5, clientEndPoint); - } - - private unsafe void SendRepeatChannelId(ref uint channelId, EndPoint clientEndPoint) - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderRepeatChannelId; - *(uint*)(p + 1) = channelId; - } - - SendAsync(_sendBuff, 0, 5, clientEndPoint); - } - - private unsafe void SendWaitConfirmConnection(ref uint channelId, EndPoint clientEndPoint) - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderWaitConfirmConnection; - *(uint*)(p + 1) = channelId; - } - - SendAsync(_sendBuff, 0, 5, clientEndPoint); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SendAsync(byte[] buffer, int offset, int count, EndPoint endPoint) - { - try - { - _socket.SendTo(new ArraySegment(buffer, offset, count), SocketFlags.None, endPoint); - } - catch (ArgumentException ex) - { - Log.Error($"ArgumentException: {ex.Message}"); // 处理参数错误 - } - catch (SocketException) - { - //Log.Error($"SocketException: {ex.Message}"); // 处理网络错误 - } - catch (ObjectDisposedException) - { - // 处理套接字已关闭的情况 - } - catch (InvalidOperationException ex) - { - Log.Error($"InvalidOperationException: {ex.Message}"); // 处理无效操作 - } - catch (Exception ex) - { - Log.Error($"Exception: {ex.Message}"); // 捕获其他异常 - } - } - - #endregion - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkChannel.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkChannel.cs deleted file mode 100644 index 4216fa7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkChannel.cs +++ /dev/null @@ -1,165 +0,0 @@ -#if FANTASY_NET -using System.Net; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -using KCP; -// ReSharper disable ParameterHidesMember -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.KCP -{ - /// - /// KCP 服务器网络通道,用于处理服务器与客户端之间的数据通信。 - /// - internal class KCPServerNetworkChannel : ANetworkServerChannel - { - private bool _isInnerDispose; - private readonly int _maxSndWnd; - private KCPServerNetwork _kcpServerNetwork; - private readonly BufferPacketParser _packetParser; - private readonly byte[] _receiveBuffer = new byte[ProgramDefine.MaxMessageSize + 20]; - public Kcp Kcp { get; private set; } - public uint ChannelId { get; private set; } - - public KCPServerNetworkChannel(KCPServerNetwork network, uint channelId, IPEndPoint ipEndPoint) : base(network, channelId, ipEndPoint) - { - _kcpServerNetwork = network; - ChannelId = channelId; - _maxSndWnd = network.Settings.MaxSendWindowSize; - Kcp = KCPFactory.Create(network.Settings, ChannelId, KcpSpanCallback); - _packetParser = PacketParserFactory.CreateServerBufferPacket(network); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isInnerDispose = true; - _kcpServerNetwork.RemoveChannel(Id); - IsDisposed = true; - Kcp.Dispose(); - Kcp = null; - ChannelId = 0; - _kcpServerNetwork = null; - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - public void Input(ReadOnlyMemory buffer) - { - Kcp.Input(buffer.Span); - _kcpServerNetwork.AddUpdateChannel(ChannelId, 0); - - while (!IsDisposed) - { - try - { - var peekSize = Kcp.PeekSize(); - - if (peekSize < 0) - { - return; - } - - var receiveCount = Kcp.Receive(_receiveBuffer.AsSpan(0, peekSize)); - - if (receiveCount != peekSize) - { - return; - } - - if (!_packetParser.UnPack(_receiveBuffer, ref receiveCount, out var packInfo)) - { - continue; - } - - Session.Receive(packInfo); - } - catch (ScanException e) - { - Log.Debug($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - if (IsDisposed) - { - return; - } - - if (Kcp.WaitSendCount > _maxSndWnd) - { - // 检查等待发送的消息,如果超出两倍窗口大小,KCP作者给的建议是要断开连接 - Log.Warning($"ERR_KcpWaitSendSizeTooLarge {Kcp.WaitSendCount} > {_maxSndWnd}"); - Dispose(); - return; - } - - var buffer = _packetParser.Pack(ref rpcId, ref routeId, memoryStream, message); - Kcp.Send(buffer.GetBuffer().AsSpan(0, (int)buffer.Position)); - - if (buffer.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - _kcpServerNetwork.MemoryStreamBufferPool.ReturnMemoryStream(buffer); - } - - _kcpServerNetwork.AddUpdateChannel(ChannelId, 0); - } - - private const byte KcpHeaderReceiveData = (byte)KcpHeader.ReceiveData; - - private unsafe void KcpSpanCallback(byte[] buffer, int count) - { - if (IsDisposed) - { - return; - } - - try - { - if (count == 0) - { - throw new Exception("KcpOutput count 0"); - } - - fixed (byte* p = buffer) - { - p[0] = KcpHeaderReceiveData; - *(uint*)(p + 1) = ChannelId; - } - - _kcpServerNetwork.SendAsync(buffer, 0, count + 5, RemoteEndPoint); - } - catch (Exception e) - { - Log.Error(e); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/NetworkProtocolFactory.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/NetworkProtocolFactory.cs deleted file mode 100644 index 995c8aa..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/NetworkProtocolFactory.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Net; -using Fantasy.Entitas; -using Fantasy.Helper; -using Fantasy.Network.Interface; -#if !FANTASY_WEBGL -using Fantasy.Network.TCP; -using Fantasy.Network.KCP; -#endif -#if FANTASY_NET -using Fantasy.Network.HTTP; -#endif -using Fantasy.Network.WebSocket; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network -{ - internal static class NetworkProtocolFactory - { -#if FANTASY_NET - public static ANetwork CreateServer(Scene scene, NetworkProtocolType protocolType, NetworkTarget networkTarget, string bindIp, int port) - { - switch (protocolType) - { - case NetworkProtocolType.TCP: - { - var network = Entity.Create(scene, false, false); - var address = NetworkHelper.ToIPEndPoint(bindIp, port); - network.Initialize(networkTarget, address); - return network; - } - case NetworkProtocolType.KCP: - { - var network = Entity.Create(scene, false, true); - var address = NetworkHelper.ToIPEndPoint(bindIp, port); - network.Initialize(networkTarget, address); - return network; - } - case NetworkProtocolType.WebSocket: - { - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget, port); - return network; - } - case NetworkProtocolType.HTTP: - { - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget, bindIp, port); - return network; - } - default: - { - throw new NotSupportedException($"Unsupported NetworkProtocolType:{protocolType}"); - } - } - } -#endif - public static AClientNetwork CreateClient(Scene scene, NetworkProtocolType protocolType, NetworkTarget networkTarget) - { -#if !FANTASY_WEBGL - switch (protocolType) - { - case NetworkProtocolType.TCP: - { - var network = Entity.Create(scene, false, false); - network.Initialize(networkTarget); - return network; - } - case NetworkProtocolType.KCP: - { - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget); - return network; - } - case NetworkProtocolType.WebSocket: - { - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget); - return network; - } - default: - { - throw new NotSupportedException($"Unsupported NetworkProtocolType:{protocolType}"); - } - } -#else - // Webgl平台只能用这个协议。 - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget); - return network; -#endif - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/NetworkProtocolType.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/NetworkProtocolType.cs deleted file mode 100644 index 55a04c9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/NetworkProtocolType.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace Fantasy.Network -{ - /// - /// 网络服务器类型 - /// - public enum NetworkType - { - /// - /// 默认 - /// - None = 0, - /// - /// 客户端网络 - /// - Client = 1, -#if FANTASY_NET - /// - /// 服务器网络 - /// - Server = 2 -#endif - } - /// - /// 网络服务的目标 - /// - public enum NetworkTarget - { - /// - /// 默认 - /// - None = 0, - /// - /// 对外 - /// - Outer = 1, -#if FANTASY_NET - /// - /// 对内 - /// - Inner = 2 -#endif - } - /// - /// 支持的网络协议 - /// - public enum NetworkProtocolType - { - /// - /// 默认 - /// - None = 0, - /// - /// KCP - /// - KCP = 1, - /// - /// TCP - /// - TCP = 2, - /// - /// WebSocket - /// - WebSocket = 3, - /// - /// HTTP - /// - HTTP = 4, - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/NetworkThreadComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/NetworkThreadComponent.cs deleted file mode 100644 index c0c166b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/NetworkThreadComponent.cs +++ /dev/null @@ -1,100 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Threading; -using Fantasy.Entitas; -// ReSharper disable ForCanBeConvertedToForeach -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Network -{ - internal interface INetworkThreadUpdate - { - void Update(); - } - - /// - /// 网络线程组件 - /// - internal sealed class NetworkThreadComponent : Entity - { - private Thread _netWorkThread; - internal ThreadSynchronizationContext SynchronizationContext { get; private set; } - private readonly List _updates = new List(); - - internal NetworkThreadComponent Initialize() - { - SynchronizationContext = new ThreadSynchronizationContext(); - _netWorkThread = new Thread(Update) - { - IsBackground = true - }; - _netWorkThread.Start(); - return this; - } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - SynchronizationContext.Post(() => - { - _updates.Clear(); - _netWorkThread.Join(); - _netWorkThread = null; - SynchronizationContext = null; - }); - - base.Dispose(); - } - - private void Update() - { - // 将同步上下文设置为网络线程的上下文,以确保操作在正确的线程上下文中执行。 - System.Threading.SynchronizationContext.SetSynchronizationContext(SynchronizationContext); - // 循环执行 - while (!IsDisposed) - { - for (var i = 0; i < _updates.Count; i++) - { - try - { - _updates[i].Update(); - } - catch (Exception e) - { - Log.Error(e); - } - } - SynchronizationContext.Update(); - Thread.Sleep(1); - } - } - - internal void AddNetworkThreadUpdate(INetworkThreadUpdate update) - { - SynchronizationContext.Post(() => - { - if (_updates.Contains(update)) - { - Log.Warning($"{update.GetType().FullName} Network thread update is already running"); - return; - } - _updates.Add(update); - }); - } - - internal void RemoveNetworkThreadUpdate(INetworkThreadUpdate update) - { - SynchronizationContext.Post(() => - { - _updates.Remove(update); - }); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/TCP/Client/TCPClientNetwork.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/TCP/Client/TCPClientNetwork.cs deleted file mode 100644 index 233fb7b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/TCP/Client/TCPClientNetwork.cs +++ /dev/null @@ -1,413 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Buffers; -using System.Collections.Generic; -using System.IO; -using System.IO.Pipelines; -using System.Net; -using System.Net.Sockets; -using System.Runtime.InteropServices; -using System.Threading; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). - -namespace Fantasy.Network.TCP -{ - public sealed class TCPClientNetwork : AClientNetwork - { - private bool _isSending; - private bool _isInnerDispose; - private long _connectTimeoutId; - private Socket _socket; - private IPEndPoint _remoteEndPoint; - private SocketAsyncEventArgs _sendArgs; - private ReadOnlyMemoryPacketParser _packetParser; - private readonly Pipe _pipe = new Pipe(); - private readonly Queue _sendBuffers = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - private Action _onConnectFail; - private Action _onConnectComplete; - private Action _onConnectDisconnect; - - public uint ChannelId { get; private set; } - - public void Initialize(NetworkTarget networkTarget) - { - base.Initialize(NetworkType.Client, NetworkProtocolType.TCP, networkTarget); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isSending = false; - _isInnerDispose = true; - ClearConnectTimeout(); - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - _onConnectDisconnect?.Invoke(); - - if (_socket.Connected) - { - _socket.Close(); - _socket = null; - } - - _sendBuffers.Clear(); - _packetParser?.Dispose(); - ChannelId = 0; - _sendArgs = null; - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - /// - /// 连接到远程服务器。 - /// - /// 远程服务器的终端点。 - /// 连接成功时的回调。 - /// 连接失败时的回调。 - /// 连接断开时的回调。 - /// - /// 连接超时时间,单位:毫秒。 - /// 连接的会话。 - public override Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - // 如果已经初始化过一次,抛出异常,要求重新实例化 - - if (IsInit) - { - throw new NotSupportedException("TCPClientNetwork Has already been initialized. If you want to call Connect again, please re instantiate it."); - } - - IsInit = true; - _isSending = false; - _onConnectFail = onConnectFail; - _onConnectComplete = onConnectComplete; - _onConnectDisconnect = onConnectDisconnect; - // 设置连接超时定时器 - _connectTimeoutId = Scene.TimerComponent.Net.OnceTimer(connectTimeout, () => - { - _onConnectFail?.Invoke(); - Dispose(); - }); - _packetParser = PacketParserFactory.CreateClientReadOnlyMemoryPacket(this); - _remoteEndPoint = NetworkHelper.GetIPEndPoint(remoteAddress); - _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - _socket.NoDelay = true; - _socket.SetSocketBufferToOsLimit(); - _sendArgs = new SocketAsyncEventArgs(); - _sendArgs.Completed += OnSendCompleted; - var outArgs = new SocketAsyncEventArgs - { - RemoteEndPoint = _remoteEndPoint - }; - outArgs.Completed += OnConnectSocketCompleted; - - if (!_socket.ConnectAsync(outArgs)) - { - OnReceiveSocketComplete(); - } - - Session = Session.Create(this, _remoteEndPoint); - return Session; - } - - private void OnConnectSocketCompleted(object sender, SocketAsyncEventArgs asyncEventArgs) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - if (asyncEventArgs.LastOperation == SocketAsyncOperation.Connect) - { - if (asyncEventArgs.SocketError == SocketError.Success) - { - Scene.ThreadSynchronizationContext.Post(OnReceiveSocketComplete); - } - else - { - Scene.ThreadSynchronizationContext.Post(() => - { - _onConnectFail?.Invoke(); - Dispose(); - }); - } - } - } - - private void OnReceiveSocketComplete() - { - ClearConnectTimeout(); - _onConnectComplete?.Invoke(); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); -#if UNITY_2021 - // Unity2021.3.14f有个恶心的问题,使用ReceiveAsync会导致memory不能正确写入 - // 所有只能使用ReceiveFromAsync来接收消息,但ReceiveFromAsync只有一个接受ArraySegment的接口。 - MemoryMarshal.TryGetArray(memory, out ArraySegment arraySegment); - var result = await _socket.ReceiveFromAsync(arraySegment, SocketFlags.None, _remoteEndPoint); - _pipe.Writer.Advance(result.ReceivedBytes); -#else - var count = await _socket.ReceiveAsync(memory, SocketFlags.None, _cancellationTokenSource.Token); - _pipe.Writer.Advance(count); -#endif - await _pipe.Writer.FlushAsync(); - } - catch (SocketException) - { - Dispose(); - break; - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (Exception ex) - { - Log.Error($"Unexpected exception: {ex.Message}"); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var message)) - { - ReceiveData(ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private bool TryReadMessage(ref ReadOnlySequence buffer, out ReadOnlyMemory message) - { - if (buffer.Length == 0) - { - message = default; - return false; - } - - message = buffer.First; - - if (message.Length == 0) - { - message = default; - return false; - } - - buffer = buffer.Slice(message.Length); - return true; - } - - private void ReceiveData(ref ReadOnlyMemory buffer) - { - try - { - while (_packetParser.UnPack(ref buffer, out var packInfo)) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - Session.Receive(packInfo); - } - } - catch (ScanException e) - { - Log.Warning(e.Message); - Dispose(); - } - catch (Exception e) - { - Log.Error(e); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - _sendBuffers.Enqueue(_packetParser.Pack(ref rpcId, ref routeId, memoryStream, message)); - - if (!_isSending) - { - Send(); - } - } - - private void Send() - { - if (_isSending || IsDisposed) - { - return; - } - - _isSending = true; - - while (_sendBuffers.Count > 0) - { - var memoryStreamBuffer = _sendBuffers.Dequeue(); - _sendArgs.UserToken = memoryStreamBuffer; - _sendArgs.SetBuffer(new ArraySegment(memoryStreamBuffer.GetBuffer(), 0, (int)memoryStreamBuffer.Position)); - - try - { - if (_socket.SendAsync(_sendArgs)) - { - break; - } - - ReturnMemoryStream(memoryStreamBuffer); - } - catch - { - _isSending = false; - return; - } - } - - _isSending = false; - } - - private void ReturnMemoryStream(MemoryStreamBuffer memoryStream) - { - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - - private void OnSendCompleted(object sender, SocketAsyncEventArgs asyncEventArgs) - { - if (asyncEventArgs.SocketError != SocketError.Success || asyncEventArgs.BytesTransferred == 0) - { - _isSending = false; - return; - } - - var memoryStreamBuffer = (MemoryStreamBuffer)asyncEventArgs.UserToken; - Scene.ThreadSynchronizationContext.Post(() => - { - ReturnMemoryStream(memoryStreamBuffer); - - if (_sendBuffers.Count > 0) - { - Send(); - } - else - { - _isSending = false; - } - }); - } - - #endregion - - public override void RemoveChannel(uint channelId) - { - Dispose(); - } - - private void ClearConnectTimeout() - { - if (_connectTimeoutId == 0) - { - return; - } - - Scene?.TimerComponent?.Net?.Remove(ref _connectTimeoutId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetwork.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetwork.cs deleted file mode 100644 index 3e8efb4..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetwork.cs +++ /dev/null @@ -1,161 +0,0 @@ -#if FANTASY_NET -using System.Net; -using System.Net.Sockets; -using Fantasy.Helper; -using Fantasy.Network.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -// ReSharper disable GCSuppressFinalizeForTypeWithoutDestructor -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Network.TCP -{ - public sealed class TCPServerNetwork : ANetwork - { - private Random _random; - private Socket _socket; - private SocketAsyncEventArgs _acceptAsync; - private readonly Dictionary _connectionChannel = new Dictionary(); - - public void Initialize(NetworkTarget networkTarget, IPEndPoint address) - { - base.Initialize(NetworkType.Server, NetworkProtocolType.TCP, networkTarget); - _random = new Random(); - _acceptAsync = new SocketAsyncEventArgs(); - _socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); - - if (address.AddressFamily == AddressFamily.InterNetworkV6) - { - _socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); - } - - _socket.Bind(address); - _socket.Listen(int.MaxValue); - _socket.SetSocketBufferToOsLimit(); - Log.Info($"SceneConfigId = {Scene.SceneConfigId} networkTarget = {networkTarget.ToString()} TCPServer Listen {address}"); - _acceptAsync.Completed += OnCompleted; - AcceptAsync(); - } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - try - { - foreach (var networkChannel in _connectionChannel.Values.ToArray()) - { - networkChannel.Dispose(); - } - - _connectionChannel.Clear(); - _random = null; - _socket.Dispose(); - _socket = null; - _acceptAsync.Dispose(); - _acceptAsync = null; - GC.SuppressFinalize(this); - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - private void AcceptAsync() - { - _acceptAsync.AcceptSocket = null; - - if (_socket.AcceptAsync(_acceptAsync)) - { - return; - } - - OnAcceptComplete(_acceptAsync); - } - - private void OnAcceptComplete(SocketAsyncEventArgs asyncEventArgs) - { - if (asyncEventArgs.AcceptSocket == null) - { - return; - } - - if (asyncEventArgs.SocketError != SocketError.Success) - { - Log.Error($"Socket Accept Error: {_acceptAsync.SocketError}"); - return; - } - - try - { - uint channelId; - do - { - channelId = 0xC0000000 | (uint)_random.Next(); - } while (_connectionChannel.ContainsKey(channelId)); - - _connectionChannel.Add(channelId, new TCPServerNetworkChannel(this, asyncEventArgs.AcceptSocket, channelId)); - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - AcceptAsync(); - } - } - - public override void RemoveChannel(uint channelId) - { - if (IsDisposed || !_connectionChannel.Remove(channelId, out var channel)) - { - return; - } - - if (channel.IsDisposed) - { - return; - } - - channel.Dispose(); - } - - #region 网络线程(由Socket底层产生的线程) - - private void OnCompleted(object sender, SocketAsyncEventArgs asyncEventArgs) - { - switch (asyncEventArgs.LastOperation) - { - case SocketAsyncOperation.Accept: - { - Scene.ThreadSynchronizationContext.Post(() => - { - OnAcceptComplete(asyncEventArgs); - }); - break; - } - default: - { - throw new Exception($"Socket Accept Error: {asyncEventArgs.LastOperation}"); - } - } - } - - #endregion - } -} -#endif - - diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetworkChannel.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetworkChannel.cs deleted file mode 100644 index 15f3f66..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetworkChannel.cs +++ /dev/null @@ -1,294 +0,0 @@ -#if FANTASY_NET -using System.Buffers; -using System.IO.Pipelines; -using System.Net.Sockets; -using Fantasy.Async; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. - -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). - -namespace Fantasy.Network.TCP -{ - public sealed class TCPServerNetworkChannel : ANetworkServerChannel - { - private bool _isSending; - private bool _isInnerDispose; - private readonly Socket _socket; - private readonly ANetwork _network; - private readonly Pipe _pipe = new Pipe(); - private readonly SocketAsyncEventArgs _sendArgs; - private readonly ReadOnlyMemoryPacketParser _packetParser; - private readonly Queue _sendBuffers = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - public TCPServerNetworkChannel(ANetwork network, Socket socket, uint id) : base(network, id, socket.RemoteEndPoint) - { - _socket = socket; - _network = network; - _socket.NoDelay = true; - _sendArgs = new SocketAsyncEventArgs(); - _sendArgs.Completed += OnSendCompletedHandler; - _packetParser = PacketParserFactory.CreateServerReadOnlyMemoryPacket(network); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - _isInnerDispose = true; - _network.RemoveChannel(Id); - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - if (_socket != null) - { - _socket.Shutdown(SocketShutdown.Both); - _socket.Close(); - } - - _sendBuffers.Clear(); - _packetParser.Dispose(); - _isSending = false; - base.Dispose(); - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); - var count = await _socket.ReceiveAsync(memory, SocketFlags.None, _cancellationTokenSource.Token); - - if (count == 0) - { - Dispose(); - return; - } - - _pipe.Writer.Advance(count); - await _pipe.Writer.FlushAsync(); - } - catch (SocketException) - { - Dispose(); - break; - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (Exception ex) - { - Log.Error($"Unexpected exception: {ex.Message}"); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var message)) - { - ReceiveData(ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private bool TryReadMessage(ref ReadOnlySequence buffer, out ReadOnlyMemory message) - { - if (buffer.Length == 0) - { - message = default; - return false; - } - - message = buffer.First; - - if (message.Length == 0) - { - message = default; - return false; - } - - buffer = buffer.Slice(message.Length); - return true; - } - - private void ReceiveData(ref ReadOnlyMemory buffer) - { - try - { - while (_packetParser.UnPack(ref buffer, out var packInfo)) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - Session.Receive(packInfo); - } - } - catch (ScanException e) - { - Log.Warning($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - catch (Exception e) - { - Log.Error($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - _sendBuffers.Enqueue(_packetParser.Pack(ref rpcId, ref routeId, memoryStream, message)); - - if (!_isSending) - { - Send(); - } - } - - private void Send() - { - if (_isSending || IsDisposed) - { - return; - } - - _isSending = true; - - while (_sendBuffers.Count > 0) - { - var memoryStreamBuffer = _sendBuffers.Dequeue(); - _sendArgs.UserToken = memoryStreamBuffer; - _sendArgs.SetBuffer(new ArraySegment(memoryStreamBuffer.GetBuffer(), 0, (int)memoryStreamBuffer.Position)); - - try - { - if (_socket.SendAsync(_sendArgs)) - { - break; - } - - ReturnMemoryStream(memoryStreamBuffer); - } - catch - { - _isSending = false; - return; - } - } - - _isSending = false; - } - - private void ReturnMemoryStream(MemoryStreamBuffer memoryStream) - { - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - _network.MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - - private void OnSendCompletedHandler(object sender, SocketAsyncEventArgs asyncEventArgs) - { - if (asyncEventArgs.SocketError != SocketError.Success || asyncEventArgs.BytesTransferred == 0) - { - _isSending = false; - return; - } - - var memoryStreamBuffer = (MemoryStreamBuffer)asyncEventArgs.UserToken; - - Scene.ThreadSynchronizationContext.Post(() => - { - ReturnMemoryStream(memoryStreamBuffer); - - if (_sendBuffers.Count > 0) - { - Send(); - } - else - { - _isSending = false; - } - }); - } - - #endregion - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetwork.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetwork.cs deleted file mode 100644 index ef0b78f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetwork.cs +++ /dev/null @@ -1,346 +0,0 @@ -#if FANTASY_NET || FANTASY_CONSOLE -using System.Buffers; -using System.IO.Pipelines; -using System.Net.WebSockets; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -namespace Fantasy.Network.WebSocket -{ - public sealed class WebSocketClientNetwork : AClientNetwork - { - private bool _isSending; - private bool _isInnerDispose; - private long _connectTimeoutId; - private ClientWebSocket _clientWebSocket; - private ReadOnlyMemoryPacketParser _packetParser; - private readonly Pipe _pipe = new Pipe(); - private readonly Queue _sendBuffers = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - private Action _onConnectFail; - private Action _onConnectComplete; - private Action _onConnectDisconnect; - - public void Initialize(NetworkTarget networkTarget) - { - base.Initialize(NetworkType.Client, NetworkProtocolType.WebSocket, networkTarget); - _packetParser = PacketParserFactory.CreateClientReadOnlyMemoryPacket(this); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isInnerDispose = true; - - if (_clientWebSocket.State == WebSocketState.Open || _clientWebSocket.State == WebSocketState.CloseReceived) - { - _clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client Closing", CancellationToken.None).GetAwaiter().GetResult(); - } - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - ClearConnectTimeout(); - _onConnectDisconnect?.Invoke(); - _packetParser.Dispose(); - _packetParser = null; - _isSending = false; - - _clientWebSocket.Dispose(); - _clientWebSocket = null; - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - public override Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - if (IsInit) - { - throw new NotSupportedException( - $"WebSocketClientNetwork Id:{Id} Has already been initialized. If you want to call Connect again, please re instantiate it."); - } - - IsInit = true; - _onConnectFail = onConnectFail; - _onConnectComplete = onConnectComplete; - _onConnectDisconnect = onConnectDisconnect; - // 设置连接超时定时器 - _connectTimeoutId = Scene.TimerComponent.Net.OnceTimer(connectTimeout, () => - { - _onConnectFail?.Invoke(); - Dispose(); - }); - - _clientWebSocket = new ClientWebSocket(); - var webSocketAddress = WebSocketHelper.GetWebSocketAddress(remoteAddress, isHttps); - - try - { - _clientWebSocket.ConnectAsync(new Uri(webSocketAddress), _cancellationTokenSource.Token).Wait(); - - if (_cancellationTokenSource.IsCancellationRequested) - { - return null; - } - } - catch (WebSocketException wse) - { - Log.Error($"WebSocket error: {wse.Message}"); - Dispose(); - return null; - } - catch (Exception e) - { - Log.Error($"An error occurred: {e.Message}"); - Dispose(); - return null; - } - - ClearConnectTimeout(); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - _onConnectComplete?.Invoke(); - Session = Session.Create(this, null); - return Session; - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); - // 这里接收的数据不一定是一个完整的包。如果大于8192就会分成多个包。 - var receiveResult = await _clientWebSocket.ReceiveAsync(memory, _cancellationTokenSource.Token); - // 服务器发送了关闭帧,客户端需要响应关闭帧 - if (receiveResult.MessageType == WebSocketMessageType.Close) - { - if (_clientWebSocket.State == WebSocketState.CloseReceived) - { - await _clientWebSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Response Closure", - CancellationToken.None); - } - Dispose(); - return; - } - - var count = receiveResult.Count; - - if (count > 0) - { - await PipeWriterFlushAsync(count); - } - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - // 这个先暂时注释掉,因为有些时候会出现WebSocketException - // 因为会出现这个挥手的错误,下个版本处理一下。 - // The remote party closed the WebSocket connection without completing the close handshake. - // catch (WebSocketException wse) - // { - // Log.Error($"WebSocket error: {wse.Message}"); - // Dispose(); - // break; - // } - catch (Exception e) - { - Log.Error(e); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - private async FTask PipeWriterFlushAsync(int count) - { - _pipe.Writer.Advance(count); - await _pipe.Writer.FlushAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var message)) - { - ReceiveData(ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private bool TryReadMessage(ref ReadOnlySequence buffer, out ReadOnlyMemory message) - { - if (buffer.Length == 0) - { - message = default; - return false; - } - - message = buffer.First; - - if (message.Length == 0) - { - message = default; - return false; - } - - buffer = buffer.Slice(message.Length); - return true; - } - - private void ReceiveData(ref ReadOnlyMemory buffer) - { - try - { - while (_packetParser.UnPack(ref buffer, out var packInfo)) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - Session.Receive(packInfo); - } - } - catch (ScanException e) - { - Log.Warning(e.Message); - Dispose(); - } - catch (Exception e) - { - Log.Error(e); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - _sendBuffers.Enqueue(_packetParser.Pack(ref rpcId, ref routeId, memoryStream, message)); - - if (!_isSending) - { - Send().Coroutine(); - } - } - - private async FTask Send() - { - if (_isSending || IsDisposed) - { - return; - } - - _isSending = true; - - while (_isSending) - { - if (!_sendBuffers.TryDequeue(out var memoryStream)) - { - _isSending = false; - return; - } - - await _clientWebSocket.SendAsync(new ArraySegment(memoryStream.GetBuffer(), 0, (int)memoryStream.Position), WebSocketMessageType.Binary, true, _cancellationTokenSource.Token); - - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - } - - #endregion - - public override void RemoveChannel(uint channelId) - { - Dispose(); - } - - private void ClearConnectTimeout() - { - if (_connectTimeoutId == 0) - { - return; - } - - Scene?.TimerComponent?.Net?.Remove(ref _connectTimeoutId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetworkWebgl.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetworkWebgl.cs deleted file mode 100644 index 36ef84d..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetworkWebgl.cs +++ /dev/null @@ -1,190 +0,0 @@ -#if !FANTASY_NET && !FANTASY_CONSOLE -using System; -using System.Collections.Generic; -using System.IO; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -using UnityWebSocket; - -namespace Fantasy.Network.WebSocket -{ - // 因为webgl的限制、注定这个要是在游戏主线程里。所以这个库不会再其他线程执行的。 - // WebGL:在WebGL环境下运行 - // 另外不是运行在WebGL环境下,也没必要使用WebSocket协议了。完全可以使用TCP或KCP运行。同样也不会有那个队列产生的GC。 - public class WebSocketClientNetwork : AClientNetwork - { - private UnityWebSocket.WebSocket _webSocket; - private bool _isInnerDispose; - private bool _isConnected; - private long _connectTimeoutId; - private BufferPacketParser _packetParser; - private readonly Queue _messageCache = new Queue(); - - private Action _onConnectFail; - private Action _onConnectComplete; - private Action _onConnectDisconnect; - - public void Initialize(NetworkTarget networkTarget) - { - base.Initialize(NetworkType.Client, NetworkProtocolType.WebSocket, networkTarget); - _packetParser = PacketParserFactory.CreateClient(this); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isInnerDispose = true; - ClearConnectTimeout(); - - if (_webSocket != null && _webSocket.ReadyState != WebSocketState.Closed) - { - _onConnectDisconnect?.Invoke(); - _webSocket.CloseAsync(); - } - - _packetParser.Dispose(); - _messageCache.Clear(); - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - public override Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - // 如果已经初始化过一次,抛出异常,要求重新实例化 - - if (IsInit) - { - throw new NotSupportedException($"WebSocketClientNetwork Id:{Id} Has already been initialized. If you want to call Connect again, please re instantiate it."); - } - - IsInit = true; - _onConnectFail = onConnectFail; - _onConnectComplete = onConnectComplete; - _onConnectDisconnect = onConnectDisconnect; - _connectTimeoutId = Scene.TimerComponent.Net.OnceTimer(connectTimeout, () => - { - _onConnectFail?.Invoke(); - Dispose(); - }); - var webSocketAddress = WebSocketHelper.GetWebSocketAddress(remoteAddress, isHttps); - _webSocket = new UnityWebSocket.WebSocket(webSocketAddress); - _webSocket.OnOpen += OnNetworkConnectComplete; - _webSocket.OnMessage += OnReceiveComplete; - _webSocket.OnClose += (sender, args) => - { - _onConnectDisconnect?.Invoke(); - Dispose(); - }; - _webSocket.ConnectAsync(); - Session = Session.Create(this, null); - return Session; - } - - private void OnNetworkConnectComplete(object sender, OpenEventArgs e) - { - if (IsDisposed) - { - return; - } - - _isConnected = true; - ClearConnectTimeout(); - _onConnectComplete?.Invoke(); - - while (_messageCache.TryDequeue(out var memoryStream)) - { - Send(memoryStream); - } - } - - #region Receive - - private void OnReceiveComplete(object sender, MessageEventArgs e) - { - try - { - // WebSocket 协议已经在协议层面处理了消息的边界问题,因此不需要额外的粘包处理逻辑。 - // 所以如果解包的时候出现任何错误只能是恶意攻击造成的。 - var rawDataLength = e.RawData.Length; - _packetParser.UnPack(e.RawData, ref rawDataLength, out var packInfo); - Session.Receive(packInfo); - } - catch (ScanException ex) - { - Log.Warning($"{ex}"); - Dispose(); - } - catch (Exception ex) - { - Log.Error($"{ex}"); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - if (IsDisposed) - { - return; - } - - var buffer = _packetParser.Pack(ref rpcId, ref routeId, memoryStream, message); - - if (!_isConnected) - { - _messageCache.Enqueue(buffer); - return; - } - - Send(buffer); - } - - private void Send(MemoryStreamBuffer memoryStream) - { - _webSocket.SendAsync(memoryStream.GetBuffer(), 0, (int)memoryStream.Position); -#if !UNITY_EDITOR && UNITY_WEBGL - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } -#endif - } - - #endregion - - public override void RemoveChannel(uint channelId) - { - Dispose(); - } - - private void ClearConnectTimeout() - { - if (_connectTimeoutId == 0) - { - return; - } - - Scene?.TimerComponent?.Net?.Remove(ref _connectTimeoutId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetwork.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetwork.cs deleted file mode 100644 index 779eff7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetwork.cs +++ /dev/null @@ -1,153 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#if FANTASY_NET -using System.Net; -using System.Security.Cryptography.X509Certificates; -using Fantasy.Async; -using Fantasy.Network.Interface; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable PossibleMultipleEnumeration -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Network.WebSocket; - -public class WebSocketServerNetwork : ANetwork -{ - private Random _random; - private HttpListener _httpListener; - private readonly Dictionary _connectionChannel = new Dictionary(); - - public void Initialize(NetworkTarget networkTarget, int port) - { - base.Initialize(NetworkType.Server, NetworkProtocolType.WebSocket, networkTarget); - - try - { - _random = new Random(); - _httpListener = new HttpListener(); - StartAcceptAsync(port).Coroutine(); - } - catch (HttpListenerException e) - { - if (e.ErrorCode == 5) - { - throw new Exception($"如果看下如下错误请尝试下面的办法:" + - $"1.用管理员运行CMD 输入命令: netsh http add urlacl url=http://+:8080/ user=Everyone。" + - $"2.用管理员身份运行编辑器或者程序。", e); - } - - Log.Error(e); - } - catch (Exception e) - { - Log.Error(e); - } - } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - if (_httpListener != null) - { - _httpListener.Close(); - _httpListener = null; - } - - foreach (var channel in _connectionChannel.Values.ToArray()) - { - channel.Dispose(); - } - - _connectionChannel.Clear(); - base.Dispose(); - } - - private static bool IsValidWebSocketRequest(HttpListenerRequest request) - { - // 检查必需的WebSocket握手头部 - var connectionHeader = request.Headers["Connection"]; - var upgradeHeader = request.Headers["Upgrade"]; - - if (string.IsNullOrEmpty(connectionHeader) || string.IsNullOrEmpty(upgradeHeader)) - { - return false; - } - - // Connection头部应该包含"Upgrade" (不区分大小写) - if (!connectionHeader.ToLower().Contains("upgrade")) - { - return false; - } - - // Upgrade头部应该是"websocket" (不区分大小写) - if (!upgradeHeader.ToLower().Contains("websocket")) - { - return false; - } - - // 检查WebSocket版本 (可选但推荐) - var versionHeader = request.Headers["Sec-WebSocket-Version"]; - if (!string.IsNullOrEmpty(versionHeader) && versionHeader != "13") - { - return false; - } - - return true; - } - - private async FTask StartAcceptAsync(int port) - { - var listenUrl = $"http://+:{port}/"; - _httpListener.Prefixes.Add(listenUrl); - _httpListener.Start(); - Log.Info($"SceneConfigId = {Scene.SceneConfigId} WebSocketServer Listen {listenUrl}"); - while (!IsDisposed) - { - try - { - var httpListenerContext = await _httpListener.GetContextAsync(); - // 验证WebSocket握手请求头部 - if (!IsValidWebSocketRequest(httpListenerContext.Request)) - { - httpListenerContext.Response.StatusCode = 400; - httpListenerContext.Response.StatusDescription = "Bad Request - Invalid WebSocket headers"; - httpListenerContext.Response.Close(); - continue; - } - var webSocketContext = await httpListenerContext.AcceptWebSocketAsync(null); - var channelId = 0xC0000000 | (uint) _random.Next(); - while (_connectionChannel.ContainsKey(channelId)) - { - channelId = 0xC0000000 | (uint) _random.Next(); - } - - var webSocketServerNetworkChannel = new WebSocketServerNetworkChannel(this, channelId, webSocketContext, httpListenerContext.Request.RemoteEndPoint); - _connectionChannel.Add(channelId, webSocketServerNetworkChannel); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void RemoveChannel(uint channelId) - { - if (IsDisposed || !_connectionChannel.Remove(channelId, out var channel)) - { - return; - } - - if (channel.IsDisposed) - { - return; - } - - channel.Dispose(); - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetworkChannel.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetworkChannel.cs deleted file mode 100644 index 040745f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetworkChannel.cs +++ /dev/null @@ -1,271 +0,0 @@ -#if FANTASY_NET -using System.Buffers; -using System.IO.Pipelines; -using System.Net; -using System.Net.Sockets; -using System.Net.WebSockets; -using Fantasy.Async; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.WebSocket; - -public sealed class WebSocketServerNetworkChannel : ANetworkServerChannel -{ - private bool _isSending; - private bool _isInnerDispose; - private readonly Pipe _pipe = new Pipe(); - private readonly System.Net.WebSockets.WebSocket _webSocket; - private readonly WebSocketServerNetwork _network; - private readonly ReadOnlyMemoryPacketParser _packetParser; - private readonly Queue _sendBuffers = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - public WebSocketServerNetworkChannel(ANetwork network, uint id, HttpListenerWebSocketContext httpListenerWebSocketContext, IPEndPoint remoteEndPoint) : base(network, id, remoteEndPoint) - { - _network = (WebSocketServerNetwork)network; - _webSocket = httpListenerWebSocketContext.WebSocket; - _packetParser = PacketParserFactory.CreateServerReadOnlyMemoryPacket(network); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - _isInnerDispose = true; - - if (_webSocket.State == WebSocketState.Open || _webSocket.State == WebSocketState.CloseReceived) - { - try - { - _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Normal Closure", - CancellationToken.None).GetAwaiter().GetResult(); - } - catch (Exception) - { - // 关闭过程中的异常可以忽略 - } - } - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - _sendBuffers.Clear(); - _network.RemoveChannel(Id); - _webSocket.Dispose(); - _isSending = false; - base.Dispose(); - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); - // 这里接收的数据不一定是一个完整的包。如果大于8192就会分成多个包。 - var receiveResult = await _webSocket.ReceiveAsync(memory, _cancellationTokenSource.Token); - // 客户端发送了关闭帧,服务器需要响应关闭帧 - if (receiveResult.MessageType == WebSocketMessageType.Close) - { - if (_webSocket.State == WebSocketState.CloseReceived) - { - await _webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Response Closure", - CancellationToken.None); - } - Dispose(); - return; - } - - var count = receiveResult.Count; - - if (count > 0) - { - await PipeWriterFlushAsync(count); - } - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (WebSocketException) - { - // Log.Error($"WebSocket error: {wse.Message}"); - Dispose(); - break; - } - catch (Exception e) - { - Log.Error(e); - } - } - - await _pipe.Writer.CompleteAsync(); - - // 接收循环结束,自动释放连接 - Dispose(); - } - - private async FTask PipeWriterFlushAsync(int count) - { - _pipe.Writer.Advance(count); - await _pipe.Writer.FlushAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var message)) - { - ReceiveData(ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private bool TryReadMessage(ref ReadOnlySequence buffer, out ReadOnlyMemory message) - { - if (buffer.Length == 0) - { - message = default; - return false; - } - - message = buffer.First; - - if (message.Length == 0) - { - message = default; - return false; - } - - buffer = buffer.Slice(message.Length); - return true; - } - - private void ReceiveData(ref ReadOnlyMemory buffer) - { - try - { - while (_packetParser.UnPack(ref buffer, out var packInfo)) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - Session.Receive(packInfo); - } - } - catch (ScanException e) - { - Log.Warning($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - catch (Exception e) - { - Log.Error($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - _sendBuffers.Enqueue(_packetParser.Pack(ref rpcId, ref routeId, memoryStream, message)); - - if (!_isSending) - { - Send().Coroutine(); - } - } - - private async FTask Send() - { - if (_isSending || IsDisposed) - { - return; - } - - _isSending = true; - - while (_isSending) - { - if (!_sendBuffers.TryDequeue(out var memoryStream)) - { - _isSending = false; - return; - } - - await _webSocket.SendAsync(new ArraySegment(memoryStream.GetBuffer(), 0, (int)memoryStream.Position), WebSocketMessageType.Binary, true, _cancellationTokenSource.Token); - - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - _network.MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - } - - #endregion -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/RoamingComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/RoamingComponent.cs deleted file mode 100644 index a42d582..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/RoamingComponent.cs +++ /dev/null @@ -1,254 +0,0 @@ -#if FANTASY_NET -using System.Runtime.CompilerServices; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Timer; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Network.Roaming; - -/// -/// 漫游组件,用来管理当然Scene下的所有漫游消息。 -/// 大多数是在Gate这样的转发服务器上创建的。 -/// -public sealed class RoamingComponent : Entity -{ - private TimerSchedulerNet _timerSchedulerNet; - private readonly Dictionary _sessionRoamingComponents = new(); - private readonly Dictionary _delayRemoveTaskId = new(); - - internal RoamingComponent Initialize() - { - _timerSchedulerNet = Scene.TimerComponent.Net; - return this; - } - - /// - /// 销毁方法。 - /// - public override void Dispose() - { - DisposeAsync().Coroutine(); - } - - private async FTask DisposeAsync() - { - foreach (var (_,taskId) in _delayRemoveTaskId) - { - _timerSchedulerNet.Remove(taskId); - } - - _delayRemoveTaskId.Clear(); - - foreach (var (_, sessionRoamingComponent) in _sessionRoamingComponents) - { - await sessionRoamingComponent.UnLink(); - } - - _sessionRoamingComponents.Clear(); - _timerSchedulerNet = null; - base.Dispose(); - } - - /// - /// 给Session会话增加漫游功能 - /// 如果指定的roamingId已经存在漫游,会把这个漫游功能和当前Session会话关联起来。 - /// - /// - /// 自定义roamingId,这个Id在漫游中并没有实际作用,但用户可以用这个id来进行标记。。 - /// 是否在Session断开的时候自动断开漫游功能。 - /// 如果开启了自定断开漫游功能需要设置一个延迟多久执行断开。 - /// 创建成功会返回SessionRoamingComponent组件,这个组件提供漫游的所有功能。 - public SessionRoamingComponent Create(Session session, long roamingId, bool isAutoDispose, int delayRemove) - { - if (session.SessionRoamingComponent != null) - { - if (session.SessionRoamingComponent.Id != roamingId) - { - Log.Error("The current session has created a SessionRoamingComponent."); - return null; - } - } - else - { - if (!_sessionRoamingComponents.TryGetValue(roamingId, out var sessionRoamingComponent)) - { - sessionRoamingComponent = Entity.Create(Scene, roamingId, true, true); - sessionRoamingComponent.Initialize(session); - _sessionRoamingComponents.Add(roamingId, sessionRoamingComponent); - } - } - - if (isAutoDispose) - { - session.AddComponent(roamingId).DelayRemove = delayRemove; - } - - return session.SessionRoamingComponent; - } - - /// - /// 获取当前Session会话的漫游组件 - /// - /// - /// - public SessionRoamingComponent Get(Session session) - { - var sessionRoamingFlgComponent = session.GetComponent(); - - if (sessionRoamingFlgComponent != null) - { - if (_sessionRoamingComponents.TryGetValue(sessionRoamingFlgComponent.Id, out var sessionRoamingComponent)) - { - return sessionRoamingComponent; - } - - Log.Error($"There is no SessionRoamingComponent with roamingId: {sessionRoamingFlgComponent.Id}."); - } - else - { - Log.Error("The current session has not created a roaming session yet, so you need to create one first."); - } - - return null; - } - - /// - /// 获取当前Session会话的漫游组件 - /// - /// - /// - /// - public bool TryGet(Session session, out SessionRoamingComponent sessionRoamingComponent) - { - var sessionRoamingFlgComponent = session.GetComponent(); - - if (sessionRoamingFlgComponent != null) - { - return _sessionRoamingComponents.TryGetValue(sessionRoamingFlgComponent.Id, out sessionRoamingComponent); - } - - sessionRoamingComponent = null; - return false; - } - - /// - /// 移除一个漫游 - /// - /// - /// 要移除的RoamingType,默认不设置是移除所有漫游。 - /// 当设置了延迟移除时间后,会在设置的时间后再进行移除。 - public async FTask Remove(long roamingId, int roamingType, int delayRemove = 0) - { - if (_delayRemoveTaskId.Remove(roamingId, out var taskId)) - { - _timerSchedulerNet.Remove(taskId); - } - - if (delayRemove <= 0) - { - await InnerRemove(roamingId, roamingType); - return; - } - - taskId = _timerSchedulerNet.OnceTimer(delayRemove, () => - { InnerRemove(roamingId, roamingType).Coroutine(); }); - _delayRemoveTaskId.Add(roamingId, taskId); - } - - private async FTask InnerRemove(long roamingId, int roamingType) - { - if (!_sessionRoamingComponents.Remove(roamingId, out var sessionRoamingComponent)) - { - return; - } - - await sessionRoamingComponent.UnLink(roamingType); - sessionRoamingComponent.Dispose(); - _delayRemoveTaskId.Remove(roamingId); - } -} - -/// -/// 漫游Roaming帮助类 -/// -public static class RoamingHelper -{ - /// - /// 给Session会话增加漫游功能 - /// 如果指定的roamingId已经存在漫游,会把这个漫游功能和当前Session会话关联起来。 - /// - /// - /// 自定义roamingId,这个Id在漫游中并没有实际作用,但用户可以用这个id来进行标记。 - /// 是否在Session断开的时候自动断开漫游功能。 - /// 如果开启了自定断开漫游功能需要设置一个延迟多久执行断开。 - /// 创建成功会返回SessionRoamingComponent组件,这个组件提供漫游的所有功能。 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SessionRoamingComponent CreateRoaming(this Session session, long roamingId, bool isAutoDispose = true, int delayRemove = 1000 * 60 * 3) - { - return session.Scene.RoamingComponent.Create(session, roamingId, isAutoDispose, delayRemove); - } - - /// - /// 获取当前Session会话的漫游组件 - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SessionRoamingComponent GetRoaming(this Session session) - { - return session.Scene.RoamingComponent.Get(session); - } - - /// - /// 获取当前Session会话的漫游组件 - /// - /// - /// - /// 如果返回为false表示没有获取到漫游组件。 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryGetRoaming(this Session session, out SessionRoamingComponent sessionRoamingComponent) - { - return session.Scene.RoamingComponent.TryGet(session, out sessionRoamingComponent); - } - - /// - /// 移除一个漫游 - /// - /// - /// 要移除的RoamingType,默认不设置是移除所有漫游。 - /// 当设置了延迟移除时间后,会在设置的时间后再进行移除。 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static async FTask RemoveRoaming(this Session session, int roamingType = 0, int delayRemove = 0) - { - if (session.SessionRoamingComponent == null || session.SessionRoamingComponent.Id == 0) - { - return; - } - - await session.Scene.RoamingComponent.Remove(session.SessionRoamingComponent.Id, roamingType, delayRemove); - } - - /// - /// 移除一个漫游 - /// - /// - /// - /// 要移除的RoamingType,默认不设置是移除所有漫游。 - /// 当设置了延迟移除时间后,会在设置的时间后再进行移除。 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static async FTask RemoveRoaming(Scene scene, long roamingId, int roamingType = 0, int delayRemove = 0) - { - if (roamingId == 0) - { - return; - } - - await scene.RoamingComponent.Remove(roamingId, roamingType, delayRemove); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/SessionRoamingComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/SessionRoamingComponent.cs deleted file mode 100644 index 6834834..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/SessionRoamingComponent.cs +++ /dev/null @@ -1,390 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Platform.Net; -using Fantasy.Scheduler; -using Fantasy.Timer; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -namespace Fantasy.Network.Roaming; - -internal sealed class SessionRoamingComponentDestroySystem : DestroySystem -{ - protected override void Destroy(SessionRoamingComponent self) - { - self.RoamingLock.Dispose(); - self.RoamingMessageLock.Dispose(); - - self.RoamingLock = null; - self.RoamingMessageLock = null; - self.TimerComponent = null; - self.NetworkMessagingComponent = null; - self.MessageDispatcherComponent = null; - } -} - -/// -/// Session的漫游组件。 -/// 用于关联对应的Session的功能。 -/// 但这个组件并不会挂载到这个Session下。 -/// -public sealed class SessionRoamingComponent : Entity -{ - internal CoroutineLock RoamingLock; - internal CoroutineLock RoamingMessageLock; - internal TimerComponent TimerComponent; - internal NetworkMessagingComponent NetworkMessagingComponent; - internal MessageDispatcherComponent MessageDispatcherComponent; - /// - /// 漫游的列表。 - /// - private readonly Dictionary _roaming = new Dictionary(); - - internal void Initialize(Session session) - { - session.SessionRoamingComponent = this; - - var scene = session.Scene; - TimerComponent = scene.TimerComponent; - NetworkMessagingComponent = scene.NetworkMessagingComponent; - MessageDispatcherComponent = scene.MessageDispatcherComponent; - RoamingLock = scene.CoroutineLockComponent.Create(this.GetType().TypeHandle.Value.ToInt64()); - RoamingMessageLock = scene.CoroutineLockComponent.Create(this.GetType().TypeHandle.Value.ToInt64()); - } - - #region Get - - /// - /// 尝试获取一个漫游。 - /// - /// - /// - /// - public bool TryGetRoaming(int roamingType, out Roaming roaming) - { - return _roaming.TryGetValue(roamingType, out roaming); - } - - #endregion - - #region Link - - /// - /// 建立漫游关系。 - /// - /// 要建立漫游协议的目标Scene的SceneConfig。 - /// 需要转发的Session - /// 要创建的漫游协议类型。 - /// 如果建立完成会返回为0,其余不为0的都是发生错误了。可以通过InnerErrorCode.cs来查看错误。 - public async FTask Link(Session session, SceneConfig targetSceneConfig, int roamingTyp) - { - return await Link(targetSceneConfig.RouteId, session.RuntimeId, roamingTyp); - } - - /// - /// 建立漫游关系。 - /// - /// 要建立漫游协议的目标Scene的RouteId。 - /// 需要转发的Session的RouteId。 - /// 要创建的漫游协议类型。 - /// 如果建立完成会返回为0,其余不为0的都是发生错误了。可以通过InnerErrorCode.cs来查看错误。 - public async FTask Link(long targetSceneRouteId, long forwardSessionRouteId, int roamingType) - { - if (_roaming.ContainsKey(roamingType)) - { - return InnerErrorCode.ErrLinkRoamingAlreadyExists; - } - - var response = (I_LinkRoamingResponse)await Scene.NetworkMessagingComponent.CallInnerRoute(targetSceneRouteId, - new I_LinkRoamingRequest() - { - RoamingId = Id, - RoamingType = roamingType, - ForwardSessionRouteId = forwardSessionRouteId, - SceneRouteId = Scene.RuntimeId - }); - - if (response.ErrorCode != 0) - { - return response.ErrorCode; - } - - var roaming = Entity.Create(Scene, true, true); - roaming.TerminusId = response.TerminusId; - roaming.TargetSceneRouteId = targetSceneRouteId; - roaming.ForwardSessionRouteId = forwardSessionRouteId; - roaming.SessionRoamingComponent = this; - roaming.RoamingType = roamingType; - roaming.RoamingLock = RoamingLock; - _roaming.Add(roamingType, roaming); - return 0; - } - - #endregion - - #region UnLink - - /// - /// 断开当前的所有漫游关系。 - /// 要移除的RoamingType,默认不设置是移除所有漫游。 - /// - public async FTask UnLink(int removeRoamingType = 0) - { - switch (removeRoamingType) - { - case 0: - { - foreach (var (roamingType,roaming) in _roaming) - { - try - { - var errorCode = await roaming.Disconnect(); - - if (errorCode != 0) - { - Log.Warning($"roaming roamingId:{Id} roamingType:{roamingType} disconnect errorCode:{errorCode}"); - } - } - finally - { - roaming.Dispose(); - } - } - - _roaming.Clear(); - return; - } - default: - { - if (!_roaming.Remove(removeRoamingType, out var roaming)) - { - return; - } - - var errorCode = await roaming.Disconnect(); - - if (errorCode != 0) - { - Log.Warning($"roaming roamingId:{Id} roamingType:{removeRoamingType} disconnect errorCode:{errorCode}"); - } - - roaming.Dispose(); - return; - } - } - } - - #endregion - - #region OuterMessage - - /// - /// 发送一个消息给漫游终 - /// - /// - public void Send(IRoamingMessage message) - { - Call(message.RouteType, message).Coroutine(); - } - - /// - /// 发送一个消息给漫游终端 - /// - /// - /// - public void Send(int roamingType, IRouteMessage message) - { - Call(roamingType, message).Coroutine(); - } - - /// - /// 发送一个RPC消息给漫游终端 - /// - /// - /// - public async FTask Call(IRoamingMessage message) - { - return await Call(message.RouteType, message); - } - - /// - /// 发送一个RPC消息给漫游终端 - /// - /// - /// - /// - public async FTask Call(int roamingType, IRouteMessage message) - { - if (!_roaming.TryGetValue(roamingType, out var roaming)) - { - return MessageDispatcherComponent.CreateResponse(message.GetType(), InnerErrorCode.ErrNotFoundRoaming); - } - - var failCount = 0; - var runtimeId = RuntimeId; - var routeId = roaming.TerminusId; - var requestType = message.GetType(); - - IResponse iRouteResponse = null; - - using (await RoamingMessageLock.Wait(roaming.RoamingType, "RoamingComponent Call MemoryStream")) - { - while (!IsDisposed) - { - if (routeId == 0) - { - routeId = await roaming.GetTerminusId(); - } - - if (routeId == 0) - { - return MessageDispatcherComponent.CreateResponse(requestType, InnerErrorCode.ErrNotFoundRoaming); - } - - iRouteResponse = await NetworkMessagingComponent.CallInnerRoute(routeId, message); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRoamingTimeout; - } - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrRouteTimeout: - case InnerErrorCode.ErrRoamingTimeout: - { - return iRouteResponse; - } - case InnerErrorCode.ErrNotFoundRoute: - case InnerErrorCode.ErrNotFoundRoaming: - { - if (++failCount > 20) - { - Log.Error($"RoamingComponent.Call failCount > 20 route send message fail, LinkRoamingId: {routeId}"); - return iRouteResponse; - } - - await TimerComponent.Net.WaitAsync(100); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrNotFoundRoaming; - } - - routeId = 0; - continue; - } - default: - { - return iRouteResponse; // 对于其他情况,直接返回响应,无需额外处理 - } - } - } - } - - return iRouteResponse; - } - - #endregion - - #region InnerMessage - - internal async FTask Send(int roamingType, Type requestType, APackInfo packInfo) - { - await Call(roamingType, requestType, packInfo); - } - - internal async FTask Call(int roamingType, Type requestType, APackInfo packInfo) - { - if (IsDisposed) - { - return MessageDispatcherComponent.CreateResponse(requestType, InnerErrorCode.ErrNotFoundRoaming); - } - - packInfo.IsDisposed = true; - - if (!_roaming.TryGetValue(roamingType, out var roaming)) - { - return MessageDispatcherComponent.CreateResponse(requestType, InnerErrorCode.ErrNotFoundRoaming); - } - - var failCount = 0; - var runtimeId = RuntimeId; - var routeId = roaming.TerminusId; - IResponse iRouteResponse = null; - - try - { - using (await RoamingMessageLock.Wait(roamingType, "RoamingComponent Call MemoryStream")) - { - while (!IsDisposed) - { - if (routeId == 0) - { - routeId = await roaming.GetTerminusId(); - } - - if (routeId == 0) - { - return MessageDispatcherComponent.CreateResponse(requestType, InnerErrorCode.ErrNotFoundRoaming); - } - - iRouteResponse = await NetworkMessagingComponent.CallInnerRoute(routeId, requestType, packInfo); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRoamingTimeout; - } - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrRouteTimeout: - case InnerErrorCode.ErrRoamingTimeout: - { - return iRouteResponse; - } - case InnerErrorCode.ErrNotFoundRoute: - case InnerErrorCode.ErrNotFoundRoaming: - { - if (++failCount > 20) - { - Log.Error($"RoamingComponent.Call failCount > 20 route send message fail, LinkRoamingId: {routeId}"); - return iRouteResponse; - } - - await TimerComponent.Net.WaitAsync(100); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrNotFoundRoaming; - } - routeId = 0; - continue; - } - default: - { - return iRouteResponse; // 对于其他情况,直接返回响应,无需额外处理 - } - } - } - } - } - finally - { - packInfo.Dispose(); - } - - return iRouteResponse; - } - - #endregion -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/SessionRoamingFlgComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/SessionRoamingFlgComponent.cs deleted file mode 100644 index 23f4c33..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/SessionRoamingFlgComponent.cs +++ /dev/null @@ -1,23 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.Entitas; -namespace Fantasy.Network.Roaming; - -internal sealed class SessionRoamingFlgComponent : Entity -{ - public int DelayRemove; - - public override void Dispose() - { - DisposeAsync().Coroutine(); - } - - private async FTask DisposeAsync() - { - var roamingId = Id; - await Scene.RoamingComponent.Remove(roamingId, 0, DelayRemove); - DelayRemove = 0; - base.Dispose(); - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/TerminusComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/TerminusComponent.cs deleted file mode 100644 index 0185261..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Component/TerminusComponent.cs +++ /dev/null @@ -1,138 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.DataStructure.Dictionary; -using Fantasy.Entitas; -using Fantasy.Network; -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Network.Roaming; - -/// -/// 当Terminus创建完成后发送的事件参数 -/// -public struct OnCreateTerminus -{ - /// - /// 获取与事件关联的场景实体。 - /// - public readonly Scene Scene; - /// - /// 获取与事件关联的Terminus。 - /// - public readonly Terminus Terminus; - /// - /// 初始化一个新的 OnCreateTerminus 实例。 - /// - /// - /// - public OnCreateTerminus(Scene scene, Terminus terminus) - { - Scene = scene; - Terminus = terminus; - } -} - -/// -/// 漫游终端管理组件。 -/// 这个组件不需要手动挂载,会在Scene启动的时候自动挂载这个组件。 -/// -public sealed class TerminusComponent : Entity -{ - /// - /// 漫游终端的实体集合。 - /// - private readonly Dictionary _terminals = new(); - - /// - /// Dispose - /// - public override void Dispose() - { - foreach (var (_, terminus) in _terminals) - { - terminus.Dispose(); - } - - _terminals.Clear(); - base.Dispose(); - } - - /// - /// 创建一个新的漫游终端。 - /// - /// - /// - /// - /// - /// - public async FTask<(uint, Terminus)> Create(long roamingId, int roamingType, long forwardSessionRouteId, long forwardSceneRouteId) - { - if (_terminals.ContainsKey(roamingId)) - { - return (InnerErrorCode.ErrAddRoamingTerminalAlreadyExists, null); - } - - var terminus = roamingId == 0 - ? Entity.Create(Scene, false, true) - : Entity.Create(Scene, roamingId, false, true); - terminus.RoamingType = roamingType; - terminus.TerminusId = terminus.RuntimeId; - terminus.ForwardSceneRouteId = forwardSceneRouteId; - terminus.ForwardSessionRouteId = forwardSessionRouteId; - terminus.RoamingMessageLock = Scene.CoroutineLockComponent.Create(terminus.Type.TypeHandle.Value.ToInt64()); - await Scene.EventComponent.PublishAsync(new OnCreateTerminus(Scene, terminus)); - _terminals.Add(terminus.Id, terminus); - return (0U, terminus); - } - - /// - /// 添加一个漫游终端。 - /// - /// - public void AddTerminus(Terminus terminus) - { - _terminals.Add(terminus.Id, terminus); - } - - /// - /// 根据roamingId获取一个漫游终端。 - /// - /// - /// - /// - public bool TryGetTerminus(long roamingId, out Terminus terminus) - { - return _terminals.TryGetValue(roamingId, out terminus); - } - - /// - /// 根据roamingId获取一个漫游终端。 - /// - /// - /// - public Terminus GetTerminus(long roamingId) - { - return _terminals[roamingId]; - } - - /// - /// 根据roamingId移除一个漫游终端。 - /// - /// - /// - public void RemoveTerminus(long roamingId, bool isDispose = true) - { - if (!_terminals.Remove(roamingId, out var terminus)) - { - return; - } - - if (isDispose) - { - terminus.Dispose(); - } - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Entity/Roaming.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Entity/Roaming.cs deleted file mode 100644 index 33a5355..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Entity/Roaming.cs +++ /dev/null @@ -1,132 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.InnerMessage; - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -namespace Fantasy.Network.Roaming; - -/// -/// 漫游实体 -/// -public sealed class Roaming : Entity -{ - /// - /// 连接到漫游TerminusId。 - /// 也可以理解为目标实体的RouteId。 - /// - internal long TerminusId; - /// - /// 漫游目标Scene的RouteId。 - /// - public long TargetSceneRouteId { get; internal set; } - /// - /// 漫游转发Session的RouteId。 - /// - public long ForwardSessionRouteId { get; internal set; } - /// - /// 当前漫游类型。 - /// - public int RoamingType { get; internal set; } - /// - /// 协程锁。 - /// - internal CoroutineLock RoamingLock; - /// - /// 当前正在执行的协程锁。 - /// - private WaitCoroutineLock? _waitCoroutineLock; - /// - /// 关联Session的漫游组件。 - /// - internal SessionRoamingComponent SessionRoamingComponent; - /// - /// 获得当前漫游对应终端的TerminusId。 - /// - /// - internal async FTask GetTerminusId() - { - using (await RoamingLock.Wait(RoamingType,"Roaming.cs GetTerminusId")) - { - return TerminusId; - } - } - /// - /// 设置当前漫游对应的终端的TerminusId。 - /// - /// - internal async FTask SetTerminusId(long terminusId) - { - using (await RoamingLock.Wait(RoamingType,"Roaming.cs SetTerminusId")) - { - TerminusId = terminusId; - } - } - /// - /// 锁定TerminusId。 - /// - internal async FTask LockTerminusId() - { - _waitCoroutineLock = await RoamingLock.Wait(RoamingType,"Roaming.cs LockTerminusId"); - } - - /// - /// 解锁TerminusId。 - /// - /// - /// - internal void UnLockTerminusId(long terminusId, long targetSceneRouteId) - { - if (_waitCoroutineLock == null) - { - Log.Error("terminusId unlock waitCoroutineLock is null"); - return; - } - - TerminusId = terminusId; - TargetSceneRouteId = targetSceneRouteId; - _waitCoroutineLock.Dispose(); - _waitCoroutineLock = null; - } - - /// - /// 断开当前漫游的连接。 - /// - /// - public async FTask Disconnect() - { - var response = - await Scene.NetworkMessagingComponent.CallInnerRoute(TargetSceneRouteId, new I_UnLinkRoamingRequest() - { - RoamingId = SessionRoamingComponent.Id - }); - return response.ErrorCode; - } - /// - /// 销毁方法 - /// - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - if (_waitCoroutineLock != null) - { - _waitCoroutineLock.Dispose(); - _waitCoroutineLock = null; - } - - TerminusId = 0; - TargetSceneRouteId = 0; - ForwardSessionRouteId = 0; - - RoamingLock = null; - SessionRoamingComponent = null; - base.Dispose(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Entity/Terminus.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Entity/Terminus.cs deleted file mode 100644 index 8d4448b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Entity/Terminus.cs +++ /dev/null @@ -1,338 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Scheduler; -using MongoDB.Bson.Serialization.Attributes; -// ReSharper disable UnassignedField.Global -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. -#pragma warning disable CS8603 // Possible null reference return. -namespace Fantasy.Network.Roaming; - -/// -/// 漫游终端实体 -/// -public sealed class Terminus : Entity -{ - /// - /// 当前漫游终端的TerminusId。 - /// 可以通过 TerminusId 发送消息给这个漫游终端。 - /// 也可以理解为实体的RuntimeId。 - /// - internal long TerminusId; - /// - /// 当前漫游终端的类型。 - /// - [BsonElement("r")] - internal int RoamingType; - /// - /// 漫游转发Session所在的Scene的RouteId。 - /// - [BsonElement("s")] - internal long ForwardSceneRouteId; - /// - /// 漫游转发Session的RouteId。 - /// 不知道原理千万不要手动赋值这个。 - /// - [BsonElement("f")] - internal long ForwardSessionRouteId; - /// - /// 关联的玩家实体 - /// - [BsonElement("e")] - public Entity TerminusEntity; - /// - /// 漫游消息锁。 - /// - [BsonIgnore] - internal CoroutineLock RoamingMessageLock; - /// - /// 获得转发的SessionRouteId,可以通过这个Id来发送消息来自动转发到客户端。 - /// - public long SessionRouteId => ForwardSessionRouteId; - /// - /// 存放其他漫游终端的Id。 - /// 通过这个Id可以发送消息给它。 - /// - [BsonIgnore] - private readonly Dictionary _roamingTerminusId = new Dictionary(); - /// - /// 创建关联的终端实体。 - /// 创建完成后,接收消息都是由关联的终端实体来处理。 - /// 注意,当你销毁这个实体的时候,并不能直接销毁Terminus,会导致无法接收到漫游消息。 - /// - /// - /// - public T LinkTerminusEntity() where T : Entity, new() - { - if (TerminusEntity != null) - { - Log.Error($"TerminusEntity:{TerminusEntity.Type.FullName} Already exists!"); - return null; - } - - var t = Entity.Create(Scene, true, true); - TerminusEntity = t; - TerminusId = TerminusEntity.RuntimeId; - return t; - } - - /// - /// 关联的终端实体。 - /// 注意,当你销毁这个实体的时候,并不能直接销毁Terminus,会导致无法接收到漫游消息 - /// - /// - public void LinkTerminusEntity(Entity entity) - { - if (entity == null) - { - Log.Error("Entity cannot be empty"); - return; - } - - if (TerminusEntity != null) - { - Log.Error($"TerminusEntity:{TerminusEntity.Type.FullName} Already exists!"); - return; - } - - TerminusEntity = entity; - TerminusId = TerminusEntity.RuntimeId; - } - - #region Transfer - - /// - /// 传送漫游终端 - /// 传送完成后,漫游终端和关联的玩家实体都会被销毁。 - /// 所以如果有其他组件关联这个实体,要提前记录好Id,方便传送后清理。 - /// - /// - public async FTask StartTransfer(long targetSceneRouteId) - { - var currentSceneRouteId = Scene.SceneConfig.RouteId; - if (targetSceneRouteId == currentSceneRouteId) - { - Log.Warning($"Unable to teleport to your own scene targetSceneRouteId:{targetSceneRouteId} == currentSceneRouteId:{currentSceneRouteId}"); - return 0; - } - - try - { - // 传送目标服务器之前要先锁定,防止再传送过程中还有其他消息发送过来。 - var lockErrorCode = await Lock(); - if (lockErrorCode != 0) - { - return lockErrorCode; - } - // 开始执行传送请求。 - var response = (I_TransferTerminusResponse)await Scene.NetworkMessagingComponent.CallInnerRoute( - targetSceneRouteId, - new I_TransferTerminusRequest() - { - Terminus = this - }); - if (response.ErrorCode != 0) - { - // 如果传送出现异常,需要先解锁,不然会出现一直卡死的问题。 - await UnLock(); - return response.ErrorCode; - } - // 在当前Scene下移除漫游终端。 - Scene.TerminusComponent.RemoveTerminus(Id); - } - catch (Exception e) - { - Log.Error(e); - // 如果代码执行出现任何异常,要先去解锁,避免会出现卡死的问题。 - await UnLock(); - return InnerErrorCode.ErrTerminusStartTransfer; - } - - return 0; - } - - /// - /// 传送完成。 - /// 当传送完成后,需要清理漫游终端。 - /// - /// - public async FTask TransferComplete(Scene scene) - { - // 首先恢复漫游终端的序列化数据。并且注册到框架中。 - Deserialize(scene); - TerminusId = RuntimeId; - if (TerminusEntity != null) - { - TerminusEntity.Deserialize(scene); - TerminusId = TerminusEntity.RuntimeId; - } - // 然后要解锁下漫游 - return await UnLock(); - } - - /// - /// 锁定漫游当执行锁定了后,所有消息都会被暂时放入队列中不会发送。 - /// 必须要解锁后才能继续发送消息。 - /// - /// - public async FTask Lock() - { - var response = await Scene.NetworkMessagingComponent.CallInnerRoute(ForwardSceneRouteId, - new I_LockTerminusIdRequest() - { - SessionRuntimeId = ForwardSessionRouteId, - RoamingType = RoamingType - }); - return response.ErrorCode; - } - - /// - /// 锁定漫游 - /// - /// - public async FTask UnLock() - { - var response = await Scene.NetworkMessagingComponent.CallInnerRoute(ForwardSceneRouteId, - new I_UnLockTerminusIdRequest() - { - SessionRuntimeId = ForwardSessionRouteId, - RoamingType = RoamingType, - TerminusId = TerminusId, - TargetSceneRouteId = Scene.RouteId - }); - return response.ErrorCode; - } - - #endregion - - #region Message - - private async FTask GetTerminusId(int roamingType) - { - if (IsDisposed) - { - return 0; - } - - var response = (I_GetTerminusIdResponse)await Scene.NetworkMessagingComponent.CallInnerRoute( - ForwardSceneRouteId, - new I_GetTerminusIdRequest() - { - SessionRuntimeId = ForwardSessionRouteId, - RoamingType = roamingType - }); - return response.TerminusId; - } - - /// - /// 发送一个消息给客户端 - /// - /// - public void Send(IRouteMessage message) - { - Scene.NetworkMessagingComponent.SendInnerRoute(ForwardSessionRouteId, message); - } - /// - /// 发送一个漫游消息 - /// - /// - /// - public void Send(int roamingType, IRoamingMessage message) - { - Call(roamingType, message).Coroutine(); - } - - /// - /// 发送一个漫游RPC消息。 - /// - /// - /// - /// - public async FTask Call(int roamingType, IRoamingMessage request) - { - if (IsDisposed) - { - return Scene.MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoaming); - } - - if (roamingType == RoamingType) - { - Log.Warning($"Does not support sending messages to the same scene as roamingType currentRoamingType:{RoamingType} roamingType:{roamingType}"); - return Scene.MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoaming); - } - - var failCount = 0; - var runtimeId = RuntimeId; - IResponse iRouteResponse = null; - _roamingTerminusId.TryGetValue(roamingType, out var routeId); - - using (await RoamingMessageLock.Wait(roamingType, "Terminus Call request")) - { - while (!IsDisposed) - { - if (routeId == 0) - { - routeId = await GetTerminusId(roamingType); - - if (routeId != 0) - { - _roamingTerminusId[roamingType] = routeId; - } - else - { - return Scene.MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoaming); - } - } - - iRouteResponse = await Scene.NetworkMessagingComponent.CallInnerRoute(routeId, request); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRoamingTimeout; - } - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrRouteTimeout: - case InnerErrorCode.ErrRoamingTimeout: - { - return iRouteResponse; - } - case InnerErrorCode.ErrNotFoundRoute: - case InnerErrorCode.ErrNotFoundRoaming: - { - if (++failCount > 20) - { - Log.Error($"Terminus.Call failCount > 20 route send message fail, TerminusId: {routeId}"); - return iRouteResponse; - } - - await Scene.TimerComponent.Net.WaitAsync(100); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrNotFoundRoaming; - } - - routeId = 0; - continue; - } - default: - { - return iRouteResponse; // 对于其他情况,直接返回响应,无需额外处理 - } - } - } - } - - return iRouteResponse; - } - - #endregion -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_GetTerminusIdRequestHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_GetTerminusIdRequestHandler.cs deleted file mode 100644 index 90f7ab9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_GetTerminusIdRequestHandler.cs +++ /dev/null @@ -1,32 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Network.Roaming; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -namespace Fantasy.Roaming.Handler; - -internal sealed class I_GetTerminusIdRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_GetTerminusIdRequest request, I_GetTerminusIdResponse response, Action reply) - { - if (!scene.TryGetEntity(request.SessionRuntimeId, out var sessionEntity)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundSession; - return; - } - - var session = (Session)sessionEntity; - - if (!scene.RoamingComponent.TryGet(session, out var sessionRoamingComponent) || !sessionRoamingComponent.TryGetRoaming(request.RoamingType, out var sessionRoaming)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundRoamingType; - return; - } - - response.TerminusId = await sessionRoaming.GetTerminusId(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_LinkRoamingRequestHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_LinkRoamingRequestHandler.cs deleted file mode 100644 index 6efb58c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_LinkRoamingRequestHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Roaming.Handler; - -public sealed class I_LinkRoamingRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_LinkRoamingRequest request, I_LinkRoamingResponse response, Action reply) - { - var (errorCode, roamingTerminal) = await scene.TerminusComponent.Create( - request.RoamingId, request.RoamingType, - request.ForwardSessionRouteId, request.SceneRouteId); - - if (errorCode != 0) - { - response.ErrorCode = errorCode; - return; - } - - response.TerminusId = roamingTerminal.TerminusId; - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_LockTerminusIdRequestHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_LockTerminusIdRequestHandler.cs deleted file mode 100644 index c530a1e..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_LockTerminusIdRequestHandler.cs +++ /dev/null @@ -1,35 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Network.Interface; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Roaming.Handler; - -/// -/// 内部网络漫游锁定的请求处理。 -/// -internal sealed class I_LockTerminusIdRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_LockTerminusIdRequest request, I_LockTerminusIdResponse response, Action reply) - { - if (!scene.TryGetEntity(request.SessionRuntimeId, out var sessionEntity)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundSession; - return; - } - - var session = (Session)sessionEntity; - - if (!scene.RoamingComponent.TryGet(session, out var sessionRoamingComponent) || !sessionRoamingComponent.TryGetRoaming(request.RoamingType, out var sessionRoaming)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundRoamingType; - return; - } - - await sessionRoaming.LockTerminusId(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_TransferTerminusRequestHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_TransferTerminusRequestHandler.cs deleted file mode 100644 index 162171f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_TransferTerminusRequestHandler.cs +++ /dev/null @@ -1,22 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Roaming.Handler; - -/// -/// 传送漫游Terminus的请求处理 -/// -internal sealed class I_TransferTerminusRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_TransferTerminusRequest request, I_TransferTerminusResponse response, Action reply) - { - // 添加Terminus到当前Scene下。 - scene.TerminusComponent.AddTerminus(request.Terminus); - // 执行Terminus的传送完成逻辑。 - await request.Terminus.TransferComplete(scene); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_UnLinkRoamingRequestHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_UnLinkRoamingRequestHandler.cs deleted file mode 100644 index 5849b11..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_UnLinkRoamingRequestHandler.cs +++ /dev/null @@ -1,16 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -namespace Fantasy.Roaming.Handler; - -internal sealed class I_UnLinkRoamingRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_UnLinkRoamingRequest request, I_UnLinkRoamingResponse response, Action reply) - { - scene.TerminusComponent.RemoveTerminus(request.RoamingId, request.DisposeRoaming); - await FTask.CompletedTask; - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_UnLockTerminusIdRequestHandler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_UnLockTerminusIdRequestHandler.cs deleted file mode 100644 index 8a04079..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Roaming/Handler/I_UnLockTerminusIdRequestHandler.cs +++ /dev/null @@ -1,36 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Network.Interface; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Roaming.Handler; - -/// -/// 内部网络漫游解锁的请求处理。 -/// -internal sealed class I_UnLockTerminusIdRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_UnLockTerminusIdRequest request, I_UnLockTerminusIdResponse response, Action reply) - { - if (!scene.TryGetEntity(request.SessionRuntimeId, out var sessionEntity)) - { - response.ErrorCode = InnerErrorCode.ErrUnLockTerminusIdNotFoundSession; - return; - } - - var session = (Session)sessionEntity; - - if (!scene.RoamingComponent.TryGet(session, out var sessionRoamingComponent) || !sessionRoamingComponent.TryGetRoaming(request.RoamingType, out var sessionRoaming)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundRoamingType; - return; - } - - sessionRoaming.UnLockTerminusId(request.TerminusId, request.TargetSceneRouteId); - await FTask.CompletedTask; - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Route/RouteComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Route/RouteComponent.cs deleted file mode 100644 index 1ce1fe8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Route/RouteComponent.cs +++ /dev/null @@ -1,82 +0,0 @@ -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; - -#if FANTASY_NET -namespace Fantasy.Network; - -/// -/// RouteComponent的AwakeSystem -/// -public sealed class RouteComponentAwakeSystem : AwakeSystem -{ - /// - /// Awake - /// - /// - /// - protected override void Awake(RouteComponent self) - { - ((Session)self.Parent).RouteComponent = self; - } -} - -/// -/// 自定义Route组件、如果要自定义Route协议必须使用这个组件 -/// -public sealed class RouteComponent : Entity -{ - /// - /// 存储路由类型和路由ID的映射关系。 - /// - public readonly Dictionary RouteAddress = new Dictionary(); - - /// - /// 添加路由类型和路由ID的映射关系。 - /// - /// 路由类型。 - /// 路由ID。 - public void AddAddress(long routeType, long routeId) - { - RouteAddress.Add(routeType, routeId); - } - - /// - /// 移除指定路由类型的映射关系。 - /// - /// 路由类型。 - public void RemoveAddress(long routeType) - { - RouteAddress.Remove(routeType); - } - - /// - /// 获取指定路由类型的路由ID。 - /// - /// 路由类型。 - /// 路由ID。 - public long GetRouteId(long routeType) - { - return RouteAddress.GetValueOrDefault(routeType, 0); - } - - /// - /// 尝试获取指定路由类型的路由ID。 - /// - /// 路由类型。 - /// 输出的路由ID。 - /// 如果获取成功返回true,否则返回false。 - public bool TryGetRouteId(long routeType, out long routeId) - { - return RouteAddress.TryGetValue(routeType, out routeId); - } - - /// - /// 释放组件资源,清空映射关系。 - /// - public override void Dispose() - { - RouteAddress.Clear(); - base.Dispose(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Component/ConsoleSessionHeartbeatComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Component/ConsoleSessionHeartbeatComponent.cs deleted file mode 100644 index dc4677e..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Component/ConsoleSessionHeartbeatComponent.cs +++ /dev/null @@ -1,156 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global - -#if FANTASY_CONSOLE - -using System; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.InnerMessage; -using Fantasy.Timer; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Network -{ - public class SessionHeartbeatComponentAwakeSystem : AwakeSystem - { - protected override void Awake(SessionHeartbeatComponent self) - { - self.TimerComponent = self.Scene.TimerComponent; - } - } - - /// - /// 负责管理会话心跳的组件。 - /// - public class SessionHeartbeatComponent : Entity - { - public int TimeOut; - public long TimerId; - public long LastTime; - public long SelfRunTimeId; - public long TimeOutTimerId; - public long SessionRunTimeId; - public TimerComponent TimerComponent; - public EntityReference Session; - private readonly PingRequest _pingRequest = new PingRequest(); - - public int Ping { get; private set; } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - Stop(); - Ping = 0; - Session = null; - TimeOut = 0; - SelfRunTimeId = 0; - base.Dispose(); - } - - /// - /// 使用指定的间隔启动心跳功能。 - /// - /// 以毫秒为单位的心跳请求发送间隔。 - /// 设置与服务器的通信超时时间,如果超过这个时间限制,将自动断开会话(Session)。 - /// 用于检测与服务器连接超时频率。 - public void Start(int interval, int timeOut = 2000, int timeOutInterval = 3000) - { - TimeOut = timeOut + interval; - Session = (Session)Parent; - SelfRunTimeId = RuntimeId; - LastTime = TimeHelper.Now; - - if (TimerComponent == null) - { - Log.Error("请在Unity的菜单执行Fantasy->Generate link.xml再重新打包"); - return; - } - - TimerId = TimerComponent.Net.RepeatedTimer(interval, () => RepeatedSend().Coroutine()); - TimeOutTimerId = TimerComponent.Net.RepeatedTimer(timeOutInterval, CheckTimeOut); - } - - private void CheckTimeOut() - { - if (TimeHelper.Now - LastTime < TimeOut) - { - return; - } - - Session entityReference = Session; - - if (entityReference == null) - { - return; - } - - entityReference.Dispose(); - } - - /// - /// 停止心跳功能。 - /// - public void Stop() - { - if (TimerId != 0) - { - TimerComponent?.Net.Remove(ref TimerId); - } - - if (TimeOutTimerId != 0) - { - TimerComponent?.Net.Remove(ref TimeOutTimerId); - } - } - - /// - /// 异步发送心跳请求并处理响应。 - /// - /// 表示进行中操作的异步任务。 - private async FTask RepeatedSend() - { - if (SelfRunTimeId != RuntimeId) - { - Stop(); - return; - } - - Session session = Session; - - if (session == null) - { - Dispose(); - return; - } - - try - { - var requestTime = TimeHelper.Now; - - var pingResponse = (PingResponse)await session.Call(_pingRequest); - - if (pingResponse.ErrorCode != 0) - { - return; - } - - var responseTime = TimeHelper.Now; - LastTime = responseTime; - Ping = (int)(responseTime - requestTime) / 2; - TimeHelper.TimeDiff = pingResponse.Now + Ping - responseTime; - } - catch (Exception) - { - Dispose(); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Component/SessionIdleCheckerComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Component/SessionIdleCheckerComponent.cs deleted file mode 100644 index 595fa75..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Component/SessionIdleCheckerComponent.cs +++ /dev/null @@ -1,117 +0,0 @@ -#if FANTASY_NET -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Platform.Net; -using Fantasy.Timer; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network; - -public class SessionIdleCheckerComponentAwakeSystem : AwakeSystem -{ - protected override void Awake(SessionIdleCheckerComponent self) - { - self.TimerComponent = self.Scene.TimerComponent; - } -} - -/// -/// 负责检查会话空闲超时的组件。 -/// -public class SessionIdleCheckerComponent : Entity -{ - /// - /// 空闲超时时间(毫秒) - /// - private long _timeOut; - /// - /// 检查计时器的 ID - /// - private long _timerId; - /// - /// 用于确保组件完整性的自身运行时 ID - /// - private long _selfRuntimeId; - /// - /// 对会话对象的引用 - /// - private Session _session; - public TimerComponent TimerComponent; - - /// - /// 重写 Dispose 方法以释放资源。 - /// - public override void Dispose() - { - Stop(); // 停止检查计时器 - _timeOut = 0; // 重置空闲超时时间 - _selfRuntimeId = 0; // 重置自身运行时 ID - _session = null; // 清除会话引用 - base.Dispose(); - } - - /// - /// 使用指定的间隔和空闲超时时间启动空闲检查功能。 - /// - /// 以毫秒为单位的检查间隔。 - /// 以毫秒为单位的空闲超时时间。 - internal void Start(int interval, int timeOut) - { - _timeOut = timeOut; - _session = (Session)Parent; - _selfRuntimeId = RuntimeId; - // 安排重复计时器,在指定的间隔内执行 Check 方法 - _timerId = TimerComponent.Net.RepeatedTimer(interval, Check); - } - - /// - /// 重新开始心跳检查 - /// - /// 以毫秒为单位的检查间隔。 - /// 以毫秒为单位的空闲超时时间。 - public void Restart(int interval, int timeOut) - { - Stop(); - Start(interval, timeOut); - } - - /// - /// 停止空闲检查功能。 - /// - private void Stop() - { - if (_timerId == 0) - { - return; - } - - TimerComponent.Net.Remove(ref _timerId); - } - - /// - /// 执行空闲检查操作。 - /// - private void Check() - { - if (_selfRuntimeId != RuntimeId || IsDisposed || _session == null) - { - Stop(); - return; - } - - var timeNow = TimeHelper.Now; - - if (timeNow - _session.LastReceiveTime < _timeOut) - { - return; - } -#if FANTASY_DEBUG - Log.Warning($"session timeout id:{Id} timeNow:{timeNow} _session.LastReceiveTime:{_session.LastReceiveTime} _timeOut:{_timeOut}"); -#endif - _session.Dispose(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Component/UnitySessionHeartbeatComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Component/UnitySessionHeartbeatComponent.cs deleted file mode 100644 index fa981ce..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Component/UnitySessionHeartbeatComponent.cs +++ /dev/null @@ -1,188 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global - -using System; -using System.Collections.Generic; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.InnerMessage; -using Fantasy.Timer; - -#if FANTASY_UNITY - -namespace Fantasy.Network -{ - public class SessionHeartbeatComponentAwakeSystem : AwakeSystem - { - protected override void Awake(SessionHeartbeatComponent self) - { - self.TimerComponent = self.Scene.TimerComponent; - } - } - - /// - /// 负责管理会话心跳的组件。 - /// - public class SessionHeartbeatComponent : Entity - { - public int TimeOut; - public long TimerId; - public long LastTime; - public long SelfRunTimeId; - public long TimeOutTimerId; - public TimerComponent TimerComponent; - public EntityReference Session; - private readonly PingRequest _pingRequest = new PingRequest(); - - // Ping滑动窗口及其累加和 - private int _pingSum; - private int _maxPingSamples; - private readonly Queue _pingSamples = new Queue(); - /// - /// 当前Ping延迟(毫秒,滑动均值) - /// - public int PingMilliseconds { get; private set; } - /// - /// 当前Ping延迟(秒,浮点数,通常用于调试) - /// - public float PingSeconds => PingMilliseconds / 1000f; - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - Stop(); - Session = null; - TimeOut = 0; - LastTime = 0; - SelfRunTimeId = 0; - base.Dispose(); - } - - /// - /// 使用指定的间隔启动心跳功能。 - /// - /// 以毫秒为单位的心跳请求发送间隔。 - /// 设置与服务器的通信超时时间,如果超过这个时间限制,将自动断开会话(Session)。 - /// 用于检测与服务器连接超时频率。 - /// Ping包的采样数量 - public void Start(int interval, int timeOut = 5000, int timeOutInterval = 3000, int maxPingSamples = 8) - { - TimeOut = timeOut + interval; - Session = (Session)Parent; - SelfRunTimeId = RuntimeId; - LastTime = TimeHelper.Now; - _maxPingSamples = maxPingSamples; - - if (TimerComponent == null) - { - Log.Error("请在Unity的菜单执行Fantasy->Generate link.xml再重新打包"); - return; - } - - TimerId = TimerComponent.Unity.RepeatedTimer(interval, () => - { - RepeatedSend().Coroutine(); - }); - TimeOutTimerId = TimerComponent.Unity.RepeatedTimer(timeOutInterval, CheckTimeOut); - } - - private void CheckTimeOut() - { - if (TimeHelper.Now - LastTime < TimeOut) - { - return; - } - - Session entityReference = Session; - - if (entityReference == null) - { - return; - } - - entityReference.Dispose(); - } - - /// - /// 停止心跳功能。 - /// - public void Stop() - { - if (TimerId != 0) - { - TimerComponent?.Unity.Remove(ref TimerId); - } - - if (TimeOutTimerId != 0) - { - TimerComponent?.Unity.Remove(ref TimeOutTimerId); - } - - _pingSum = 0; - PingMilliseconds = 0; - _pingSamples.Clear(); - } - - /// - /// 异步发送心跳请求并处理响应。 - /// - /// 表示进行中操作的异步任务。 - private async FTask RepeatedSend() - { - if (SelfRunTimeId != RuntimeId) - { - Stop(); - return; - } - - Session session = Session; - - if (session == null) - { - Dispose(); - return; - } - - try - { - var requestTime = TimeHelper.Now; - var pingResponse = (PingResponse)await session.Call(_pingRequest); - - if (pingResponse.ErrorCode != 0) - { - return; - } - - var responseTime = TimeHelper.Now; - LastTime = responseTime; - - // 计算Ping(毫秒) - var rtt = (int)(responseTime - requestTime); - var ping = rtt / 2; - - // 平滑滑动均值 - _pingSamples.Enqueue(ping); - _pingSum += ping; - if (_pingSamples.Count > _maxPingSamples) - { - _pingSum -= _pingSamples.Dequeue(); - } - - PingMilliseconds = Math.Max(0, _pingSamples.Count > 0 ? _pingSum / _pingSamples.Count : 0); - - // 校正服务器时间(可选) - TimeHelper.TimeDiff = pingResponse.Now + ping - responseTime; - } - catch (Exception) - { - Dispose(); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/ProcessSession/ProcessScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/ProcessSession/ProcessScheduler.cs deleted file mode 100644 index ec7c30c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/ProcessSession/ProcessScheduler.cs +++ /dev/null @@ -1,269 +0,0 @@ -#if FANTASY_NET -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using Fantasy.IdFactory; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Platform.Net; - -namespace Fantasy.Scheduler; - -internal static class ProcessScheduler -{ - public static void Scheduler(this ProcessSession session, Type messageType, uint rpcId, long routeId, APackInfo packInfo) - { - switch (packInfo.OpCodeIdStruct.Protocol) - { - case OpCodeType.InnerResponse: - case OpCodeType.InnerRouteResponse: - case OpCodeType.InnerAddressableResponse: - case OpCodeType.InnerRoamingResponse: - case OpCodeType.OuterAddressableResponse: - case OpCodeType.OuterCustomRouteResponse: - case OpCodeType.OuterRoamingResponse: - { - using (packInfo) - { - var sessionScene = session.Scene; - var message = packInfo.Deserialize(messageType); - sessionScene.ThreadSynchronizationContext.Post(() => - { - // 因为有可能是其他Scene线程下发送过来的、所以必须放到当前Scene进程下运行。 - sessionScene.NetworkMessagingComponent.ResponseHandler(rpcId, (IResponse)message); - }); - } - - return; - } - case OpCodeType.InnerRouteMessage: - { - using (packInfo) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new Exception($"not found scene routeId:{routeId}"); - } - - var message = packInfo.Deserialize(messageType); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - var sceneMessageDispatcherComponent = scene.MessageDispatcherComponent; - - if (entity == null || entity.IsDisposed) - { - return; - } - - sceneMessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, message, rpcId).Coroutine(); - }); - } - - return; - } - case OpCodeType.InnerRouteRequest: - { - using (packInfo) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new Exception($"not found scene routeId:{routeId}"); - } - - var message = packInfo.Deserialize(messageType); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - var sceneMessageDispatcherComponent = scene.MessageDispatcherComponent; - - if (entity == null || entity.IsDisposed) - { - sceneMessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, rpcId); - return; - } - - sceneMessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, message, rpcId).Coroutine(); - }); - } - - return; - } - case OpCodeType.OuterAddressableMessage: - case OpCodeType.OuterCustomRouteMessage: - case OpCodeType.OuterAddressableRequest: - case OpCodeType.OuterCustomRouteRequest: - case OpCodeType.OuterRoamingMessage: - case OpCodeType.OuterRoamingRequest: - { - using (packInfo) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new NotSupportedException($"not found scene routeId = {routeId}"); - } - - var message = packInfo.Deserialize(messageType); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - - if (entity == null || entity.IsDisposed) - { - scene.MessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, rpcId); - return; - } - - scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, message, rpcId).Coroutine(); - }); - } - return; - } - default: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - packInfo.Dispose(); - throw new NotSupportedException($"SessionInnerScheduler Received unsupported message protocolCode:{packInfoProtocolCode} messageType:{messageType}"); - } - } - } - - public static void Scheduler(this ProcessSession session, Type messageType, uint rpcId, long routeId, uint protocolCode, object message) - { - OpCodeIdStruct opCodeIdStruct = protocolCode; - - switch (opCodeIdStruct.Protocol) - { - case OpCodeType.InnerResponse: - case OpCodeType.InnerRouteResponse: - case OpCodeType.InnerAddressableResponse: - case OpCodeType.InnerRoamingResponse: - case OpCodeType.OuterAddressableResponse: - case OpCodeType.OuterCustomRouteResponse: - case OpCodeType.OuterRoamingResponse: - { - var sessionScene = session.Scene; - sessionScene.ThreadSynchronizationContext.Post(() => - { - var iResponse = (IResponse)session.Deserialize(messageType, message, ref opCodeIdStruct); - // 因为有可能是其他Scene线程下发送过来的、所以必须放到当前Scene进程下运行。 - sessionScene.NetworkMessagingComponent.ResponseHandler(rpcId, iResponse); - }); - - return; - } - case OpCodeType.InnerRoamingMessage: - case OpCodeType.InnerAddressableMessage: - case OpCodeType.InnerRouteMessage: - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new Exception($"not found scene routeId:{routeId}"); - } - - var messageObject = session.Deserialize(messageType, message, ref opCodeIdStruct); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - var sceneMessageDispatcherComponent = scene.MessageDispatcherComponent; - - if (entity == null || entity.IsDisposed) - { - return; - } - - sceneMessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, messageObject, rpcId).Coroutine(); - }); - - return; - } - case OpCodeType.InnerAddressableRequest: - case OpCodeType.InnerRoamingRequest: - case OpCodeType.InnerRouteRequest: - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new Exception($"not found scene routeId:{routeId}"); - } - - var messageObject = session.Deserialize(messageType, message, ref opCodeIdStruct); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - var sceneMessageDispatcherComponent = scene.MessageDispatcherComponent; - - if (entity == null || entity.IsDisposed) - { - sceneMessageDispatcherComponent.FailRouteResponse(session, message.GetType(), InnerErrorCode.ErrNotFoundRoute, rpcId); - return; - } - - sceneMessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, messageObject, rpcId).Coroutine(); - }); - - return; - } - case OpCodeType.OuterAddressableMessage: - case OpCodeType.OuterCustomRouteMessage: - case OpCodeType.OuterRoamingMessage: - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - Log.Error($"not found scene routeId:{routeId}"); - return; - } - - var messageObject = session.Deserialize(messageType, message, ref opCodeIdStruct); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - - switch (entity) - { - case null: - { - // 执行到这里是说明Session已经断开了 - // 因为这里是其他服务器Send到外网的数据、所以不需要给发送端返回就可以 - return; - } - case Session gateSession: - { - // 这里如果是Session只可能是Gate的Session、如果是的话、肯定是转发Address消息 - gateSession.Send((IMessage)messageObject, rpcId); - return; - } - default: - { - scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, messageObject, rpcId).Coroutine(); - return; - } - } - }); - - return; - } - default: - { - throw new NotSupportedException($"SessionInnerScheduler Received unsupported message protocolCode:{protocolCode} messageType:{messageType}"); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/ProcessSession/ProcessSession.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/ProcessSession/ProcessSession.cs deleted file mode 100644 index ecd0bd4..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/ProcessSession/ProcessSession.cs +++ /dev/null @@ -1,124 +0,0 @@ -using Fantasy.Async; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.PacketParser.Interface; -using Fantasy.Pool; -using Fantasy.Scheduler; -using Fantasy.Serialize; -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#if FANTASY_NET -namespace Fantasy.Network; - -/// -/// 网络服务器内部会话。 -/// -public sealed class ProcessSession : Session -{ - private readonly MemoryStreamBufferPool _memoryStreamBufferPool = new MemoryStreamBufferPool(); - private readonly Dictionary> _createInstances = new Dictionary>(); - - /// - /// 发送消息到服务器内部。 - /// - /// 要发送的消息。 - /// RPC 标识符。 - /// 路由标识符。 - public override void Send(IMessage message, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - this.Scheduler(message.GetType(), rpcId, routeId, message.OpCode(), message); - } - - /// - /// 发送路由消息到服务器内部。 - /// - /// 要发送的路由消息。 - /// RPC 标识符。 - /// 路由标识符。 - public override void Send(IRouteMessage routeMessage, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - this.Scheduler(routeMessage.GetType(), rpcId, routeId, routeMessage.OpCode(), routeMessage); - } - - public override void Send(uint rpcId, long routeId, Type messageType, APackInfo packInfo) - { - if (IsDisposed) - { - return; - } - - this.Scheduler(messageType, rpcId, routeId, packInfo); - } - - public override void Send(ProcessPackInfo packInfo, uint rpcId = 0, long routeId = 0) - { - this.Scheduler(packInfo.MessageType, rpcId, routeId, packInfo); - } - - public override void Send(MemoryStreamBuffer memoryStream, uint rpcId = 0, long routeId = 0) - { - throw new Exception("The use of this method is not supported"); - } - - public override FTask Call(IRouteRequest request, long routeId = 0) - { - throw new Exception("The use of this method is not supported"); - } - - public override FTask Call(IRequest request, long routeId = 0) - { - throw new Exception("The use of this method is not supported"); - } - - public object Deserialize(Type messageType, object message, ref OpCodeIdStruct opCodeIdStruct) - { - var memoryStream = _memoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.None); - - try - { - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - - if (memoryStream.Position == 0) - { - if (_createInstances.TryGetValue(messageType, out var createInstance)) - { - return createInstance(); - } - - createInstance = CreateInstance.CreateObject(messageType); - _createInstances.Add(messageType, createInstance); - return createInstance(); - } - - memoryStream.SetLength(memoryStream.Position); - memoryStream.Seek(0, SeekOrigin.Begin); - return serializer.Deserialize(messageType, memoryStream); - } - } - catch (Exception e) - { - Log.Error($"ProcessSession.Deserialize {e}"); - } - finally - { - _memoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - - throw new Exception($"type:{messageType} Does not support processing protocol"); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/ProcessSession/ProcessSessionInfo.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/ProcessSession/ProcessSessionInfo.cs deleted file mode 100644 index 6e3a534..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/ProcessSession/ProcessSessionInfo.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network; - -internal sealed class ProcessSessionInfo(Session session, AClientNetwork aClientNetwork) : IDisposable -{ - public readonly Session Session = session; - public readonly AClientNetwork AClientNetwork = aClientNetwork; - - public void Dispose() - { - Session.Dispose(); - AClientNetwork?.Dispose(); - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Session.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Session.cs deleted file mode 100644 index 02789e7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Network/Session/Session.cs +++ /dev/null @@ -1,298 +0,0 @@ -// ReSharper disable RedundantUsingDirective -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.PacketParser.Interface; -using Fantasy.Scheduler; -using Fantasy.Serialize; -#if FANTASY_NET -using Fantasy.Network.Route; -using Fantasy.Platform.Net; -using Fantasy.Network.Roaming; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#endif -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 -#pragma warning disable CS8601 -#pragma warning disable CS8618 - -namespace Fantasy.Network -{ - /// - /// 网络会话的基类,用于管理网络通信。 - /// - public class Session : Entity, ISupportedMultiEntity - { - private uint _rpcId; - internal long LastReceiveTime; - /// - /// 关联的网络连接通道 - /// - internal INetworkChannel Channel { get; private set; } - /// - /// 当前Session的终结点信息 - /// - public IPEndPoint RemoteEndPoint { get; private set; } - private ANetworkMessageScheduler NetworkMessageScheduler { get; set;} - internal readonly Dictionary> RequestCallback = new(); - /// - /// Session的Dispose委托 - /// - internal event Action OnDispose; -#if FANTASY_NET - internal RouteComponent RouteComponent; - internal SessionRoamingComponent SessionRoamingComponent; - internal AddressableRouteComponent AddressableRouteComponent; - internal static Session Create(ANetworkMessageScheduler networkMessageScheduler, ANetworkServerChannel channel, NetworkTarget networkTarget) - { - var session = Entity.Create(channel.Scene, false, true); - session.Channel = channel; - session.NetworkMessageScheduler = networkMessageScheduler; - session.RemoteEndPoint = channel.RemoteEndPoint as IPEndPoint; - session.OnDispose = channel.Dispose; - session.LastReceiveTime = TimeHelper.Now; - // 在外部网络目标下,添加会话空闲检查组件 - if (networkTarget == NetworkTarget.Outer) - { - var interval = ProgramDefine.SessionIdleCheckerInterval; - var timeOut = ProgramDefine.SessionIdleCheckerTimeout; - session.AddComponent().Start(interval, timeOut); - } - return session; - } -#endif - internal static Session Create(AClientNetwork network, IPEndPoint remoteEndPoint) - { - // 创建会话实例 - var session = Entity.Create(network.Scene, false, true); - session.Channel = network; - session.RemoteEndPoint = remoteEndPoint; - session.OnDispose = network.Dispose; - session.NetworkMessageScheduler = network.NetworkMessageScheduler; - session.LastReceiveTime = TimeHelper.Now; - return session; - } -#if FANTASY_NET - internal static ProcessSession CreateInnerSession(Scene scene) - { - var session = Entity.Create(scene, false, false); - session.NetworkMessageScheduler = new InnerMessageScheduler(scene); - return session; - } - - /// - /// 发送一个消息,框架内部使用建议不要用这个方法。 - /// - /// 如果是RPC消息需要传递一个RPCId - /// routeId - /// 消息的类型 - /// packInfo消息包 - public virtual void Send(uint rpcId, long routeId, Type messageType, APackInfo packInfo) - { - if (IsDisposed) - { - return; - } - - Channel.Send(rpcId, routeId, packInfo.MemoryStream, null); - } - - /// - /// 发送一个消息,框架内部使用建议不要用这个方法。 - /// - /// 一个ProcessPackInfo消息包 - /// 如果是RPC消息需要传递一个RPCId - /// routeId - public virtual void Send(ProcessPackInfo packInfo, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - using (packInfo) - { - Channel.Send(rpcId, routeId, packInfo.MemoryStream, null); - } - } - - /// - /// 发送一个消息 - /// - /// 需要发送的MemoryStreamBuffer - /// 如果是RPC消息需要传递一个RPCId - /// routeId - public virtual void Send(MemoryStreamBuffer memoryStream, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - Channel.Send(rpcId, routeId, memoryStream, null); - } -#endif - /// - /// 销毁一个Session,当执行了这个方法会自动断开网络的连接。 - /// - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - _rpcId = 0; - LastReceiveTime = 0; - Channel = null; - RemoteEndPoint = null; - NetworkMessageScheduler = null; -#if FANTASY_NET - SessionRoamingComponent = null; - RouteComponent = null; - AddressableRouteComponent = null; -#endif - base.Dispose(); - - // 终止所有等待中的请求回调 - foreach (var requestCallback in RequestCallback.Values.ToArray()) - { - requestCallback.SetException(new Exception($"session is dispose: {Id}")); - } - - RequestCallback.Clear(); - OnDispose?.Invoke(); - } - - /// - /// 发送一个消息 - /// - /// 消息的实例 - /// 如果是RPC消息需要传递一个RPCId - /// routeId - public virtual void Send(IMessage message, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - Channel.Send(rpcId, routeId, null, message); - } - - /// - /// 发送一个消息 - /// - /// 消息的实例,不同的是这个是发送Route消息使用的 - /// 如果是RPC消息需要传递一个RPCId - /// routeId - public virtual void Send(IRouteMessage routeMessage, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - Channel.Send(rpcId, routeId, null, routeMessage); - } - - /// - /// 发送一个RPC消息 - /// - /// 请求Route消息的实例 - /// routeId - /// - public virtual FTask Call(IRouteRequest request, long routeId = 0) - { - if (IsDisposed) - { - return null; - } - - var requestCallback = FTask.Create(); - var rpcId = ++_rpcId; - RequestCallback.Add(rpcId, requestCallback); - Send(request, rpcId, routeId); - return requestCallback; - } - - /// - /// 发送一个RPC消息 - /// - /// 请求消息的实例 - /// routeId - /// - public virtual FTask Call(IRequest request, long routeId = 0) - { - if (IsDisposed) - { - return null; - } - - var requestCallback = FTask.Create(); - var rpcId = ++_rpcId; - RequestCallback.Add(rpcId, requestCallback); - Send(request, rpcId, routeId); - return requestCallback; - } - - internal void Receive(APackInfo packInfo) - { - if (IsDisposed) - { - return; - } - - LastReceiveTime = TimeHelper.Now; - - try - { - NetworkMessageScheduler.Scheduler(this, packInfo).Coroutine(); - } - catch (Exception e) - { - // 如果解析失败,只有一种可能,那就是有人恶意发包。 - // 所以这里强制关闭了当前连接。不让对方一直发包。 - Dispose(); - Log.Error(e); - } - } -#if FANTASY_NET - /// - /// 重新开始心跳检查 - /// - /// - /// - public void RestartIdleChecker(int interval, int timeOut) - { - var sessionIdleCheckerComponent = GetComponent(); - if (sessionIdleCheckerComponent == null) - { - Log.Error("SessionIdleCheckerComponent is null"); - return; - } - - sessionIdleCheckerComponent.Restart(interval, timeOut); - } - - /// - /// 重新开始心跳检查(使用框架配置的参数) - /// - public void RestartIdleChecker() - { - RestartIdleChecker(ProgramDefine.SessionIdleCheckerInterval, ProgramDefine.SessionIdleCheckerTimeout); - } -#endif - } -} diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Console/Entry.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Console/Entry.cs deleted file mode 100644 index c0b3aa6..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Console/Entry.cs +++ /dev/null @@ -1,101 +0,0 @@ -#if FANTASY_CONSOLE -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.Serialize; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Console -{ - public struct OnFantasyInit - { - public Scene Scene; - } - - /// - /// 一般的控制台启动入口,可以适用大部分客户端环境 - /// - public sealed class Entry - { - private static bool _isInit; - private static Thread _updateThread; - public static Scene Scene { get; private set; } - - /// - /// 初始化框架 - /// - /// - public static async FTask Initialize(params System.Reflection.Assembly[] assemblies) - { - if (_isInit) - { - Log.Error("Fantasy has already been initialized and does not need to be initialized again!"); - return; - } - Log.Info($"Fantasy Version:{Define.VERSION}"); - // 初始化程序集管理系统 - await AssemblySystem.InnerInitialize(assemblies); - // 初始化序列化 - SerializerManager.Initialize(); - _isInit = true; - Log.Debug("Fantasy Initialize Complete!"); - } - - /// - /// 启动框架。 - /// 如果您的平台有每帧更新逻辑的方法,请不要调用这个方法。 - /// 如果没有实现每帧执行方法平台需要调用这个方法,目的是开启一个新的线程来每帧执行Update。 - /// 注意因为开启了一个新的线程来处理更新逻辑,所以要注意多线程的问题。 - /// - public static void StartUpdate() - { - _updateThread = new Thread(() => - { - while (_isInit) - { - ThreadScheduler.Update(); - Thread.Sleep(1); - } - }) - { - IsBackground = true - }; - _updateThread.Start(); - } - - /// - /// 在Entry中创建一个Scene,如果Scene已经被创建过,将先销毁Scene再创建。 - /// - /// - /// - public static async FTask CreateScene(string sceneRuntimeMode = SceneRuntimeMode.MainThread) - { - Scene?.Dispose(); - Scene = await Scene.Create(sceneRuntimeMode); - await Scene.EventComponent.PublishAsync(new OnFantasyInit() - { - Scene = Scene - }); - return Scene; - } - - /// - /// 如果有的话一定要在每帧执行这个方法 - /// - public void Update() - { - ThreadScheduler.Update(); - } - - public static void Dispose() - { - AssemblySystem.Dispose(); - SerializerManager.Dispose(); - Scene?.Dispose(); - Scene = null; - _isInit = false; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Console/ThreadSynchronizationContext.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Console/ThreadSynchronizationContext.cs deleted file mode 100644 index 29fd54a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Console/ThreadSynchronizationContext.cs +++ /dev/null @@ -1,38 +0,0 @@ -#if FANTASY_CONSOLE -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8765 // Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes). -namespace Fantasy -{ - public sealed class ThreadSynchronizationContext : SynchronizationContext - { - private Action _actionHandler; - private readonly Queue _queue = new(); - - public void Update() - { - while (_queue.TryDequeue(out _actionHandler)) - { - try - { - _actionHandler(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void Post(SendOrPostCallback callback, object state) - { - Post(() => callback(state)); - } - - public void Post(Action action) - { - _queue.Enqueue(action); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigLoader.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigLoader.cs deleted file mode 100644 index d359cf5..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigLoader.cs +++ /dev/null @@ -1,537 +0,0 @@ -#if FANTASY_NET -using System.Text; -using System.Xml; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.IdFactory; -using Fantasy.Network; -using Fantasy.Platform.Net; - -namespace Fantasy; - -/// -/// Fantasy框架XML配置文件加载器 -/// -public static class ConfigLoader -{ - /// - /// 从XML配置文件初始化所有配置 - /// - /// - /// - public static async FTask InitializeFromXml(string configPath) - { - var configText = await FileHelper.GetTextByRelativePath(configPath); - var doc = new XmlDocument(); - doc.LoadXml(configText); - - var root = doc.DocumentElement; - if (root?.LocalName != "fantasy") - { - throw new InvalidOperationException("Invalid Fantasy config file format"); - } - - // 创建命名空间管理器 - - var nsManager = new XmlNamespaceManager(doc.NameTable); - nsManager.AddNamespace("f", "http://fantasy.net/config"); - - // 加载运行时配置 - - LoadRuntimeConfig(root, nsManager); - - var configTableNode = root.SelectSingleNode("f:configTable", nsManager); - if (configTableNode != null) - { - var configTablePath = configTableNode.Attributes?["path"]?.Value; - if (string.IsNullOrEmpty(configTablePath)) - { - throw new InvalidOperationException("The configTable in the Fantasy configuration file lacks path configuration"); - } - await LoadJsonConfig(configTablePath); - return; - } - - var serverNode = root.SelectSingleNode("f:server", nsManager); - if (serverNode == null) - { - throw new InvalidOperationException("Missing server configuration in Fantasy config file"); - } - - // 加载框架需要的四个配置文件 - LoadMachineConfig(serverNode, nsManager); - LoadProcessConfig(serverNode, nsManager); - LoadWorldConfig(serverNode, nsManager); - LoadSceneConfig(serverNode, nsManager); - // 验证所有配置的完整性和正确性 - CheckConfig(); - } - - #region LoadJsonConfig - - private static async FTask LoadJsonConfig(string configTablePath) - { - var machineConfigFullPath = FileHelper.GetFullPath($"{configTablePath}/MachineConfigData.Json"); - - if (!File.Exists(machineConfigFullPath)) - { - throw new InvalidOperationException($"MachineConfigData.Json not found in the {machineConfigFullPath} directory"); - } - - var processConfigFullPath = FileHelper.GetFullPath($"{configTablePath}/ProcessConfigData.Json"); - - if (!File.Exists(processConfigFullPath)) - { - throw new InvalidOperationException($"ProcessConfigData.Json not found in the {processConfigFullPath} directory"); - } - - var worldConfigFullPath = FileHelper.GetFullPath($"{configTablePath}/WorldConfigData.Json"); - - if (!File.Exists(worldConfigFullPath)) - { - throw new InvalidOperationException($"WorldConfigData.Json not found in the {worldConfigFullPath} directory"); - } - - var sceneConfigFullPath = FileHelper.GetFullPath($"{configTablePath}/SceneConfigData.Json"); - - if (!File.Exists(sceneConfigFullPath)) - { - throw new InvalidOperationException($"SceneConfigData.Json not found in the {sceneConfigFullPath} directory"); - } - - MachineConfigData.Initialize(await File.ReadAllTextAsync(machineConfigFullPath, Encoding.UTF8)); - ProcessConfigData.Initialize(await File.ReadAllTextAsync(processConfigFullPath, Encoding.UTF8)); - WorldConfigData.Initialize(await File.ReadAllTextAsync(worldConfigFullPath, Encoding.UTF8)); - SceneConfigData.Initialize(await File.ReadAllTextAsync(sceneConfigFullPath, Encoding.UTF8)); - - // 验证所有配置的完整性和正确性 - CheckConfig(); - } - - #endregion - - #region LoadXMLConfig - - private static void LoadMachineConfig(XmlNode serverNode, XmlNamespaceManager nsManager) - { - var machinesNode = serverNode.SelectSingleNode("f:machines", nsManager); - if (machinesNode == null) - { - throw new InvalidOperationException("Missing machines configuration - at least one machine must be configured"); - } - - var machineNodes = machinesNode.SelectNodes("f:machine", nsManager); - if (machineNodes == null || machineNodes.Count == 0) - { - throw new InvalidOperationException("No machine configurations found - at least one machine must be configured"); - } - - var machineList = new List(); - foreach (XmlNode machineNode in machineNodes) - { - var machine = new MachineConfig - { - Id = uint.Parse(GetRequiredAttribute(machineNode, "id")), - OuterIP = GetRequiredAttribute(machineNode, "outerIP"), - OuterBindIP = GetRequiredAttribute(machineNode, "outerBindIP"), - InnerBindIP = GetRequiredAttribute(machineNode, "innerBindIP") - }; - machineList.Add(machine); - } - - MachineConfigData.Initialize(machineList); - } - - private static void LoadProcessConfig(XmlNode serverNode, XmlNamespaceManager nsManager) - { - var processesNode = serverNode.SelectSingleNode("f:processes", nsManager); - if (processesNode == null) - { - throw new InvalidOperationException("Missing processes configuration - at least one process must be configured"); - } - - var processNodes = processesNode.SelectNodes("f:process", nsManager); - if (processNodes == null || processNodes.Count == 0) - { - throw new InvalidOperationException("No process configurations found - at least one process must be configured"); - } - - var processList = new List(); - foreach (XmlNode processNode in processNodes) - { - var process = new ProcessConfig - { - Id = uint.Parse(GetRequiredAttribute(processNode, "id")), - MachineId = uint.Parse(GetRequiredAttribute(processNode, "machineId")), - StartupGroup = uint.Parse(GetRequiredAttribute(processNode, "startupGroup")) - }; - processList.Add(process); - } - - ProcessConfigData.Initialize(processList); - } - - private static void LoadWorldConfig(XmlNode serverNode, XmlNamespaceManager nsManager) - { - var worldsNode = serverNode.SelectSingleNode("f:worlds", nsManager); - if (worldsNode == null) - { - throw new InvalidOperationException("Missing worlds configuration - at least one world must be configured"); - } - - var worldNodes = worldsNode.SelectNodes("f:world", nsManager); - if (worldNodes == null || worldNodes.Count == 0) - { - throw new InvalidOperationException("No world configurations found - at least one world must be configured"); - } - - var worldList = new List(); - foreach (XmlNode worldNode in worldNodes) - { - var world = new WorldConfig - { - Id = uint.Parse(GetRequiredAttribute(worldNode, "id")), - WorldName = GetRequiredAttribute(worldNode, "worldName"), - DbConnection = GetOptionalAttribute(worldNode, "dbConnection") ?? string.Empty, - DbName = GetRequiredAttribute(worldNode, "dbName"), - DbType = GetRequiredAttribute(worldNode, "dbType") - }; - worldList.Add(world); - } - - WorldConfigData.Initialize(worldList); - } - - private static void LoadSceneConfig(XmlNode serverNode, XmlNamespaceManager nsManager) - { - var scenesNode = serverNode.SelectSingleNode("f:scenes", nsManager); - if (scenesNode == null) - { - throw new InvalidOperationException("Missing scenes configuration - at least one scene must be configured"); - } - - var sceneNodes = scenesNode.SelectNodes("f:scene", nsManager); - if (sceneNodes == null || sceneNodes.Count == 0) - { - throw new InvalidOperationException("No scene configurations found - at least one scene must be configured"); - } - - var sceneList = new List(); - foreach (XmlNode sceneNode in sceneNodes) - { - var scene = new SceneConfig - { - Id = uint.Parse(GetRequiredAttribute(sceneNode, "id")), - ProcessConfigId = uint.Parse(GetRequiredAttribute(sceneNode, "processConfigId")), - WorldConfigId = uint.Parse(GetRequiredAttribute(sceneNode, "worldConfigId")), - SceneRuntimeMode = GetRequiredAttribute(sceneNode, "sceneRuntimeMode"), - SceneTypeString = GetRequiredAttribute(sceneNode, "sceneTypeString"), - NetworkProtocol = GetOptionalAttribute(sceneNode, "networkProtocol") ?? string.Empty, - OuterPort = int.Parse(GetOptionalAttribute(sceneNode, "outerPort") ?? "0"), - InnerPort = int.Parse(GetRequiredAttribute(sceneNode, "innerPort")), - SceneType = int.Parse(GetRequiredAttribute(sceneNode, "sceneType")) - }; - sceneList.Add(scene); - } - - SceneConfigData.Initialize(sceneList); - } - - private static string GetRequiredAttribute(XmlNode node, string attributeName) - { - return node.Attributes?[attributeName]?.Value ?? throw new InvalidOperationException($"Required attribute '{attributeName}' is missing or null"); - } - - private static string? GetOptionalAttribute(XmlNode? node, string attributeName) - { - return node?.Attributes?[attributeName]?.Value; - } - - #endregion - - #region CheckConfig - - private static void CheckConfig() - { - // 检查Machine配置 - CheckMachineConfig(); - // 检查Process配置 - CheckProcessConfig(); - // 检查World配置 - CheckWorldConfig(); - // 检查Scene配置 - CheckSceneConfig(); - // 检查引用关系 - CheckConfigReferences(); - // 检查端口冲突 - CheckPortConflicts(); - } - - private static void CheckMachineConfig() - { - var machines = MachineConfigData.Instance.List; - var machineIds = new HashSet(); - - foreach (var machine in machines) - { - // 检查ID重复 - if (!machineIds.Add(machine.Id)) - { - throw new InvalidOperationException($"Duplicate machine ID: {machine.Id}"); - } - - // 检查必填字段 - if (string.IsNullOrWhiteSpace(machine.OuterIP)) - { - throw new InvalidOperationException($"Machine {machine.Id}: OuterIP cannot be null or empty"); - } - - if (string.IsNullOrWhiteSpace(machine.OuterBindIP)) - { - throw new InvalidOperationException($"Machine {machine.Id}: OuterBindIP cannot be null or empty"); - } - - if (string.IsNullOrWhiteSpace(machine.InnerBindIP)) - { - throw new InvalidOperationException($"Machine {machine.Id}: InnerBindIP cannot be null or empty"); - } - } - } - - private static void CheckProcessConfig() - { - var processes = ProcessConfigData.Instance.List; - var processIds = new HashSet(); - - foreach (var process in processes) - { - // 检查ID重复 - if (!processIds.Add(process.Id)) - { - throw new InvalidOperationException($"Duplicate process ID: {process.Id}"); - } - - // 检查必填字段 - if (process.Id == 0) - { - throw new InvalidOperationException("Process ID cannot be 0"); - } - - if (process.MachineId == 0) - { - throw new InvalidOperationException($"Process {process.Id}: MachineId cannot be 0"); - } - } - } - - private static void CheckWorldConfig() - { - var worlds = WorldConfigData.Instance.List; - var worldIds = new HashSet(); - - foreach (var world in worlds) - { - // 检查ID重复 - if (!worldIds.Add(world.Id)) - { - throw new InvalidOperationException($"Duplicate world ID: {world.Id}"); - } - - // 检查必填字段 - if (string.IsNullOrWhiteSpace(world.WorldName)) - { - throw new InvalidOperationException($"World {world.Id}: WorldName cannot be null or empty"); - } - - if (string.IsNullOrWhiteSpace(world.DbName)) - { - throw new InvalidOperationException($"World {world.Id}: DbName cannot be null or empty"); - } - - if (string.IsNullOrWhiteSpace(world.DbType)) - { - throw new InvalidOperationException($"World {world.Id}: DbType cannot be null or empty"); - } - } - } - - private static void CheckSceneConfig() - { - var scenes = SceneConfigData.Instance.List; - var sceneIds = new HashSet(); - - foreach (var scene in scenes) - { - // 检查ID重复 - if (!sceneIds.Add(scene.Id)) - { - throw new InvalidOperationException($"Duplicate scene ID: {scene.Id}"); - } - - // 检查必填字段 - if (scene.ProcessConfigId == 0) - { - throw new InvalidOperationException($"Scene {scene.Id}: ProcessConfigId cannot be 0"); - } - - if (scene.WorldConfigId == 0) - { - throw new InvalidOperationException($"Scene {scene.Id}: WorldConfigId cannot be 0"); - } - - if (string.IsNullOrWhiteSpace(scene.SceneRuntimeMode)) - { - throw new InvalidOperationException($"Scene {scene.Id}: SceneRuntimeMode cannot be null or empty"); - } - - if (string.IsNullOrWhiteSpace(scene.SceneTypeString)) - { - throw new InvalidOperationException($"Scene {scene.Id}: SceneTypeString cannot be null or empty"); - } - - if (scene.InnerPort == 0) - { - throw new InvalidOperationException($"Scene {scene.Id}: InnerPort cannot be 0"); - } - - if (scene.SceneType == 0) - { - throw new InvalidOperationException($"Scene {scene.Id}: SceneType cannot be 0"); - } - - // 检查NetworkProtocol配置 - if (scene.OuterPort > 0 && string.IsNullOrWhiteSpace(scene.NetworkProtocol)) - { - throw new InvalidOperationException($"Scene {scene.Id}: NetworkProtocol must be set when OuterPort > 0"); - } - - // 检查Scene ID范围(仅在IdFactoryType.World模式下) - CheckSceneIdRange(scene); - } - } - - private static void CheckConfigReferences() - { - // 检查Process的MachineId引用 - foreach (var process in ProcessConfigData.Instance.List) - { - if (MachineConfigData.Instance.List.All(m => m.Id != process.MachineId)) - { - throw new InvalidOperationException($"Process {process.Id}: Referenced MachineId {process.MachineId} not found"); - } - } - - // 检查Scene的ProcessConfigId和WorldConfigId引用 - foreach (var scene in SceneConfigData.Instance.List) - { - if (ProcessConfigData.Instance.List.All(p => p.Id != scene.ProcessConfigId)) - { - throw new InvalidOperationException($"Scene {scene.Id}: Referenced ProcessConfigId {scene.ProcessConfigId} not found"); - } - - if (WorldConfigData.Instance.List.All(w => w.Id != scene.WorldConfigId)) - { - throw new InvalidOperationException($"Scene {scene.Id}: Referenced WorldConfigId {scene.WorldConfigId} not found"); - } - } - } - - private static void CheckPortConflicts() - { - // 按机器分组检查端口冲突 - var machinePortMap = new Dictionary>(); // MachineId -> (Port -> SceneId) - - foreach (var scene in SceneConfigData.Instance.List) - { - // 获取Scene所属的机器ID - var process = ProcessConfigData.Instance.Get(scene.ProcessConfigId); - var machineId = process.MachineId; - - if (!machinePortMap.ContainsKey(machineId)) - { - machinePortMap[machineId] = new Dictionary(); - } - - var machinePorts = machinePortMap[machineId]; - - // 检查同一Scene内InnerPort和OuterPort是否冲突 - if (scene.OuterPort > 0 && scene.InnerPort == scene.OuterPort) - { - throw new InvalidOperationException($"Scene {scene.Id}: InnerPort and OuterPort cannot use the same port {scene.InnerPort}"); - } - - // 检查InnerPort在同一机器下是否与其他端口冲突 - if (machinePorts.TryGetValue(scene.InnerPort, out var conflictSceneId1)) - { - throw new InvalidOperationException($"Scene {scene.Id}: InnerPort {scene.InnerPort} conflicts with another port from Scene {conflictSceneId1} on Machine {machineId}"); - } - machinePorts[scene.InnerPort] = scene.Id; - - // 检查OuterPort在同一机器下是否与其他端口冲突(如果不为0) - if (scene.OuterPort > 0) - { - if (machinePorts.TryGetValue(scene.OuterPort, out var conflictSceneId)) - { - throw new InvalidOperationException($"Scene {scene.Id}: OuterPort {scene.OuterPort} conflicts with another port from Scene {conflictSceneId} on Machine {machineId}"); - } - machinePorts[scene.OuterPort] = scene.Id; - } - } - } - - private static void CheckSceneIdRange(SceneConfig scene) - { - // 检查当前是否为World模式的ID工厂 - if (IdFactoryHelper.GetIdFactoryType() != IdFactoryType.World) - { - return; // 非World模式不需要检查 - } - - var worldConfigId = scene.WorldConfigId; - var minAllowedId = worldConfigId * 1000 + 1; - var maxAllowedId = worldConfigId * 1000 + 255; - - if (scene.Id < minAllowedId) - { - throw new InvalidOperationException($"Scene {scene.Id}: ID must be >= {minAllowedId} (WorldConfigId {worldConfigId} * 1000 + 1)"); - } - - if (scene.Id > maxAllowedId) - { - throw new InvalidOperationException($"Scene {scene.Id}: ID must be <= {maxAllowedId} (WorldConfigId {worldConfigId} * 1000 + 255)"); - } - } - - #endregion - - #region LoadRuntimeConfig - - private static void LoadRuntimeConfig(XmlNode root, XmlNamespaceManager nsManager) - { - // 加载IdFactory配置 - - XmlNode? idFactoryNode = root.SelectSingleNode("f:idFactory", nsManager); - string idFactoryType = GetOptionalAttribute(idFactoryNode, "type") ?? "World"; - IdFactoryHelper.Initialize(Enum.Parse(idFactoryType)); - - // 加载网络配置 - - XmlNode? networkNode = root.SelectSingleNode("f:network", nsManager); - ProgramDefine.InnerNetwork = Enum.Parse(GetOptionalAttribute(networkNode, "inner") ?? "TCP"); - ProgramDefine.MaxMessageSize = int.Parse(GetOptionalAttribute(networkNode, "maxMessageSize") ?? "1048560"); - - // 加载会话配置 - - XmlNode? sessionNode = root.SelectSingleNode("f:session", nsManager); - ProgramDefine.SessionIdleCheckerTimeout = int.Parse(GetOptionalAttribute(sessionNode, "idleTimeout") ?? "8000"); - ProgramDefine.SessionIdleCheckerInterval = int.Parse(GetOptionalAttribute(sessionNode, "idleInterval") ?? "5000"); - - Log.Info($"Current inner network protocol:{ProgramDefine.InnerNetwork.ToString()}"); - Log.Info($"Max Message Size(byte):{ProgramDefine.MaxMessageSize}"); - Log.Info($"Current session idle timeout:{ProgramDefine.SessionIdleCheckerTimeout}"); - Log.Info($"Session-check interval:{ProgramDefine.SessionIdleCheckerInterval} "); - } - - #endregion -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/MachineConfig.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/MachineConfig.cs deleted file mode 100644 index b32996f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/MachineConfig.cs +++ /dev/null @@ -1,110 +0,0 @@ -#if FANTASY_NET -// ReSharper disable InconsistentNaming -using System.Collections.Concurrent; -using System.Runtime.Serialization; -using Fantasy.Helper; -using Newtonsoft.Json; -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Net -{ - /// - /// 用于记录服务器物理信息 - /// - public sealed class MachineConfigData - { - /// - /// 存放所有MachineConfigInfo信息 - /// - public List List; - [JsonIgnore] - [IgnoreDataMember] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); - /// - /// 获得MachineConfig的实例 - /// - public static MachineConfigData Instance { get; private set; } - /// - /// 初始化MachineConfig - /// - /// - public static void Initialize(string machineConfigJson) - { - try - { - Instance = machineConfigJson.Deserialize(); - foreach (var config in Instance.List) - { - Instance._configs.TryAdd(config.Id, config); - } - } - catch (Exception e) - { - throw new InvalidOperationException($"MachineConfigData.Json format error {e.Message}"); - } - } - /// - /// 初始化MachineConfig - /// - /// - public static void Initialize(List list) - { - Instance = new MachineConfigData - { - List = list - }; - foreach (var config in Instance.List) - { - Instance._configs.TryAdd(config.Id, config); - } - } - /// - /// 根据Id获取MachineConfig - /// - /// - /// - /// - public MachineConfig Get(uint id) - { - if (_configs.TryGetValue(id, out var machineConfigInfo)) - { - return machineConfigInfo; - } - - throw new FileNotFoundException($"MachineConfig not find {id} Id"); - } - /// - /// 根据Id获取MachineConfig - /// - /// - /// - /// - public bool TryGet(uint id, out MachineConfig config) - { - return _configs.TryGetValue(id, out config); - } - } - /// - /// 表示一个物理服务器的信息 - /// - public sealed class MachineConfig - { - /// - /// Id - /// - public uint Id { get; set; } - /// - /// 外网IP - /// - public string OuterIP { get; set; } - /// - /// 外网绑定IP - /// - public string OuterBindIP { get; set; } - /// - /// 内网绑定IP - /// - public string InnerBindIP { get; set; } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/ProcessConfig.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/ProcessConfig.cs deleted file mode 100644 index 73301ce..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/ProcessConfig.cs +++ /dev/null @@ -1,122 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using System.Runtime.Serialization; -using Fantasy.Helper; -using Newtonsoft.Json; -// ReSharper disable CollectionNeverUpdated.Global -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Platform.Net -{ - /// - /// 用于管理进程信息 - /// - public sealed class ProcessConfigData - { - /// - /// 存放所有ProcessConfig信息 - /// - public List List; - [JsonIgnore] - [IgnoreDataMember] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); - /// - /// 获得ProcessConfigData的实例 - /// - public static ProcessConfigData Instance { get; private set; } - /// - /// 初始化ProcessConfig - /// - /// - public static void Initialize(string processConfigJson) - { - try - { - Instance = processConfigJson.Deserialize(); - foreach (var config in Instance.List) - { - Instance._configs.TryAdd(config.Id, config); - } - } - catch (Exception e) - { - throw new InvalidOperationException($"ProcessConfigData.Json format error {e.Message}"); - } - } - /// - /// 初始化ProcessConfig - /// - /// - public static void Initialize(List list) - { - Instance = new ProcessConfigData - { - List = list - }; - foreach (var config in Instance.List) - { - Instance._configs.TryAdd(config.Id, config); - } - } - /// - /// 根据Id获取ProcessConfig - /// - /// - /// - /// - public ProcessConfig Get(uint id) - { - if (_configs.TryGetValue(id, out var processConfigInfo)) - { - return processConfigInfo; - } - - throw new FileNotFoundException($"MachineConfig not find {id} Id"); - } - /// - /// 根据Id获取ProcessConfig - /// - /// - /// - /// - public bool TryGet(uint id, out ProcessConfig config) - { - return _configs.TryGetValue(id, out config); - } - /// - /// 按照startupGroup寻找属于startupGroup组的ProcessConfig - /// - /// startupGroup - /// - public IEnumerable ForEachByStartupGroup(uint startupGroup) - { - foreach (var processConfig in List) - { - if (processConfig.StartupGroup == startupGroup) - { - yield return processConfig; - } - } - } - } - /// - /// 表示一个进程配置信息 - /// - public sealed class ProcessConfig - { - /// - /// 进程Id - /// - public uint Id { get; set; } - /// - /// 机器ID - /// - public uint MachineId { get; set; } - /// - /// 启动组 - /// - public uint StartupGroup { get; set; } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/SceneConfig.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/SceneConfig.cs deleted file mode 100644 index 14f8a1a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/SceneConfig.cs +++ /dev/null @@ -1,216 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using System.Runtime.Serialization; -using Fantasy.DataStructure.Collection; -using Fantasy.DataStructure.Dictionary; -using Fantasy.Helper; -using Fantasy.IdFactory; -using Newtonsoft.Json; -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8601 // Possible null reference assignment. - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Net -{ - /// - /// 存放所有SceneConfigInfo信息 - /// - public sealed class SceneConfigData - { - /// - /// 存放所有SceneConfig信息 - /// - public List List; - [JsonIgnore] - [IgnoreDataMember] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); - [JsonIgnore] - [IgnoreDataMember] - private readonly OneToManyList _sceneConfigBySceneType = new OneToManyList(); - [JsonIgnore] - [IgnoreDataMember] - private readonly OneToManyList _sceneConfigByProcess = new OneToManyList(); - [JsonIgnore] [IgnoreDataMember] - private readonly Dictionary>> _worldSceneTypes = new Dictionary>>(); - /// - /// 获得SceneConfigData的实例 - /// - public static SceneConfigData Instance { get; private set; } - /// - /// 初始化SceneConfig - /// - /// - public static void Initialize(string sceneConfigJson) - { - try - { - Instance = sceneConfigJson.Deserialize(); - Initialize(); - } - catch (Exception e) - { - throw new InvalidOperationException($"SceneConfigData.Json format error {e.Message}"); - } - } - /// - /// 初始化SceneConfig - /// - public static void Initialize(List sceneConfigs) - { - Instance = new SceneConfigData() { List = sceneConfigs }; - Initialize(); - } - - private static void Initialize() - { - foreach (var config in Instance.List) - { - config.Initialize(); - Instance._configs.TryAdd(config.Id, config); - Instance._sceneConfigByProcess.Add(config.ProcessConfigId, config); - Instance._sceneConfigBySceneType.Add(config.SceneType, config); - - var configWorldConfigId = (int)config.WorldConfigId; - - if (!Instance._worldSceneTypes.TryGetValue(configWorldConfigId, out var sceneConfigDic)) - { - sceneConfigDic = new Dictionary>(); - Instance._worldSceneTypes.Add(configWorldConfigId, sceneConfigDic); - } - - if (!sceneConfigDic.TryGetValue(config.SceneType, out var sceneConfigList)) - { - sceneConfigList = new List(); - sceneConfigDic.Add(config.SceneType, sceneConfigList); - } - - sceneConfigList.Add(config); - } - } - - /// - /// 根据Id获取SceneConfig - /// - /// - /// - /// - public SceneConfig Get(uint id) - { - if (_configs.TryGetValue(id, out var sceneConfigInfo)) - { - return sceneConfigInfo; - } - - throw new FileNotFoundException($"WorldConfig not find {id} Id"); - } - - /// - /// 根据Id获取SceneConfig - /// - /// - /// - /// - public bool TryGet(uint id, out SceneConfig config) - { - return _configs.TryGetValue(id, out config); - } - - /// - /// 获得SceneConfig - /// - /// - /// - public List GetByProcess(uint serverConfigId) - { - return _sceneConfigByProcess.TryGetValue(serverConfigId, out var list) ? list : new List(); - } - - /// - /// 获得SceneConfig - /// - /// - /// - public List GetSceneBySceneType(int sceneType) - { - return !_sceneConfigBySceneType.TryGetValue(sceneType, out var list) ? new List() : list; - } - - /// - /// 获得SceneConfig - /// - /// - /// - /// - public List GetSceneBySceneType(int world, int sceneType) - { - if (!_worldSceneTypes.TryGetValue(world, out var sceneConfigDic)) - { - return new List(); - } - - if (!sceneConfigDic.TryGetValue(sceneType, out var list)) - { - return new List(); - } - - return list; - } - } - - /// - /// 表示一个Scene配置信息 - /// - public sealed class SceneConfig - { - /// - /// ID - /// - public uint Id { get; set; } - /// - /// 进程Id - /// - public uint ProcessConfigId { get; set; } - /// - /// 世界Id - /// - public uint WorldConfigId { get; set; } - /// - /// Scene运行类型 - /// - public string SceneRuntimeMode { get; set; } - /// - /// Scene类型 - /// - public string SceneTypeString { get; set; } - /// - /// 协议类型 - /// - public string NetworkProtocol { get; set; } - /// - /// 外网端口 - /// - public int OuterPort { get; set; } - /// - /// 内网端口 - /// - public int InnerPort { get; set; } - /// - /// Scene类型 - /// - public int SceneType { get; set; } - /// - /// RouteId - /// - [JsonIgnore] - [IgnoreDataMember] - public long RouteId { get; private set; } - /// - /// 初始化方法 - /// - public void Initialize() - { - RouteId = IdFactoryHelper.RuntimeId(0, Id, (byte)WorldConfigId, 0); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/WorldConfig.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/WorldConfig.cs deleted file mode 100644 index 30ff6bb..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ConfigTable/WorldConfig.cs +++ /dev/null @@ -1,115 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using System.Runtime.Serialization; -using Fantasy.Helper; -using Newtonsoft.Json; -#pragma warning disable CS8601 // Possible null reference assignment. - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Net -{ - /// - /// 存放所有WorldConfigInfo信息 - /// - public sealed class WorldConfigData - { - /// - /// 存放所有WorldConfigInfo信息 - /// - public List List; - [JsonIgnore] - [IgnoreDataMember] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); - /// - /// 获得WorldConfig的实例 - /// - public static WorldConfigData Instance { get; private set; } - /// - /// 初始化WorldConfig - /// - /// - public static void Initialize(string worldConfigJson) - { - try - { - Instance = worldConfigJson.Deserialize(); - foreach (var config in Instance.List) - { - Instance._configs.TryAdd(config.Id, config); - } - } - catch (Exception e) - { - throw new InvalidOperationException($"WorldConfigData.Json format error {e.Message}"); - } - } - /// - /// 初始化WorldConfig - /// - /// - public static void Initialize(List list) - { - Instance = new WorldConfigData - { - List = list - }; - foreach (var config in Instance.List) - { - Instance._configs.TryAdd(config.Id, config); - } - } - /// - /// 根据Id获取WorldConfig - /// - /// - /// - /// - public WorldConfig Get(uint id) - { - if (_configs.TryGetValue(id, out var worldConfigInfo)) - { - return worldConfigInfo; - } - - throw new FileNotFoundException($"WorldConfig not find {id} Id"); - } - /// - /// 根据Id获取WorldConfig - /// - /// - /// - /// - public bool TryGet(uint id, out WorldConfig config) - { - return _configs.TryGetValue(id, out config); - } - } - - /// - /// 表示一个世界配置信息 - /// - public sealed class WorldConfig - { - /// - /// Id - /// - public uint Id { get; set; } - /// - /// 名称 - /// - public string WorldName { get; set; } - /// - /// 数据库连接字符串 - /// - public string DbConnection { get; set; } - /// - /// 数据库名称 - /// - public string DbName { get; set; } - /// - /// 数据库类型 - /// - public string DbType { get; set; } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/Entry.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/Entry.cs deleted file mode 100644 index dff5316..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/Entry.cs +++ /dev/null @@ -1,141 +0,0 @@ -#if FANTASY_NET -using CommandLine; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Network; -using Fantasy.Serialize; -// ReSharper disable FunctionNeverReturns - -namespace Fantasy.Platform.Net; - -/// -/// Fantasy.Net 应用程序入口 -/// -/// 当命令行格式异常时抛出。 -/// 不支持的 ProcessType 类型异常。 -public static class Entry -{ - /// - /// 框架初始化 - /// - /// 日志实例 - /// 注册的Assembly - /// - public static async FTask Initialize(ILog? log, params System.Reflection.Assembly[] assemblies) - { - // 注册日志模块到框架 - if (log != null) - { - Log.Register(log); - } - Log.Info($"Fantasy Version:{ProgramDefine.VERSION}"); - // 加载Fantasy.config配置文件 - await ConfigLoader.InitializeFromXml(Path.Combine(AppContext.BaseDirectory, "Fantasy.config")); - // 解析命令行参数 - Parser.Default.ParseArguments(Environment.GetCommandLineArgs()) - .WithNotParsed(error => throw new Exception("Command line format error!")) - .WithParsed(option => - { - ProgramDefine.ProcessId = option.ProcessId; - ProgramDefine.ProcessType = option.ProcessType; - ProgramDefine.RuntimeMode = Enum.Parse(option.RuntimeMode); - ProgramDefine.StartupGroup = option.StartupGroup; - }); - // 初始化Log系统 - Log.Initialize(); - // 检查启动参数,后期可能有机器人等不同的启动参数 - switch (ProgramDefine.ProcessType) - { - case "Game": - { - break; - } - default: - { - throw new NotSupportedException($"ProcessType is {ProgramDefine.ProcessType} Unrecognized!"); - } - } - // 初始化程序集管理系统 - await AssemblySystem.InnerInitialize(assemblies); - // 初始化序列化 - SerializerManager.Initialize(); - // 精度处理(只针对Windows下有作用、其他系统没有这个问题、一般也不会用Windows来做服务器的) - WinPeriod.Initialize(); - } - - /// - /// 框架初始化 - /// - /// 注册的Assembly - public static FTask Initialize(params System.Reflection.Assembly[] assemblies) - { - return Initialize(null, assemblies); - } - - /// - /// 启动Fantasy.Net - /// - public static async FTask Start() - { - // 启动Process - StartProcess().Coroutine(); - await FTask.CompletedTask; - while (true) - { - ThreadScheduler.Update(); - Thread.Sleep(1); - } - } - - /// - /// 初始化并且启动框架 - /// - /// - public static async FTask Start(params System.Reflection.Assembly[] assemblies) - { - await Initialize(assemblies); - await Start(); - } - - private static async FTask StartProcess() - { - if (ProgramDefine.StartupGroup != 0) - { - foreach (var processConfig in ProcessConfigData.Instance.ForEachByStartupGroup((uint)ProgramDefine.StartupGroup)) - { - await Process.Create(processConfig.Id); - } - - return; - } - - switch (ProgramDefine.RuntimeMode) - { - case ProcessMode.Develop: - { - foreach (var processConfig in ProcessConfigData.Instance.List) - { - await Process.Create(processConfig.Id); - } - - return; - } - case ProcessMode.Release: - { - await Process.Create(ProgramDefine.ProcessId); - return; - } - } - } - - /// - /// 关闭 Fantasy - /// - public static void Close() - { - AssemblySystem.Dispose(); - SerializerManager.Dispose(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/Process.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/Process.cs deleted file mode 100644 index e3a6cf8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/Process.cs +++ /dev/null @@ -1,156 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using Fantasy.Async; -using Fantasy.IdFactory; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8601 // Possible null reference assignment. -namespace Fantasy.Platform.Net; - -/// -/// 一个进程的实例 -/// -public sealed class Process : IDisposable -{ - /// - /// 当前进程的Id - /// - public readonly uint Id; - /// - /// 进程关联的MachineId - /// - public readonly uint MachineId; - private readonly ConcurrentDictionary _processScenes = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary Scenes = new ConcurrentDictionary(); - private Process() {} - private Process(uint id, uint machineId) - { - Id = id; - MachineId = machineId; - } - - internal bool IsProcess(ref long routeId) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - return _processScenes.ContainsKey(sceneId); - } - - internal bool IsProcess(ref uint sceneId) - { - return _processScenes.ContainsKey(sceneId); - } - - internal void AddSceneToProcess(Scene scene) - { - _processScenes.TryAdd(scene.SceneConfigId, scene); - } - - internal void RemoveSceneToProcess(Scene scene, bool isDispose) - { - if (!_processScenes.Remove(scene.SceneConfigId, out _)) - { - return; - } - - if (isDispose) - { - scene.Dispose(); - } - } - - internal bool TryGetSceneToProcess(long routeId, out Scene scene) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - return _processScenes.TryGetValue(sceneId, out scene); - } - - internal bool TryGetSceneToProcess(uint sceneId, out Scene scene) - { - return _processScenes.TryGetValue(sceneId, out scene); - } - /// - /// 销毁方法 - /// - public void Dispose() - { - if (_processScenes.IsEmpty) - { - return; - } - - var sceneQueue = new Queue(); - - foreach (var (_, scene) in _processScenes) - { - sceneQueue.Enqueue(scene); - } - - while (sceneQueue.TryDequeue(out var removeScene)) - { - removeScene.Dispose(); - } - - _processScenes.Clear(); - } - - internal static async FTask Create(uint processConfigId) - { - if (!ProcessConfigData.Instance.TryGet(processConfigId, out var processConfig)) - { - Log.Error($"not found processConfig by Id:{processConfigId}"); - return null; - } - - if (!MachineConfigData.Instance.TryGet(processConfig.MachineId, out var machineConfig)) - { - Log.Error($"not found machineConfig by Id:{processConfig.MachineId}"); - return null; - } - - var process = new Process(processConfigId, processConfig.MachineId); - var sceneConfigs = SceneConfigData.Instance.GetByProcess(processConfigId); - - foreach (var sceneConfig in sceneConfigs) - { - await Scene.Create(process, machineConfig, sceneConfig); - } - - Log.Info($"Process:{processConfigId} Startup Complete SceneCount:{sceneConfigs.Count}"); - return process; - } - - internal bool IsInAppliaction(ref uint sceneId) - { - return _processScenes.ContainsKey(sceneId); - } - - internal static void AddScene(Scene scene) - { - Scenes.TryAdd(scene.SceneConfigId, scene); - } - - internal static void RemoveScene(Scene scene, bool isDispose) - { - if (!Scenes.Remove(scene.SceneConfigId, out _)) - { - return; - } - - if (isDispose) - { - scene.Dispose(); - } - } - - internal static bool TryGetScene(long routeId, out Scene scene) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - return Scenes.TryGetValue(sceneId, out scene); - } - - internal static bool TryGetScene(uint sceneId, out Scene scene) - { - return Scenes.TryGetValue(sceneId, out scene); - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ProcessDefine.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ProcessDefine.cs deleted file mode 100644 index 51732db..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ProcessDefine.cs +++ /dev/null @@ -1,52 +0,0 @@ -#if FANTASY_NET -using CommandLine; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Net; - -/// -/// Process运行模式 -/// -public enum ProcessMode -{ - /// - /// 默认 - /// - None =0, - /// - /// 开发模式 - /// - Develop = 1, - /// - /// 发布模式 - /// - Release = 2 -} - -internal sealed class CommandLineOptions -{ - /// - /// 用于启动指定的进程,该进程的 ID 与 ProcessConfig 的 ID 相关联。此参数只能传递单个 ID,不支持传递多个 ID。 - /// - [Option("pid", Required = false, Default = (uint)0, HelpText = "Enter an ProcessIdId such as 1")] - public uint ProcessId { get; set; } - /// - /// Process类型,获取或设置应用程序的类型。 - /// Game - 游戏服务器Process - /// Robot - 机器人(暂未支持该功能) - /// - [Option('a', "ProcessType", Required = false, Default = "Game", HelpText = "Game")] - public string ProcessType { get; set; } - /// - /// 服务器运行模式,获取或设置服务器的运行模式。 - /// Develop - 开发模式(启动Process配置表中的所有Process) - /// Release - 发布模式(根据ProcessId启动Process) - /// - [Option('m', "RuntimeMode", Required = true, Default = "Release", HelpText = "Develop:启动Process配置表中的所有Process,\nRelease:根据ProcessId启动Process")] - public string RuntimeMode { get; set; } - /// - /// 启动组。 - /// - [Option('g', "StartupGroup", Required = false, Default = 0, HelpText = "Used to start a group of Process")] - public int StartupGroup { get; set; } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ThreadSynchronizationContext.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ThreadSynchronizationContext.cs deleted file mode 100644 index bb2948a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Net/ThreadSynchronizationContext.cs +++ /dev/null @@ -1,52 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -#pragma warning disable CS8765 -#pragma warning disable CS8601 -#pragma warning disable CS8618 - -namespace Fantasy; - -/// -/// 线程的同步上下文 -/// -public sealed class ThreadSynchronizationContext : SynchronizationContext -{ - private readonly ConcurrentQueue _queue = new(); - /// - /// 执行当前上下文投递过的逻辑 - /// - public void Update() - { - while (_queue.TryDequeue(out var actionHandler)) - { - try - { - actionHandler(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - /// - /// 投递一个逻辑到当前上下文 - /// - /// - /// - public override void Post(SendOrPostCallback callback, object state) - { - Post(() => callback(state)); - } - - /// - /// 投递一个逻辑到当前上下文 - /// - /// - public void Post(Action action) - { - _queue.Enqueue(action); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/ProgramDefine.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/ProgramDefine.cs deleted file mode 100644 index 7e7299d..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/ProgramDefine.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -#if FANTASY_NET -using Fantasy.Network; -using Fantasy.Platform.Net; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. -#endif - -namespace Fantasy -{ - /// - /// 程序定义 - /// - public static class ProgramDefine - { - /// - /// Fantasy版本。 - /// - public const string VERSION = "Fantasy 2.0 Beta"; - /// - /// 消息体最大长度(字节)。默认1024k。 - /// 注意:前后端设置的消息大小,一定要一样才可以,不然会不出现问题。 - /// - public static int MaxMessageSize { get; set; } = ushort.MaxValue * 16; -#if FANTASY_NET - /// - /// App程序Id。 - /// - public static uint ProcessId { get; internal set; } - /// - /// 应用程序的类型。 - /// - public static string ProcessType { get; internal set; } - /// - /// 服务器运行模式,获取或设置服务器的运行模式。 - /// - public static ProcessMode RuntimeMode { get; internal set; } - /// - /// 服务器启动组 - /// - public static int StartupGroup { get; internal set; } - /// - /// 会话空闲检查超时时间。 - /// - public static int SessionIdleCheckerTimeout { get; internal set; } - /// - /// 会话空闲检查间隔。 - /// - public static int SessionIdleCheckerInterval { get; internal set; } - /// - /// 内部网络通讯协议类型。 - /// - public static NetworkProtocolType InnerNetwork { get; internal set; } -#endif - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/AppDefine.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/AppDefine.cs deleted file mode 100644 index d9d85ae..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/AppDefine.cs +++ /dev/null @@ -1,19 +0,0 @@ -#if FANTASY_UNITY -namespace Fantasy.Platform.Unity -{ - public static class AppDefine - { - public static string RemoteUpdatePath; - public static bool EditorModel = true; - public const string VersionName = "version.bytes"; - public const string VersionMD5Name = "version.md5"; - public const string AssetBundleManifestName = "Fantasy"; - public static bool IsEditor => UnityEngine.Application.isEditor && EditorModel; - public static string AssetBundleSaveDirectory => "Assets/AssetBundles"; - public static string LocalAssetBundlePath => UnityEngine.Application.streamingAssetsPath; - public static string RemoteAssetBundlePath => UnityEngine.Application.persistentDataPath; - public static string PersistentDataVersion => $"{UnityEngine.Application.persistentDataPath}/{VersionName}"; - public static string StreamingAssetsVersion => $"{UnityEngine.Application.streamingAssetsPath}/{VersionName}"; - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonDefaultValueAttribute.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonDefaultValueAttribute.cs deleted file mode 100644 index 49914ec..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonDefaultValueAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] - public class BsonDefaultValueAttribute : Attribute - { - public BsonDefaultValueAttribute(object defaultValue) { } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonElementAttribute.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonElementAttribute.cs deleted file mode 100644 index 3892727..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonElementAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] - public class BsonElementAttribute : Attribute - { - public BsonElementAttribute() { } - - public BsonElementAttribute(string elementName) { } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIdAttribute.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIdAttribute.cs deleted file mode 100644 index 48274d0..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIdAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public class BsonIdAttribute : Attribute - { - - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreAttribute.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreAttribute.cs deleted file mode 100644 index 23e55c8..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] - public class BsonIgnoreAttribute : Attribute - { - - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfDefaultAttribute.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfDefaultAttribute.cs deleted file mode 100644 index 82dddde..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfDefaultAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] - public class BsonIgnoreIfDefaultAttribute : Attribute - { - public BsonIgnoreIfDefaultAttribute() { } - - public BsonIgnoreIfDefaultAttribute(bool value) { } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfNullAttribute.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfNullAttribute.cs deleted file mode 100644 index f330a8b..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfNullAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public class BsonIgnoreIfNullAttribute : Attribute - { - - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Entry.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Entry.cs deleted file mode 100644 index f0fa9e6..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Entry.cs +++ /dev/null @@ -1,110 +0,0 @@ -#if FANTASY_UNITY -using System; -using System.Linq; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.Serialize; -using UnityEngine; -using UnityEngine.Scripting; - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Platform.Unity -{ - public sealed class FantasyObject : MonoBehaviour - { - public static GameObject FantasyObjectGameObject { get; private set; } - - public static void OnRuntimeMethodLoad() - { - FantasyObjectGameObject = new GameObject("Fantasy.Net"); - DontDestroyOnLoad(FantasyObjectGameObject); - } - private void OnApplicationQuit() - { - Destroy(FantasyObjectGameObject); - } - } - - public struct OnSceneCreate - { - public Scene Scene; - public object Arg; - } - - public class Entry : MonoBehaviour - { - private static bool _isInit; - public static Scene Scene { get; private set; } - - /// - /// 初始化框架 - /// - /// - public static async FTask Initialize(params System.Reflection.Assembly[] assemblies) - { - if (_isInit) - { - Log.Error("Fantasy has already been initialized and does not need to be initialized again!"); - return; - } - FantasyObject.OnRuntimeMethodLoad(); - Log.Register(new UnityLog()); - ProgramDefine.MaxMessageSize = ushort.MaxValue * 16; - Log.Info($"Fantasy Version:{ProgramDefine.VERSION}"); - await AssemblySystem.InnerInitialize(assemblies); - // 初始化序列化 - SerializerManager.Initialize(); -#if FANTASY_WEBGL - ThreadSynchronizationContext.Initialize(); -#endif - _isInit = true; - FantasyObject.FantasyObjectGameObject.AddComponent(); - Log.Debug("Fantasy Initialize Complete!"); - } - - /// - /// 在Entry中创建一个Scene,如果Scene已经被创建过,将先销毁Scene再创建。 - /// - /// - /// - /// - public static async FTask CreateScene(object arg = null, string sceneRuntimeMode = SceneRuntimeMode.MainThread) - { - Scene?.Dispose(); - Scene = await Scene.Create(sceneRuntimeMode); - await Scene.EventComponent.PublishAsync(new OnSceneCreate() - { - Arg = arg, - Scene = Scene - }); - return Scene; - } - - private void Update() - { - ThreadScheduler.Update(); - } - - private void LateUpdate() - { - ThreadScheduler.LateUpdate(); - } - - private void OnDestroy() - { - AssemblySystem.Dispose(); - SerializerManager.Dispose(); - if (Scene != null) - { - Scene?.Dispose(); - Scene = null; - } - _isInit = false; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Temp.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Temp.cs deleted file mode 100644 index 399488f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/Temp.cs +++ /dev/null @@ -1,108 +0,0 @@ -// using System.Reflection; -// using Fantasy.Assembly; -// using Fantasy.Async; -// // using UnityEngine; -// #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// #pragma warning disable CS8603 // Possible null reference return. -// #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -// #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -// -// namespace Fantasy.Platform.Unity -// { -// public class MonoBehaviour -// { -// -// } -// -// public class GameObject -// { -// public GameObject(string name) -// { -// -// } -// } -// -// internal enum RuntimeInitializeLoadType -// { -// BeforeSceneLoad = 1, -// } -// -// internal class RuntimeInitializeOnLoadMethodAttribute : Attribute -// { -// public RuntimeInitializeLoadType RuntimeInitializeLoadType; -// -// public RuntimeInitializeOnLoadMethodAttribute(RuntimeInitializeLoadType loadType) -// { -// -// } -// } -// -// public sealed class FantasyObject : MonoBehaviour -// { -// public static GameObject FantasyObjectGameObject { get; private set; } -// // 这个方法将在游戏启动时自动调用 -// [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] -// static void OnRuntimeMethodLoad() -// { -// FantasyObjectGameObject = new GameObject("Fantasy.Net"); -// // DontDestroyOnLoad(FantasyObjectGameObject); -// } -// private void OnApplicationQuit() -// { -// // Destroy(FantasyObjectGameObject); -// } -// } -// -// public struct OnFantasyInit -// { -// public Scene Scene; -// } -// -// public class Entry : MonoBehaviour -// { -// private static bool _isInit; -// public static Scene Scene { get; private set; } -// /// -// /// 初始化框架 -// /// -// public static async FTask Initialize(params System.Reflection.Assembly[] assemblies) -// { -// Scene?.Dispose(); -// // 初始化程序集管理系统 -// AssemblySystem.Initialize(assemblies); -// if (!_isInit) -// { -// #if FANTASY_WEBGL -// ThreadSynchronizationContext.Initialize(); -// #endif -// _isInit = true; -// // FantasyObject.FantasyObjectGameObject.AddComponent(); -// } -// // Scene = await Scene.Create(SceneRuntimeType.MainThread); -// // await Scene.EventComponent.PublishAsync(new OnFantasyInit() -// // { -// // Scene = Scene -// // }); -// // return Scene; -// await FTask.CompletedTask; -// return null; -// } -// -// private void Update() -// { -// ThreadScheduler.Update(); -// } -// -// private void OnDestroy() -// { -// AssemblySystem.Dispose(); -// if (Scene != null) -// { -// Scene?.Dispose(); -// Scene = null; -// } -// _isInit = false; -// } -// } -// } diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/ThreadSynchronizationContext.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/ThreadSynchronizationContext.cs deleted file mode 100644 index 44b165a..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Platform/Unity/ThreadSynchronizationContext.cs +++ /dev/null @@ -1,104 +0,0 @@ -#if FANTASY_UNITY && !FANTASY_WEBGL -#pragma warning disable CS8765 -#pragma warning disable CS8601 -#pragma warning disable CS8618 -using System; -using System.Collections.Concurrent; -using System.Threading; - -namespace Fantasy -{ - public sealed class ThreadSynchronizationContext : SynchronizationContext - { - private Action _actionHandler; - private readonly ConcurrentQueue _queue = new(); - - public void Update() - { - while (_queue.TryDequeue(out _actionHandler)) - { - try - { - _actionHandler(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void Post(SendOrPostCallback callback, object state) - { - Post(() => callback(state)); - } - - public void Post(Action action) - { - _queue.Enqueue(action); - } - } -} -#endif -#if FANTASY_UNITY && FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Threading; -using Fantasy; -using UnityEngine; -using Object = UnityEngine.Object; - -public class WebGLSynchronizationContextUpdater : MonoBehaviour -{ - private ThreadSynchronizationContext _context; - - public void Initialize(ThreadSynchronizationContext context) - { - _context = context; - } - - void Update() - { - _context.Update(); - } -} -public sealed class ThreadSynchronizationContext : SynchronizationContext -{ - private Action _actionHandler; - private readonly Queue _queue = new(); - - public static void Initialize() - { - var context = new ThreadSynchronizationContext(); - SetSynchronizationContext(context); - var go = new GameObject("WebGLSynchronizationContextUpdater"); - go.AddComponent().Initialize(context); - Object.DontDestroyOnLoad(go); - } - - public void Update() - { - while (_queue.TryDequeue(out _actionHandler)) - { - try - { - _actionHandler(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void Post(SendOrPostCallback callback, object state) - { - Post(() => callback(state)); - } - - public void Post(Action action) - { - _queue.Enqueue(action); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Concurrent/MultiThreadPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Concurrent/MultiThreadPool.cs deleted file mode 100644 index 4c946d1..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Concurrent/MultiThreadPool.cs +++ /dev/null @@ -1,37 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Concurrent; -using System.Runtime.CompilerServices; -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Pool -{ - /// - /// 线程安全的静态通用对象池。 - /// - internal static class MultiThreadPool - { - private static readonly ConcurrentDictionary ObjectPools = new ConcurrentDictionary(); - - public static T Rent() where T : IPool, new() - { - return ObjectPools.GetOrAdd(typeof(T), t => new MultiThreadPoolQueue(2000, () => new T())).Rent(); - } - - public static IPool Rent(Type type) - { - return ObjectPools.GetOrAdd(type, t => new MultiThreadPoolQueue(2000, CreateInstance.CreateIPool(type))).Rent(); - } - - public static void Return(T obj) where T : IPool, new() - { - if (!obj.IsPool()) - { - return; - } - - ObjectPools.GetOrAdd(typeof(T), t => new MultiThreadPoolQueue(2000, () => new T())).Return(obj); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Concurrent/MultiThreadPoolQueue.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Concurrent/MultiThreadPoolQueue.cs deleted file mode 100644 index df15a1c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Concurrent/MultiThreadPoolQueue.cs +++ /dev/null @@ -1,76 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Concurrent; -using System.Threading; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Pool -{ - /// - /// 线程安全的对象池。 - /// - internal class MultiThreadPoolQueue - { - private int _poolCount; - private readonly int _maxCapacity; - private readonly Func _createInstance; - private readonly ConcurrentQueue _poolQueue = new ConcurrentQueue(); - private MultiThreadPoolQueue() { } - - public MultiThreadPoolQueue(int maxCapacity, Func createInstance) - { - _maxCapacity = maxCapacity; - _createInstance = createInstance; - } - - public T Rent() where T : IPool, new() - { - if (!_poolQueue.TryDequeue(out var t)) - { - var pool = new T(); - pool.SetIsPool(true); - return pool; - } - - t.SetIsPool(true); - Interlocked.Decrement(ref _poolCount); - return (T)t; - } - - public IPool Rent() - { - if (!_poolQueue.TryDequeue(out var t)) - { - var instance = _createInstance(); - instance.SetIsPool(true); - return instance; - } - - t.SetIsPool(true); - Interlocked.Decrement(ref _poolCount); - return t; - } - - public void Return(IPool obj) - { - if (!obj.IsPool()) - { - return; - } - - obj.SetIsPool(false); - - if (Interlocked.Increment(ref _poolCount) <= _maxCapacity) - { - _poolQueue.Enqueue(obj); - return; - } - - Interlocked.Decrement(ref _poolCount); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Interface/IPool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Interface/IPool.cs deleted file mode 100644 index 1775f28..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Interface/IPool.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Fantasy.Pool -{ - /// - /// 实现了这个接口代表支持对象池 - /// - public interface IPool - { - /// - /// 是否从池里创建的 - /// - bool IsPool(); - /// - /// 设置是否从池里创建的 - /// - /// - void SetIsPool(bool isPool); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Normal/Pool.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Normal/Pool.cs deleted file mode 100644 index 88006e1..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Normal/Pool.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable CheckNamespace - -namespace Fantasy.Pool -{ - /// - /// 静态的对象池系统,不支持多线程。 - /// - /// - public static class Pool where T : IPool, new() - { - private static readonly Queue PoolQueue = new Queue(); - /// - /// 池子里可用的数量 - /// - public static int Count => PoolQueue.Count; - - /// - /// 租借 - /// - /// - public static T Rent() - { - return PoolQueue.Count == 0 ? new T() : PoolQueue.Dequeue(); - } - - /// - /// 租借 - /// - /// 如果池子里没有,会先执行这个委托。 - /// - public static T Rent(Func generator) - { - return PoolQueue.Count == 0 ? generator() : PoolQueue.Dequeue(); - } - - /// - /// 返还 - /// - /// - public static void Return(T t) - { - if (t == null) - { - return; - } - - PoolQueue.Enqueue(t); - } - - /// - /// 返还 - /// - /// 返还的东西 - /// 返还后执行的委托 - public static void Return(T t, Action reset) - { - if (t == null) - { - return; - } - - reset(t); - PoolQueue.Enqueue(t); - } - - /// - /// 清空池子 - /// - public static void Clear() - { - PoolQueue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Normal/PoolCore.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Normal/PoolCore.cs deleted file mode 100644 index 94144f1..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Normal/PoolCore.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using Fantasy.DataStructure.Collection; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Pool -{ - /// - /// 对象池抽象接口,用于创建和管理可重复使用的对象实例。 - /// - public abstract class PoolCore : IDisposable - { - private int _poolCount; - private readonly int _maxCapacity; - /// - /// 池子里可用的数量 - /// - public int Count => _poolQueue.Count; - private readonly OneToManyQueue _poolQueue = new OneToManyQueue(); - private readonly Dictionary> _typeCheckCache = new Dictionary>(); - - /// - /// 构造函数 - /// - /// 初始的容量 - protected PoolCore(int maxCapacity) - { - _maxCapacity = maxCapacity; - } - - /// - /// 租借 - /// - /// - /// - public T Rent() where T : IPool, new() - { - if (!_poolQueue.TryDequeue(typeof(T), out var queue)) - { - queue = new T(); - } - - queue.SetIsPool(true); - _poolCount--; - return (T)queue; - } - - /// - /// 租借 - /// - /// 租借的类型 - /// - /// - public IPool Rent(Type type) - { - if (!_poolQueue.TryDequeue(type, out var queue)) - { - if (!_typeCheckCache.TryGetValue(type, out var createInstance)) - { - if (!typeof(IPool).IsAssignableFrom(type)) - { - throw new NotSupportedException($"{this.GetType().FullName} Type:{type.FullName} must inherit from IPool"); - } - else - { - createInstance = CreateInstance.CreateIPool(type); - _typeCheckCache[type] = createInstance; - } - } - - var instance = createInstance(); - instance.SetIsPool(true); - return instance; - } - - queue.SetIsPool(true); - _poolCount--; - return queue; - } - - /// - /// 返还 - /// - /// - /// - public void Return(Type type, IPool obj) - { - if (obj == null) - { - return; - } - - if (!obj.IsPool()) - { - return; - } - - if (_poolCount >= _maxCapacity) - { - return; - } - - _poolCount++; - obj.SetIsPool(false); - _poolQueue.Enqueue(type, obj); - } - - /// - /// 销毁方法 - /// - public virtual void Dispose() - { - _poolCount = 0; - _poolQueue.Clear(); - _typeCheckCache.Clear(); - } - } - - /// - /// 泛型对象池核心类,用于创建和管理可重复使用的对象实例。 - /// - /// 要池化的对象类型 - public abstract class PoolCore where T : IPool, new() - { - private int _poolCount; - private readonly int _maxCapacity; - private readonly Queue _poolQueue = new Queue(); - /// - /// 池子里可用的数量 - /// - public int Count => _poolQueue.Count; - - /// - /// 构造函数 - /// - /// 初始的容量 - protected PoolCore(int maxCapacity) - { - _maxCapacity = maxCapacity; - } - - /// - /// 租借 - /// - /// - public virtual T Rent() - { - T dequeue; - - if (_poolQueue.Count == 0) - { - dequeue = new T(); - } - else - { - _poolCount--; - dequeue = _poolQueue.Dequeue(); - } - - dequeue.SetIsPool(true); - return dequeue; - } - - /// - /// 返还 - /// - /// - public virtual void Return(T item) - { - if (item == null) - { - return; - } - - if (!item.IsPool()) - { - return; - } - - if (_poolCount >= _maxCapacity) - { - return; - } - - _poolCount++; - item.SetIsPool(false); - _poolQueue.Enqueue(item); - } - - /// - /// 销毁方法 - /// - public virtual void Dispose() - { - _poolCount = 0; - _poolQueue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Normal/PoolWithDisposable.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Normal/PoolWithDisposable.cs deleted file mode 100644 index 3f97f1c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/Normal/PoolWithDisposable.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections.Generic; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -namespace Fantasy.Pool -{ - /// - /// 静态通用对象池,用于存储实现了 IDisposable 接口的对象。 - /// - /// 要存储在对象池中的对象类型,必须实现 IDisposable 接口。 - public abstract class PoolWithDisposable : IDisposable where T : IPool, IDisposable, new() - { - private int _poolCount; - private readonly int _maxCapacity; - private readonly Queue _poolQueue = new Queue(); - /// - /// 池子里可用的数量 - /// - public int Count => _poolQueue.Count; - - /// - /// 构造函数 - /// - /// 初始的容量 - protected PoolWithDisposable(int maxCapacity) - { - _maxCapacity = maxCapacity; - } - - /// - /// 租借 - /// - /// - public T Rent() - { - T dequeue; - if (_poolQueue.Count == 0) - { - dequeue = new T(); - } - else - { - _poolCount--; - dequeue = _poolQueue.Dequeue(); - } - - dequeue.SetIsPool(true); - return dequeue; - } - - /// - /// 租借 - /// - /// - /// - public T Rent(Func generator) - { - T dequeue; - - if (_poolQueue.Count == 0) - { - dequeue = generator(); - } - else - { - _poolCount--; - dequeue = _poolQueue.Dequeue(); - } - - dequeue.SetIsPool(true); - return dequeue; - } - - /// - /// 返还 - /// - /// - public void Return(T t) - { - if (t == null) - { - return; - } - - if (!t.IsPool()) - { - return; - } - - if (_poolCount >= _maxCapacity) - { - return; - } - - _poolCount++; - t.SetIsPool(true); - _poolQueue.Enqueue(t); - t.Dispose(); - } - - /// - /// 返还 - /// - /// - /// - public void Return(T t, Action reset) - { - if (t == null) - { - return; - } - - if (!t.IsPool()) - { - reset(t); - return; - } - - if (_poolCount >= _maxCapacity) - { - return; - } - - reset(t); - _poolCount++; - t.SetIsPool(false); - _poolQueue.Enqueue(t); - t.Dispose(); - } - - /// - /// 销毁方法 - /// - public virtual void Dispose() - { - _poolCount = 0; - _poolQueue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/PoolHelper.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/PoolHelper.cs deleted file mode 100644 index d9214fd..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Pool/PoolHelper.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Reflection.Emit; -using Fantasy.Serialize; - -#pragma warning disable CS8604 // Possible null reference argument. - -namespace Fantasy.Pool -{ - internal static class CreateInstance where T : IPool - { - public static Func Create { get; } - - static CreateInstance() - { - var type = typeof(T); - var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - var il = dynamicMethod.GetILGenerator(); - il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - il.Emit(OpCodes.Ret); - Create = (Func) dynamicMethod.CreateDelegate(typeof(Func)); - } - } - - internal static class CreateInstance - { - public static Func CreateIPool(Type type) - { - var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - var il = dynamicMethod.GetILGenerator(); - il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - il.Emit(OpCodes.Ret); - return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - } - - public static Func CreateObject(Type type) - { - var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - var il = dynamicMethod.GetILGenerator(); - il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - il.Emit(OpCodes.Ret); - return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - } - - public static Func CreateMessage(Type type) - { - var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - var il = dynamicMethod.GetILGenerator(); - il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - il.Emit(OpCodes.Ret); - return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - } - } - - // public static class CreateInstance - // { - // public static Func Create(Type type) - // { - // var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - // var il = dynamicMethod.GetILGenerator(); - // il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - // il.Emit(OpCodes.Ret); - // return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - // } - // } - - // /// - // /// 利用泛型的特性来减少反射的使用。 - // /// - // /// - // public static class PoolChecker where T : new() - // { - // public static bool IsPool { get; } - // - // static PoolChecker() - // { - // IsPool = typeof(IPool).IsAssignableFrom(typeof(T)); - // } - // } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/ISceneUpdate.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/ISceneUpdate.cs deleted file mode 100644 index f83aec7..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/ISceneUpdate.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace Fantasy -{ - internal interface ISceneUpdate - { - void Update(); - } - - internal sealed class EmptySceneUpdate : ISceneUpdate - { - public void Update() - { - - } - } - -#if FANTASY_UNITY - internal interface ISceneLateUpdate - { - void LateUpdate(); - } - - internal sealed class EmptySceneLateUpdate : ISceneLateUpdate - { - public void LateUpdate() - { - - } - } -#endif - -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scene.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scene.cs deleted file mode 100644 index 15ced7e..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scene.cs +++ /dev/null @@ -1,645 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Event; -using Fantasy.IdFactory; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Pool; -using Fantasy.Scheduler; -using Fantasy.Timer; -#if FANTASY_NET -using Fantasy.DataBase; -using Fantasy.Platform.Net; -using Fantasy.SingleCollection; -using System.Runtime.CompilerServices; -using Fantasy.Network.Route; -using Fantasy.Network.Roaming; -#endif -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -namespace Fantasy -{ - /// - /// 当Scene创建完成后发送的事件参数 - /// - public struct OnCreateScene - { - /// - /// 获取与事件关联的场景实体。 - /// - public readonly Scene Scene; - /// - /// 初始化一个新的 OnCreateScene 实例。 - /// - /// - public OnCreateScene(Scene scene) - { - Scene = scene; - } - } - - /// - /// 表示一个场景实体,用于创建与管理特定的游戏场景信息。 - /// - public partial class Scene : Entity - { - #region Members - /// - /// Scene的运行类型 - /// - public SceneRuntimeType SceneRuntimeType { get; protected set; } -#if FANTASY_NET - /// - /// Scene类型,对应SceneConfig的SceneType - /// - public int SceneType { get; protected set; } - /// - /// 所属的世界 - /// - public World World { get; protected set; } - /// - /// 所在的Process - /// - public Process Process { get; protected set; } - /// - /// SceneConfig的Id - /// - public uint SceneConfigId { get; protected set; } - internal ANetwork InnerNetwork { get; private set; } - internal ANetwork OuterNetwork { get; private set; } - internal SceneConfig SceneConfig => SceneConfigData.Instance.Get(SceneConfigId); - private readonly Dictionary _processSessionInfos = new Dictionary(); -#endif - /// - /// 当前Scene的上下文 - /// - public ThreadSynchronizationContext ThreadSynchronizationContext { get; internal set; } - /// - /// 当前Scene的下创建的Entity - /// - private readonly Dictionary _entities = new Dictionary(); - internal readonly Dictionary> TypeInstance = new Dictionary>(); - #endregion - - #region IdFactory - - /// - /// Entity实体Id的生成器 - /// - public IEntityIdFactory EntityIdFactory { get; protected set; } - /// - /// Entity实体RuntimeId的生成器 - /// - public IRuntimeIdFactory RuntimeIdFactory { get; protected set; } - - #endregion - - #region Pool - - internal EntityPool EntityPool; - internal EntityListPool EntityListPool; - internal EntitySortedDictionaryPool EntitySortedDictionaryPool; - - #endregion - - #region Component - - /// - /// Scene下的任务调度器系统组件 - /// - public TimerComponent TimerComponent { get; internal set; } - /// - /// Scene下的事件系统组件 - /// - public EventComponent EventComponent { get; internal set; } - /// - /// Scene下的ESC系统组件 - /// - public EntityComponent EntityComponent { get; internal set; } - /// - /// Scene下的网络消息对象池组件 - /// - public MessagePoolComponent MessagePoolComponent { get; internal set; } - /// - /// Scene下的协程锁组件 - /// - public CoroutineLockComponent CoroutineLockComponent { get; internal set; } - /// - /// Scene下的网络消息派发组件 - /// - internal MessageDispatcherComponent MessageDispatcherComponent { get; set; } -#if FANTASY_NET - /// - /// Scene下的Entity分表组件 - /// - public SingleCollectionComponent SingleCollectionComponent { get; internal set; } - /// - /// Scene下的内网消息发送组件 - /// - public NetworkMessagingComponent NetworkMessagingComponent { get; internal set; } - /// - /// Scene下的漫游终端管理组件 - /// - public TerminusComponent TerminusComponent { get; internal set; } - /// - /// Scene下的Session漫游组件 - /// - public RoamingComponent RoamingComponent { get; internal set; } -#endif - #endregion - - #region Initialize - - private async FTask Initialize() - { - EntityPool = new EntityPool(); - EntityListPool = new EntityListPool(); - EntitySortedDictionaryPool = new EntitySortedDictionaryPool(); - EntityComponent = await Create(this, false, false).Initialize(); - SceneUpdate = EntityComponent; -#if FANTASY_UNITY - SceneLateUpdate = EntityComponent; -#endif - MessagePoolComponent = Create(this,false,true); - EventComponent = await Create(this,false,true).Initialize(); - TimerComponent = Create(this, false, true).Initialize(); - CoroutineLockComponent = Create(this, false, true).Initialize(); - MessageDispatcherComponent = await Create(this, false, true).Initialize(); -#if FANTASY_NET - NetworkMessagingComponent = Create(this, false, true); - SingleCollectionComponent = await Create(this, false, true).Initialize(); - TerminusComponent = Create(this, false, true); - RoamingComponent = Create(this, false, true).Initialize(); -#endif - } - - /// - /// Scene销毁方法,执行了该方法会把当前Scene下的所有实体都销毁掉。 - /// - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - base.Dispose(); - _entities.Remove(RuntimeId); - - switch (SceneRuntimeType) - { - case SceneRuntimeType.Root: - { -#if FANTASY_NET - foreach (var (_, processSessionInfo) in _processSessionInfos.ToList()) - { - processSessionInfo.Dispose(); - } - - _processSessionInfos.Clear(); -#endif - _entities.Remove(EntityComponent.RuntimeId); - - foreach (var (runtimeId, entity) in _entities.ToList()) - { - if (runtimeId != entity.RuntimeId) - { - continue; - } - entity.Dispose(); - } - - _entities.Clear(); -#if FANTASY_UNITY - _unityWorldId--; - _unitySceneId--; -#endif - TypeInstance.Clear(); -#if FANTASY_NET - Process.RemoveScene(this, false); - Process.RemoveSceneToProcess(this, false); -#endif - EntityComponent.Dispose(); - EntityPool.Dispose(); - EntityListPool.Dispose(); - EntitySortedDictionaryPool.Dispose(); - break; - } - case SceneRuntimeType.SubScene: - { - break; - } - default: - { - Log.Error($"SceneRuntimeType: {SceneRuntimeType} The unsupported SceneRuntimeType of the Scene executed Dispose."); - break; - } - } - - SceneUpdate = null; - EntityIdFactory = null; - RuntimeIdFactory = null; - - EntityPool = null; - EntityListPool = null; - EntitySortedDictionaryPool = null; - EntityComponent = null; - TimerComponent = null; - EventComponent = null; - MessagePoolComponent = null; - CoroutineLockComponent = null; - MessageDispatcherComponent = null; -#if FANTASY_NET - World = null; - Process = null; - SceneType = 0; - SceneConfigId = 0; - SingleCollectionComponent = null; - NetworkMessagingComponent = null; - TerminusComponent = null; - RoamingComponent = null; -#elif FANTASY_UNITY - Session = null; - UnityNetwork = null; - SceneLateUpdate = null; -#endif - ThreadSynchronizationContext = null; - SceneRuntimeType = SceneRuntimeType.None; - } - - #endregion - - internal ISceneUpdate SceneUpdate { get; set; } - internal void Update() - { - try - { - SceneUpdate.Update(); - } - catch (Exception e) - { - Log.Error(e); - } - } -#if FANTASY_UNITY - internal ISceneLateUpdate SceneLateUpdate { get; set; } - internal void LateUpdate() - { - try - { - SceneLateUpdate.LateUpdate(); - } - catch (Exception e) - { - Log.Error(e); - } - } -#endif - #region Create - -#if FANTASY_UNITY || FANTASY_CONSOLE - private static uint _unitySceneId = 0; - private static byte _unityWorldId = 0; - public Session Session { get; private set; } - private AClientNetwork UnityNetwork { get; set; } - /// - /// 创建一个Unity的Scene,注意:该方法只能在主线程下使用。 - /// - /// 选择Scene的运行方式 - /// - /// - public static async FTask Create(string sceneRuntimeMode = SceneRuntimeMode.MainThread) - { - var world = ++_unityWorldId; - - if (world > byte.MaxValue - 1) - { - throw new Exception($"World ID ({world}) exceeds the maximum allowed value of 255."); - } - - var sceneId = (uint)(++_unitySceneId + world * 1000); - - if (sceneId > 255255) - { - throw new Exception($"Scene ID ({sceneId}) exceeds the maximum allowed value of 255255."); - } - - var scene = new Scene(); - scene.Scene = scene; - scene.Parent = scene; - scene.Type = typeof(Scene); - scene.SceneRuntimeType = SceneRuntimeType.Root; - scene.EntityIdFactory = IdFactoryHelper.EntityIdFactory(sceneId, world); - scene.RuntimeIdFactory = IdFactoryHelper.RuntimeIdFactory(0, sceneId, world); - scene.Id = IdFactoryHelper.EntityId(0, sceneId, world, 0); - scene.RuntimeId = IdFactoryHelper.RuntimeId(0, sceneId, world, 0); - scene.AddEntity(scene); - await SetScheduler(scene, sceneRuntimeMode); - scene.ThreadSynchronizationContext.Post(() => - { - scene.EventComponent.PublishAsync(new OnCreateScene(scene)).Coroutine(); - }); - return scene; - } - public Session Connect(string remoteAddress, NetworkProtocolType networkProtocolType, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - UnityNetwork?.Dispose(); - UnityNetwork = NetworkProtocolFactory.CreateClient(this, networkProtocolType, NetworkTarget.Outer); - Session = UnityNetwork.Connect(remoteAddress, onConnectComplete, onConnectFail, onConnectDisconnect, isHttps, connectTimeout); - return Session; - } -#endif -#if FANTASY_NET - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Scene Create(Process process, byte worldId, uint sceneConfigId) - { - var scene = new Scene(); - scene.Scene = scene; - scene.Parent = scene; - scene.Type = typeof(Scene); - scene.Process = process; - scene.SceneRuntimeType = SceneRuntimeType.Root; - scene.EntityIdFactory = IdFactoryHelper.EntityIdFactory(sceneConfigId, worldId); - scene.RuntimeIdFactory = IdFactoryHelper.RuntimeIdFactory(0,sceneConfigId, worldId); - scene.Id = IdFactoryHelper.EntityId(0, sceneConfigId, worldId, 0); - scene.RuntimeId = IdFactoryHelper.RuntimeId(0, sceneConfigId, worldId, 0); - scene.AddEntity(scene); - return scene; - } - /// - /// 创建一个新的Scene - /// - /// 所属的Process - /// 对应的MachineConfig配置文件 - /// 对应的SceneConfig配置文件 - /// 创建成功后会返回创建的Scene的实例 - public static async FTask Create(Process process, MachineConfig machineConfig, SceneConfig sceneConfig) - { - var scene = Create(process, (byte)sceneConfig.WorldConfigId, sceneConfig.Id); - scene.SceneType = sceneConfig.SceneType; - scene.SceneConfigId = sceneConfig.Id; - await SetScheduler(scene, sceneConfig.SceneRuntimeMode); - - if (sceneConfig.WorldConfigId != 0) - { - scene.World = World.Create(scene, (byte)sceneConfig.WorldConfigId); - } - - if (sceneConfig.InnerPort != 0) - { - // 创建内网网络服务器 - scene.InnerNetwork = NetworkProtocolFactory.CreateServer(scene, ProgramDefine.InnerNetwork, NetworkTarget.Inner, machineConfig.InnerBindIP, sceneConfig.InnerPort); - } - - if (sceneConfig.OuterPort != 0) - { - // 创建外网网络服务 - var networkProtocolType = Enum.Parse(sceneConfig.NetworkProtocol); - scene.OuterNetwork = NetworkProtocolFactory.CreateServer(scene, networkProtocolType, NetworkTarget.Outer, machineConfig.OuterBindIP, sceneConfig.OuterPort); - } - - Process.AddScene(scene); - process.AddSceneToProcess(scene); - - scene.ThreadSynchronizationContext.Post(() => - { - if (sceneConfig.SceneTypeString == "Addressable") - { - // 如果是AddressableScene,自动添加上AddressableManageComponent。 - scene.AddComponent(); - } - - scene.EventComponent.PublishAsync(new OnCreateScene(scene)).Coroutine(); - }); - - return scene; - } - /// - /// 在Scene下面创建一个子Scene,一般用于副本,或者一些特殊的场景。 - /// - /// 主Scene的实例 - /// SceneType,可以在SceneType里找到,例如:SceneType.Addressable - /// 子Scene创建成功后执行的委托,可以传递null - /// - public static SubScene CreateSubScene(Scene parentScene, int sceneType, Action onSubSceneComplete = null) - { - var scene = new SubScene(); - scene.Scene = scene; - scene.Parent = scene; - scene.RootScene = parentScene; - scene.Type = typeof(SubScene); - scene.SceneType = sceneType; - scene.World = parentScene.World; - scene.Process = parentScene.Process; - scene.SceneRuntimeType = SceneRuntimeType.SubScene; - scene.EntityIdFactory = parentScene.EntityIdFactory; - scene.RuntimeIdFactory = parentScene.RuntimeIdFactory; - scene.Id = scene.EntityIdFactory.Create; - scene.RuntimeId = scene.RuntimeIdFactory.Create; - scene.AddEntity(scene); - scene.Initialize(parentScene); - scene.ThreadSynchronizationContext.Post(() => OnEvent().Coroutine()); - return scene; - async FTask OnEvent() - { - await scene.EventComponent.PublishAsync(new OnCreateScene(scene)); - onSubSceneComplete?.Invoke(scene, parentScene); - } - } -#endif - private static async FTask SetScheduler(Scene scene, string sceneRuntimeMode) - { - switch (sceneRuntimeMode) - { - case "MainThread": - { - scene.ThreadSynchronizationContext = ThreadScheduler.MainScheduler.ThreadSynchronizationContext; - scene.SceneUpdate = new EmptySceneUpdate(); -#if FANTASY_UNITY - scene.SceneLateUpdate = new EmptySceneLateUpdate(); -#endif - ThreadScheduler.AddMainScheduler(scene); - await scene.Initialize(); - break; - } - case "MultiThread": - { -#if !FANTASY_WEBGL - scene.ThreadSynchronizationContext = new ThreadSynchronizationContext(); -#endif - scene.SceneUpdate = new EmptySceneUpdate(); -#if FANTASY_UNITY - scene.SceneLateUpdate = new EmptySceneLateUpdate(); -#endif - ThreadScheduler.AddToMultiThreadScheduler(scene); - await scene.Initialize(); - break; - } - case "ThreadPool": - { -#if !FANTASY_WEBGL - scene.ThreadSynchronizationContext = new ThreadSynchronizationContext(); -#endif - scene.SceneUpdate = new EmptySceneUpdate(); -#if FANTASY_UNITY - scene.SceneLateUpdate = new EmptySceneLateUpdate(); -#endif - ThreadScheduler.AddToThreadPoolScheduler(scene); - await scene.Initialize(); - break; - } - } - } - #endregion - - #region Entities - - /// - /// 添加一个实体到当前Scene下 - /// - /// 实体实例 - public virtual void AddEntity(Entity entity) - { - _entities.Add(entity.RuntimeId, entity); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 返回的实体 - public virtual Entity GetEntity(long runTimeId) - { - return _entities.TryGetValue(runTimeId, out var entity) ? entity : null; - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 实体实例 - /// 返回一个bool值来提示是否查找到这个实体 - public virtual bool TryGetEntity(long runTimeId, out Entity entity) - { - return _entities.TryGetValue(runTimeId, out entity); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 要查询实体的泛型类型 - /// 返回的实体 - public virtual T GetEntity(long runTimeId) where T : Entity - { - return _entities.TryGetValue(runTimeId, out var entity) ? (T)entity : null; - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 实体实例 - /// 要查询实体的泛型类型 - /// 返回一个bool值来提示是否查找到这个实体 - public virtual bool TryGetEntity(long runTimeId, out T entity) where T : Entity - { - if (_entities.TryGetValue(runTimeId, out var getEntity)) - { - entity = (T)getEntity; - return true; - } - - entity = null; - return false; - } - - /// - /// 删除一个实体,仅是删除不会指定实体的销毁方法 - /// - /// 实体的RunTimeId - /// 返回一个bool值来提示是否删除了这个实体 - public virtual bool RemoveEntity(long runTimeId) - { - return _entities.Remove(runTimeId); - } - - /// - /// 删除一个实体,仅是删除不会指定实体的销毁方法 - /// - /// 实体实例 - /// 返回一个bool值来提示是否删除了这个实体 - public virtual bool RemoveEntity(Entity entity) - { - return _entities.Remove(entity.RuntimeId); - } - - #endregion - - #region InnerSession - -#if FANTASY_NET - /// - /// 根据runTimeId获得Session - /// - /// - /// - /// - internal virtual Session GetSession(long runTimeId) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref runTimeId); - - if (_processSessionInfos.TryGetValue(sceneId, out var processSessionInfo)) - { - if (!processSessionInfo.Session.IsDisposed) - { - return processSessionInfo.Session; - } - - _processSessionInfos.Remove(sceneId); - } - - if (Process.IsInAppliaction(ref sceneId)) - { - // 如果在同一个Process下,不需要通过Socket发送了,直接通过Process下转发。 - var processSession = Session.CreateInnerSession(Scene); - _processSessionInfos.Add(sceneId, new ProcessSessionInfo(processSession, null)); - return processSession; - } - - if (!SceneConfigData.Instance.TryGet(sceneId, out var sceneConfig)) - { - throw new Exception($"The scene with sceneId {sceneId} was not found in the configuration file"); - } - - if (!ProcessConfigData.Instance.TryGet(sceneConfig.ProcessConfigId, out var processConfig)) - { - throw new Exception($"The process with processId {sceneConfig.ProcessConfigId} was not found in the configuration file"); - } - - if (!MachineConfigData.Instance.TryGet(processConfig.MachineId, out var machineConfig)) - { - throw new Exception($"The machine with machineId {processConfig.MachineId} was not found in the configuration file"); - } - - var remoteAddress = $"{machineConfig.InnerBindIP}:{sceneConfig.InnerPort}"; - var client = NetworkProtocolFactory.CreateClient(Scene, ProgramDefine.InnerNetwork, NetworkTarget.Inner); - var session = client.Connect(remoteAddress, null, () => - { - Log.Error($"Unable to connect to the target server sourceServerId:{Scene.Process.Id} targetServerId:{sceneConfig.ProcessConfigId}"); - }, null, false); - _processSessionInfos.Add(sceneId, new ProcessSessionInfo(session, client)); - return session; - } -#endif - #endregion - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/SceneRuntimeMode.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/SceneRuntimeMode.cs deleted file mode 100644 index 60dbc85..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/SceneRuntimeMode.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Fantasy -{ - /// - /// Scene的运行类型 - /// - public class SceneRuntimeMode - { - /// - /// Scene在主线程中运行. - /// - public const string MainThread = "MainThread"; - /// - /// Scene在一个独立的线程中运行. - /// - public const string MultiThread = "MultiThread"; - /// - /// Scene在一个根据当前CPU核心数创建的线程池中运行. - /// - public const string ThreadPool = "ThreadPool"; - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/SceneRuntimeType.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/SceneRuntimeType.cs deleted file mode 100644 index 664107f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/SceneRuntimeType.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Fantasy -{ - /// - /// 代表一个Scene的类型 - /// - public enum SceneRuntimeType - { - /// - /// 默认 - /// - None = 0, - /// - /// 代表一个普通的Scene,一个普通的Scene肯定是是Root的 - /// - Root = 1, - /// - /// 代表一个子场景,子场景肯定是有父场景的 - /// - SubScene = 2, - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/ISceneScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/ISceneScheduler.cs deleted file mode 100644 index c04cc30..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/ISceneScheduler.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Fantasy -{ - internal interface ISceneScheduler : IDisposable - { - void Add(Scene scene); - void Remove(Scene scene); - void Update(); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/MainScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/MainScheduler.cs deleted file mode 100644 index 4db5ee9..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/MainScheduler.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Collections.Generic; -#if FANTASY_UNITY || FANTASY_NET || !FANTASY_WEBGL -using System.Threading; -#endif -#if FANTASY_NET -using Fantasy.Platform.Net; -#endif -namespace Fantasy -{ - internal sealed class MainScheduler : ISceneScheduler - { - private readonly Queue _queue = new Queue(); - public readonly ThreadSynchronizationContext ThreadSynchronizationContext; - - public MainScheduler() - { - ThreadSynchronizationContext = new ThreadSynchronizationContext(); -#if !FANTASY_WEBGL || !UNITY_EDITOR - SynchronizationContext.SetSynchronizationContext(ThreadSynchronizationContext); -#endif - } - public void Dispose() - { - _queue.Clear(); - } - - public void Add(Scene scene) - { - ThreadSynchronizationContext.Post(() => - { - if (scene.IsDisposed) - { - return; - } - - _queue.Enqueue(scene); - }); - } - - public void Remove(Scene scene) - { - ThreadSynchronizationContext.Post(() => - { - if (scene.IsDisposed) - { - return; - } - - var initialCount = _queue.Count; - for (var i = 0; i < initialCount; i++) - { - var currentScene = _queue.Dequeue(); - if (currentScene != scene) - { - _queue.Enqueue(currentScene); - } - } - }); - } - - public void Update() - { - ThreadSynchronizationContext.Update(); - var initialCount = _queue.Count; - - while (initialCount-- > 0) - { - if(!_queue.TryDequeue(out var scene)) - { - continue; - } - - if (scene.IsDisposed) - { - continue; - } - - scene.Update(); - _queue.Enqueue(scene); - } - } -#if FANTASY_UNITY - public void LateUpdate() - { - var initialCount = _queue.Count; - - while (initialCount-- > 0) - { - if(!_queue.TryDequeue(out var scene)) - { - continue; - } - - if (scene.IsDisposed) - { - continue; - } - - scene.LateUpdate(); - _queue.Enqueue(scene); - } - } -#endif - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/MultiThreadScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/MultiThreadScheduler.cs deleted file mode 100644 index 28f2d42..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/MultiThreadScheduler.cs +++ /dev/null @@ -1,103 +0,0 @@ -#if !FANTASY_WEBGL || !FANTASY_SINGLETHREAD -using System; -using System.Collections.Concurrent; -using System.Threading; -namespace Fantasy -{ - internal struct MultiThreadStruct : IDisposable - { - public readonly Thread Thread; - public readonly CancellationTokenSource Cts; - - public MultiThreadStruct(Thread thread, CancellationTokenSource cts) - { - Thread = thread; - Cts = cts; - } - - public void Dispose() - { - Cts.Cancel(); - if (Thread.IsAlive) - { - Thread.Join(); - } - Cts.Dispose(); - } - } - - internal sealed class MultiThreadScheduler : ISceneScheduler - { - private bool _isDisposed; - private readonly ConcurrentDictionary _threads = new ConcurrentDictionary(); - public int ThreadCount => _threads.Count; - - public void Dispose() - { - if (_isDisposed) - { - return; - } - - _isDisposed = true; - - foreach (var (_, multiThreadStruct) in _threads.ToArray()) - { - multiThreadStruct.Dispose(); - } - - _threads.Clear(); - } - - public void Add(Scene scene) - { - var cts = new CancellationTokenSource(); - var thread = new Thread(() => Loop(scene, cts.Token)); - _threads.TryAdd(scene.RuntimeId, new MultiThreadStruct(thread, cts)); - thread.Start(); - } - - public void Remove(Scene scene) - { - if (_threads.TryRemove(scene.RuntimeId, out var multiThreadStruct)) - { - multiThreadStruct.Dispose(); - } - } - - public void Update() - { - throw new NotImplementedException(); - } - - private void Loop(Scene scene, CancellationToken cancellationToken) - { - var sceneThreadSynchronizationContext = scene.ThreadSynchronizationContext; - SynchronizationContext.SetSynchronizationContext(sceneThreadSynchronizationContext); - - while (!cancellationToken.IsCancellationRequested) - { - try - { - if (scene.IsDisposed) - { - Remove(scene); - return; - } - - sceneThreadSynchronizationContext.Update(); - scene.Update(); - } - catch (Exception e) - { - Log.Error($"Error in MultiThreadScheduler loop: {e.Message}"); - } - finally - { - Thread.Sleep(1); - } - } - } - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/ThreadPoolScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/ThreadPoolScheduler.cs deleted file mode 100644 index d8353f5..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/ThreadPoolScheduler.cs +++ /dev/null @@ -1,138 +0,0 @@ -#if !FANTASY_WEBGL || !FANTASY_SINGLETHREAD -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8604 // Possible null reference argument. -namespace Fantasy -{ - internal sealed class ThreadPoolScheduler : ISceneScheduler - { - private bool _isDisposed; - private readonly List _threads; - private readonly ConcurrentQueue _queue = new ConcurrentQueue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - public ThreadPoolScheduler() - { - // 最大线程数、避免线程过多发生的资源抢占问题。 - // 但如果使用了MultiThreadScheduler,那么这里的线程数就算是设置了也有可能导致线程过多的问题。 - // 线程过多看每个线程的抢占情况,如果抢占资源占用不是很大也没什么大问题。如果过大的情况,就会有性能问题。 - // 所以根据情况来使用不同的调度器。 - var maxThreadCount = Environment.ProcessorCount; - _threads = new List(maxThreadCount); - - for (var i = 0; i < maxThreadCount; ++i) - { - Thread thread = new(() => Loop(_cancellationTokenSource.Token)) - { - IsBackground = true - }; - _threads.Add(thread); - thread.Start(); - } - } - - public void Dispose() - { - if (_isDisposed) - { - return; - } - - _isDisposed = true; - _cancellationTokenSource.Cancel(); - - foreach (var thread in _threads) - { - if (thread.IsAlive) - { - thread.Join(); - } - } - - _cancellationTokenSource.Dispose(); - _threads.Clear(); - } - - public void Add(Scene scene) - { - if (_isDisposed) - { - return; - } - - _queue.Enqueue(scene); - } - - public void Remove(Scene scene) - { - if (_isDisposed) - { - return; - } - - var newQueue = new Queue(); - - while (_queue.TryDequeue(out var currentScene)) - { - if (currentScene == scene) - { - continue; - } - newQueue.Enqueue(currentScene); - } - - while (newQueue.TryDequeue(out var newScene)) - { - _queue.Enqueue(newScene); - } - } - - public void Update() - { - throw new NotImplementedException(); - } - - private void Loop(CancellationToken cancellationToken) - { - while (!cancellationToken.IsCancellationRequested) - { - if (_queue.TryDequeue(out var scene)) - { - if (scene == null || scene.IsDisposed) - { - continue; - } - - var sceneThreadSynchronizationContext = scene.ThreadSynchronizationContext; - SynchronizationContext.SetSynchronizationContext(sceneThreadSynchronizationContext); - - try - { - sceneThreadSynchronizationContext.Update(); - scene.Update(); - } - catch (Exception e) - { - Log.Error($"Error in ThreadPoolScheduler scene: {e.Message}"); - } - finally - { - SynchronizationContext.SetSynchronizationContext(null); - } - // 先停止线程后再如队列,避免同一个Scene多次重复执行 - Thread.Sleep(1); - _queue.Enqueue(scene); - } - else - { - // 当队列为空的时候、避免无效循环消耗CPU。 - Thread.Sleep(10); - } - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/ThreadScheduler.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/ThreadScheduler.cs deleted file mode 100644 index 9610581..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/Scheduler/ThreadScheduler.cs +++ /dev/null @@ -1,73 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy -{ - /// - /// 线程调度器 - /// - internal static class ThreadScheduler - { - /// - /// 主线程调度器 - /// - public static MainScheduler MainScheduler { get; private set; } - /// - /// 多线程调度器,根据当前CPU核心数量创建的固定线程。 - /// - public static ISceneScheduler MultiThreadScheduler { get; private set; } - /// - /// 线程池调度器 - /// - public static ISceneScheduler ThreadPoolScheduler { get; private set; } - - static ThreadScheduler() - { - MainScheduler = new MainScheduler(); - } - - internal static void Update() - { - MainScheduler.Update(); - } - -#if FANTASY_UNITY - internal static void LateUpdate() - { - MainScheduler.LateUpdate(); - } -#endif - - internal static void AddMainScheduler(Scene scene) - { - MainScheduler.Add(scene); - } - - internal static void AddToMultiThreadScheduler(Scene scene) - { - if (MultiThreadScheduler == null) - { -#if FANTASY_SINGLETHREAD || FANTASY_WEBGL - MultiThreadScheduler = MainScheduler; -#else - MultiThreadScheduler = new MultiThreadScheduler(); -#endif - } - - MultiThreadScheduler.Add(scene); - } - - internal static void AddToThreadPoolScheduler(Scene scene) - { - if (ThreadPoolScheduler == null) - { -#if FANTASY_SINGLETHREAD || FANTASY_WEBGL - ThreadPoolScheduler = MainScheduler; -#else - ThreadPoolScheduler = new ThreadPoolScheduler(); -#endif - } - - ThreadPoolScheduler.Add(scene); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/SubScene.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/SubScene.cs deleted file mode 100644 index a8c2e73..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Scene/SubScene.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Fantasy.Entitas; -using Fantasy.Network; -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -namespace Fantasy -{ - /// - /// 代表一个Scene下的子Scene - /// - public sealed partial class SubScene : Scene - { - /// - /// 子Scene的根Scene - /// - public Scene RootScene { get; internal set; } - /// - /// 存储当前Scene下管理的实体。 - /// - private readonly Dictionary _entities = new Dictionary(); - - internal void Initialize(Scene rootScene) - { - EntityPool = rootScene.EntityPool; - EntityListPool = rootScene.EntityListPool; - EntitySortedDictionaryPool = rootScene.EntitySortedDictionaryPool; - SceneUpdate = rootScene.SceneUpdate; -#if FANTASY_UNITY - SceneLateUpdate = rootScene.SceneLateUpdate; -#endif - TimerComponent = rootScene.TimerComponent; - EventComponent = rootScene.EventComponent; - EntityComponent = rootScene.EntityComponent; - MessagePoolComponent = rootScene.MessagePoolComponent; - CoroutineLockComponent = rootScene.CoroutineLockComponent; - MessageDispatcherComponent = rootScene.MessageDispatcherComponent; -#if FANTASY_NET - NetworkMessagingComponent = rootScene.NetworkMessagingComponent; - SingleCollectionComponent = rootScene.SingleCollectionComponent; - TerminusComponent = rootScene.TerminusComponent; -#endif - ThreadSynchronizationContext = rootScene.ThreadSynchronizationContext; - } - - /// - /// 当子Scene销毁时执行 - /// - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - ThreadSynchronizationContext.Post(() => - { - if (IsDisposed) - { - return; - } - - foreach (var (runtimeId, entity) in _entities.ToList()) - { - if (runtimeId != entity.RuntimeId) - { - continue; - } - entity.Dispose(); - } - - _entities.Clear(); - base.Dispose(); - }); - } - - /// - /// 添加一个实体到当前Scene下 - /// - /// 实体实例 - public override void AddEntity(Entity entity) - { - _entities.Add(entity.RuntimeId, entity); - RootScene.AddEntity(entity); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 返回的实体 - public override Entity GetEntity(long runTimeId) - { - return _entities.GetValueOrDefault(runTimeId); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 实体实例 - /// 返回一个bool值来提示是否查找到这个实体 - public override bool TryGetEntity(long runTimeId, out Entity entity) - { - return _entities.TryGetValue(runTimeId, out entity); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 要查询实体的泛型类型 - /// 返回的实体 - public override T GetEntity(long runTimeId) - { - return _entities.TryGetValue(runTimeId, out var entity) ? (T)entity : null; - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 实体实例 - /// 要查询实体的泛型类型 - /// 返回一个bool值来提示是否查找到这个实体 - public override bool TryGetEntity(long runTimeId, out T entity) - { - if (_entities.TryGetValue(runTimeId, out var getEntity)) - { - entity = (T)getEntity; - return true; - } - - entity = null; - return false; - } - - /// - /// 删除一个实体,仅是删除不会指定实体的销毁方法 - /// - /// 实体的RunTimeId - /// 返回一个bool值来提示是否删除了这个实体 - public override bool RemoveEntity(long runTimeId) - { - return _entities.Remove(runTimeId) && RootScene.RemoveEntity(runTimeId); - } - - /// - /// 删除一个实体,仅是删除不会指定实体的销毁方法 - /// - /// 实体实例 - /// 返回一个bool值来提示是否删除了这个实体 - public override bool RemoveEntity(Entity entity) - { - return RemoveEntity(entity.RuntimeId); - } - -#if FANTASY_NET - /// - /// 根据runTimeId获得Session - /// - /// - /// - /// - internal override Session GetSession(long runTimeId) - { - return RootScene.GetSession(runTimeId); - } - #endif - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/BsonPackHelperNet.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/BsonPackHelperNet.cs deleted file mode 100644 index cf97a8c..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/BsonPackHelperNet.cs +++ /dev/null @@ -1,311 +0,0 @@ -#if FANTASY_NET -using System.Buffers; -using System.Collections; -using System.ComponentModel; -using System.Reflection; -using Fantasy.Assembly; -using Fantasy.Entitas; -using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Conventions; -using MongoDB.Bson.Serialization.Serializers; -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. - -namespace Fantasy.Serialize -{ - /// - /// BSON帮助方法 - /// - public class BsonPackHelper : ISerialize - { - /// - /// 序列化器的名字 - /// - public string SerializeName { get; } = "Bson"; - - /// - /// 构造函数 - /// - public BsonPackHelper() - { - // 清除掉注册过的LookupClassMap。 - - var classMapRegistryField = typeof(BsonClassMap).GetField("__classMaps", BindingFlags.Static | BindingFlags.NonPublic); - - if (classMapRegistryField != null) - { - ((Dictionary)classMapRegistryField.GetValue(null)).Clear(); - } - - // 清除掉注册过的ConventionRegistry。 - - var registryField = typeof(ConventionRegistry).GetField("_lookup", BindingFlags.Static | BindingFlags.NonPublic); - - if (registryField != null) - { - var registry = registryField.GetValue(null); - var dictionaryField = registry.GetType().GetField("_conventions", BindingFlags.Instance | BindingFlags.NonPublic); - if (dictionaryField != null) - { - ((IDictionary)dictionaryField.GetValue(registry)).Clear(); - } - } - - // 初始化ConventionRegistry、注册IgnoreExtraElements。 - - ConventionRegistry.Register("IgnoreExtraElements", new ConventionPack { new IgnoreExtraElementsConvention(true) }, type => true); - - // 注册一个自定义的序列化器。 - - // BsonSerializer.TryRegisterSerializer(typeof(float2), new StructBsonSerialize()); - // BsonSerializer.TryRegisterSerializer(typeof(float3), new StructBsonSerialize()); - // BsonSerializer.TryRegisterSerializer(typeof(float4), new StructBsonSerialize()); - // BsonSerializer.TryRegisterSerializer(typeof(quaternion), new StructBsonSerialize()); - BsonSerializer.RegisterSerializer(new ObjectSerializer(x => true)); - - // 注册LookupClassMap。 - - foreach (var type in AssemblySystem.ForEach()) - { - if (type.IsInterface || type.IsAbstract || type.IsGenericType || !typeof(Entity).IsAssignableFrom(type)) - { - continue; - } - - BsonClassMap.LookupClassMap(type); - } - } - - /// - /// 反序列化 - /// - /// - /// - /// - public T Deserialize(byte[] bytes) - { - var @object = BsonSerializer.Deserialize(bytes); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - public T Deserialize(MemoryStreamBuffer buffer) - { - var @object = BsonSerializer.Deserialize(buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - public object Deserialize(Type type, byte[] bytes) - { - var @object = BsonSerializer.Deserialize(bytes, type); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - public object Deserialize(Type type, MemoryStreamBuffer buffer) - { - var @object = BsonSerializer.Deserialize(buffer, type); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - public unsafe T Deserialize(byte[] bytes, int index, int count) - { - T @object; - - fixed (byte* ptr = &bytes[index]) - { - using var stream = new UnmanagedMemoryStream(ptr, count); - @object = BsonSerializer.Deserialize(stream); - } - - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - public unsafe object Deserialize(Type type, byte[] bytes, int index, int count) - { - object @object; - - fixed (byte* ptr = &bytes[index]) - { - using var stream = new UnmanagedMemoryStream(ptr, count); - @object = BsonSerializer.Deserialize(stream, type); - } - - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 序列化 - /// - /// - /// - /// - public void Serialize(T @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using IBsonWriter bsonWriter = - new BsonBinaryWriter((MemoryStream)buffer, BsonBinaryWriterSettings.Defaults); - BsonSerializer.Serialize(bsonWriter, @object); - } - - /// - /// 序列化 - /// - /// - /// - public void Serialize(object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using IBsonWriter bsonWriter = - new BsonBinaryWriter((MemoryStream)buffer, BsonBinaryWriterSettings.Defaults); - BsonSerializer.Serialize(bsonWriter, @object.GetType(), @object); - } - - /// - /// 序列化 - /// - /// - /// - /// - public void Serialize(Type type, object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using IBsonWriter bsonWriter = - new BsonBinaryWriter((MemoryStream)buffer, BsonBinaryWriterSettings.Defaults); - BsonSerializer.Serialize(bsonWriter, type, @object); - } - - /// - /// 序列化并返回的长度 - /// - /// - /// - /// - /// - public int SerializeAndReturnLength(Type type, object @object, MemoryStreamBuffer buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using IBsonWriter bsonWriter = new BsonBinaryWriter(buffer, BsonBinaryWriterSettings.Defaults); - BsonSerializer.Serialize(bsonWriter, type, @object); - return (int)buffer.Length; - } - - /// - /// 序列化 - /// - /// - /// - public byte[] Serialize(object @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - return @object.ToBson(@object.GetType()); - } - - /// - /// 序列化 - /// - /// - /// - /// - public byte[] Serialize(T @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - return @object.ToBson(); - } - - /// - /// 克隆 - /// - /// - /// - /// - public T Clone(T t) - { - return Deserialize(Serialize(t)); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/BsonPackHelperUnity.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/BsonPackHelperUnity.cs deleted file mode 100644 index bfcc95f..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/BsonPackHelperUnity.cs +++ /dev/null @@ -1,70 +0,0 @@ -#if FANTASY_UNITY -using System; -using System.Buffers; -namespace Fantasy.Serialize -{ - public class BsonPackHelper : ISerialize - { - public string SerializeName { get; } = "Bson"; - public T Deserialize(byte[] bytes) - { - throw new NotImplementedException(); - } - - public T Deserialize(MemoryStreamBuffer buffer) - { - throw new NotImplementedException(); - } - - public object Deserialize(Type type, byte[] bytes) - { - throw new NotImplementedException(); - } - - public object Deserialize(Type type, MemoryStreamBuffer buffer) - { - throw new NotImplementedException(); - } - - public T Deserialize(byte[] bytes, int index, int count) - { - throw new NotImplementedException(); - } - - public object Deserialize(Type type, byte[] bytes, int index, int count) - { - throw new NotImplementedException(); - } - - public byte[] Serialize(object obj) - { - throw new NotImplementedException(); - } - - public byte[] Serialize(T @object) - { - throw new NotImplementedException(); - } - - public void Serialize(T @object, IBufferWriter buffer) - { - throw new NotImplementedException(); - } - - public void Serialize(object @object, IBufferWriter buffer) - { - throw new NotImplementedException(); - } - - public void Serialize(Type type, object @object, IBufferWriter buffer) - { - throw new NotImplementedException(); - } - - public T Clone(T t) - { - throw new NotImplementedException(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/StructBsonSerialize.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/StructBsonSerialize.cs deleted file mode 100644 index 15d8663..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/StructBsonSerialize.cs +++ /dev/null @@ -1,65 +0,0 @@ -#if FANTASY_NET -using System.Reflection; -using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Serializers; - -namespace Fantasy.Serialize; - -/// -/// 提供对结构体类型进行 BSON 序列化和反序列化的辅助类。 -/// -/// 要序列化和反序列化的结构体类型。 -public class StructBsonSerialize : StructSerializerBase where TValue : struct -{ - /// - /// 将结构体对象序列化为 BSON 数据。 - /// - /// 序列化上下文。 - /// 序列化参数。 - /// 要序列化的结构体对象。 - public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TValue value) - { - var nominalType = args.NominalType; - var bsonWriter = context.Writer; - bsonWriter.WriteStartDocument(); - var fields = nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - foreach (var field in fields) - { - bsonWriter.WriteName(field.Name); - BsonSerializer.Serialize(bsonWriter, field.FieldType, field.GetValue(value)); - } - bsonWriter.WriteEndDocument(); - } - - /// - /// 将 BSON 数据反序列化为结构体对象。 - /// - /// 反序列化上下文。 - /// 反序列化参数。 - /// 反序列化得到的结构体对象。 - public override TValue Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) - { - //boxing is required for SetValue to work - object obj = new TValue(); - var actualType = args.NominalType; - var bsonReader = context.Reader; - bsonReader.ReadStartDocument(); - while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) - { - var name = bsonReader.ReadName(Utf8NameDecoder.Instance); - - var field = actualType.GetField(name, - BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - if (field != null) - { - var value = BsonSerializer.Deserialize(bsonReader, field.FieldType); - field.SetValue(obj, value); - } - } - bsonReader.ReadEndDocument(); - return (TValue) obj; - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/SupportInitializeChecker.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/SupportInitializeChecker.cs deleted file mode 100644 index 82c6829..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/BsonPack/SupportInitializeChecker.cs +++ /dev/null @@ -1,17 +0,0 @@ -#if FANTASY_NET -using System.ComponentModel; -using Fantasy.Entitas; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Serialize; - -public static class SupportInitializeChecker where T : Entity -{ - public static bool IsSupported { get; } - - static SupportInitializeChecker() - { - IsSupported = typeof(ISupportInitialize).IsAssignableFrom(typeof(T)); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/Interface/ASerialize.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/Interface/ASerialize.cs deleted file mode 100644 index 7487b86..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/Interface/ASerialize.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.ComponentModel; -using System.Runtime.Serialization; -using Fantasy.Pool; -#if FANTASY_NET || FANTASY_UNITY || FANTASY_CONSOLE -using MongoDB.Bson.Serialization.Attributes; -#endif -using Newtonsoft.Json; -using ProtoBuf; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Serialize -{ - public abstract class ASerialize : ISupportInitialize, IDisposable - { - public virtual void Dispose() { } - public virtual void BeginInit() { } - public virtual void EndInit() { } - public virtual void AfterDeserialization() => EndInit(); - } - - public abstract class AMessage : ASerialize, IPool - { -#if FANTASY_NET || FANTASY_UNITY || FANTASY_CONSOLE - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - private Scene _scene; - protected Scene GetScene() - { - return _scene; - } - - public void SetScene(Scene scene) - { - _scene = scene; - } -#endif -#if FANTASY_NET - [BsonIgnore] -#endif - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - private bool _isPool; - - public bool IsPool() - { - return _isPool; - } - - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/Interface/ISerialize.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/Interface/ISerialize.cs deleted file mode 100644 index 3152f53..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/Interface/ISerialize.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Buffers; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Serialize -{ - public interface ISerialize - { - /// - /// 序列化器的名字,用于在协议里指定用什么协议序列化使用 - /// - string SerializeName { get; } - /// - /// 反序列化 - /// - /// - /// - /// - T Deserialize(byte[] bytes); - /// - /// 反序列化 - /// - /// - /// - /// - T Deserialize(MemoryStreamBuffer buffer); - /// - /// 反序列化 - /// - /// - /// - /// - object Deserialize(Type type, byte[] bytes); - /// - /// 反序列化 - /// - /// - /// - /// - object Deserialize(Type type, MemoryStreamBuffer buffer); - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - T Deserialize(byte[] bytes, int index, int count); - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - object Deserialize(Type type, byte[] bytes, int index, int count); - /// - /// 序列化 - /// - /// - /// - byte[] Serialize(object obj); - /// - /// 序列化 - /// - /// - /// - /// - byte[] Serialize(T @object); - /// - /// 序列化 - /// - /// - /// - /// - void Serialize(T @object, IBufferWriter buffer); - /// - /// 序列化 - /// - /// - /// - void Serialize(object @object, IBufferWriter buffer); - /// - /// 序列化 - /// - /// - /// - /// - void Serialize(Type type, object @object, IBufferWriter buffer); - /// - /// 克隆 - /// - /// - /// - /// - T Clone(T t); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/MemoryStreamBuffer.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/MemoryStreamBuffer.cs deleted file mode 100644 index 23919b4..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/MemoryStreamBuffer.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Serialize -{ - public enum MemoryStreamBufferSource - { - None = 0, - Pack = 1, - UnPack = 2, - } - - public sealed class MemoryStreamBuffer : MemoryStream, IBufferWriter - { - public MemoryStreamBufferSource MemoryStreamBufferSource; - public MemoryStreamBuffer() { } - - public MemoryStreamBuffer(MemoryStreamBufferSource memoryStreamBufferSource, int capacity) : base(capacity) - { - MemoryStreamBufferSource = memoryStreamBufferSource; - } - public MemoryStreamBuffer(byte[] buffer): base(buffer) { } - - public void Advance(int count) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), count, "The value of 'count' cannot be negative."); - } - - var newLength = Position + count; - - if (newLength != Length) - { - SetLength(newLength); - } - - Position = newLength; - } - - public Memory GetMemory(int sizeHint = 0) - { - if (sizeHint < 0) - { - throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint, "The value of 'count' cannot be negative."); - } - - if (Length - Position <= sizeHint) - { - SetLength(Position + sizeHint); - } - - return new Memory(GetBuffer(), (int)Position, (int)(Length - Position)); - } - - public Span GetSpan(int sizeHint = 0) - { - if (sizeHint < 0) - { - throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint, "The value of 'count' cannot be negative."); - } - - if (Length - Position <= sizeHint) - { - SetLength(Position + sizeHint); - } - - return new Span(GetBuffer(), (int)Position, (int)(Length - Position)); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/ProtoBufPackHelper/IProto.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/ProtoBufPackHelper/IProto.cs deleted file mode 100644 index 2267dd2..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/ProtoBufPackHelper/IProto.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Fantasy.Serialize -{ - /// - /// 代表是一个ProtoBuf协议 - /// - public interface IProto - { - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperNet.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperNet.cs deleted file mode 100644 index 5e28808..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperNet.cs +++ /dev/null @@ -1,234 +0,0 @@ -#if FANTASY_NET || FANTASY_EXPORTER -using System.Buffers; -using Fantasy.Assembly; -using ProtoBuf.Meta; -namespace Fantasy.Serialize -{ - /// - /// ProtoBufP帮助类,Net平台使用 - /// - public sealed class ProtoBufPackHelper : ISerialize - { - /// - /// 序列化器的名字 - /// - public string SerializeName { get; } = "ProtoBuf"; - - /// - /// 构造函数 - /// - public ProtoBufPackHelper () - { -#if FANTASY_NET - RuntimeTypeModel.Default.AutoAddMissingTypes = true; - RuntimeTypeModel.Default.AllowParseableTypes = true; - RuntimeTypeModel.Default.AutoAddMissingTypes = true; - RuntimeTypeModel.Default.AutoCompile = true; - RuntimeTypeModel.Default.UseImplicitZeroDefaults = true; - RuntimeTypeModel.Default.InferTagFromNameDefault = true; - - foreach (var type in AssemblySystem.ForEach(typeof(IProto))) - { - RuntimeTypeModel.Default.Add(type, true); - } - - RuntimeTypeModel.Default.CompileInPlace(); -#endif - } - - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public T Deserialize(byte[] bytes) - { - var memory = new ReadOnlyMemory(bytes); - var @object = RuntimeTypeModel.Default.Deserialize(memory); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public T Deserialize(MemoryStreamBuffer buffer) - { - var @object = RuntimeTypeModel.Default.Deserialize(buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public object Deserialize(Type type, byte[] bytes) - { - var memory = new ReadOnlyMemory(bytes); - var @object = RuntimeTypeModel.Default.Deserialize(type, memory); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public object Deserialize(Type type, MemoryStreamBuffer buffer) - { - var @object = RuntimeTypeModel.Default.Deserialize(type, buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - /// - /// - public T Deserialize(byte[] bytes, int index, int count) - { - var memory = new ReadOnlyMemory(bytes, index, count); - var @object = RuntimeTypeModel.Default.Deserialize(memory); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - /// - /// - public object Deserialize(Type type, byte[] bytes, int index, int count) - { - var memory = new ReadOnlyMemory(bytes, index, count); - var @object = RuntimeTypeModel.Default.Deserialize(type, memory); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - /// - public void Serialize(T @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize(buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - public void Serialize(object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize(buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - /// - public void Serialize(Type type, object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize(buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到byte[] - /// - /// - /// - public byte[] Serialize(object @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using (var buffer = new MemoryStream()) - { - RuntimeTypeModel.Default.Serialize(buffer, @object); - return buffer.ToArray(); - } - } - /// - /// 使用ProtoBuf序列化某一个实例到byte[] - /// - /// - /// - /// - public byte[] Serialize(T @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using (var buffer = new MemoryStream()) - { - RuntimeTypeModel.Default.Serialize(buffer, @object); - return buffer.ToArray(); - } - } - /// - /// 克隆 - /// - /// - /// - /// - public T Clone(T t) - { - return Deserialize(Serialize(t)); - } - } -} -#endif diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperUnity.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperUnity.cs deleted file mode 100644 index 0e386af..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperUnity.cs +++ /dev/null @@ -1,225 +0,0 @@ -#if FANTASY_UNITY || FANTASY_CONSOLE -using System; -using System.Buffers; -using System.IO; -using Fantasy.Assembly; -using ProtoBuf; -using ProtoBuf.Meta; - -namespace Fantasy.Serialize -{ - /// - /// ProtoBufP帮助类,Unity平台使用 - /// - public sealed class ProtoBufPackHelper : ISerialize - { - /// - /// 序列化器的名字 - /// - public string SerializeName { get; } = "ProtoBuf"; - - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public unsafe T Deserialize(byte[] bytes) - { - fixed (byte* ptr = bytes) - { - using var stream = new UnmanagedMemoryStream(ptr, bytes.Length); - var @object = ProtoBuf.Serializer.Deserialize(stream); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public T Deserialize(MemoryStreamBuffer buffer) - { - var @object = ProtoBuf.Serializer.Deserialize(buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public unsafe object Deserialize(Type type, byte[] bytes) - { - fixed (byte* ptr = bytes) - { - using var stream = new UnmanagedMemoryStream(ptr, bytes.Length); - var @object = ProtoBuf.Serializer.Deserialize(type, stream); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public object Deserialize(Type type, MemoryStreamBuffer buffer) - { - var @object = ProtoBuf.Serializer.Deserialize(type, buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - /// - /// - public unsafe T Deserialize(byte[] bytes, int index, int count) - { - fixed (byte* ptr = &bytes[index]) - { - using var stream = new UnmanagedMemoryStream(ptr, count); - var @object = ProtoBuf.Serializer.Deserialize(stream); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - /// - /// - public unsafe object Deserialize(Type type, byte[] bytes, int index, int count) - { - fixed (byte* ptr = &bytes[index]) - { - using var stream = new UnmanagedMemoryStream(ptr, count); - var @object = ProtoBuf.Serializer.Deserialize(type, stream); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - /// - public void Serialize(T @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize((MemoryStream)buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - public void Serialize(object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize((MemoryStream)buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - /// - public void Serialize(Type type, object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize((MemoryStream)buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到byte[] - /// - /// - /// - public byte[] Serialize(object @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using (var buffer = new MemoryStream()) - { - RuntimeTypeModel.Default.Serialize(buffer, @object); - return buffer.ToArray(); - } - } - /// - /// 使用ProtoBuf序列化某一个实例到byte[] - /// - /// - /// - public byte[] Serialize(T @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using (var buffer = new MemoryStream()) - { - RuntimeTypeModel.Default.Serialize(buffer, @object); - return buffer.ToArray(); - } - } - /// - /// 克隆 - /// - /// - /// - /// - public T Clone(T t) - { - return Deserialize(Serialize(t)); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/SerializerManager.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/SerializerManager.cs deleted file mode 100644 index 1ff52aa..0000000 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Serialize/SerializerManager.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Assembly; -using Fantasy.Helper; -#if !FANTASY_EXPORTER -using Fantasy.Network; -#endif -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -namespace Fantasy.Serialize -{ - /// - /// 框架内置的序列化器类型 - /// - public static class FantasySerializerType - { - /// - /// ProtoBuf在SerializerManager的数组下标 - /// - public const int ProtoBuf = 0; - /// - /// Bson在SerializerManager的数组下标 - /// - public const int Bson = 1; - } - - /// - /// 管理序列化静态方法,主要是优化网络协议时使用。 - /// - public static class SerializerManager - { - private static ISerialize[] _serializers; - private static bool _isInitialized = false; - -#if FANTASY_NET || FANTASY_UNITY - /// - /// 初始化方法 - /// - public static void Initialize() - { - if (_isInitialized) - { - return; - } - - try - { - var sort = new SortedList(); - - foreach (var serializerType in AssemblySystem.ForEach(typeof(ISerialize))) - { - var serializer = (ISerialize)Activator.CreateInstance(serializerType); - var computeHash64 = HashCodeHelper.ComputeHash64(serializer.SerializeName); - sort.Add(computeHash64, serializer); - } - - var index = 1; - _serializers = new ISerialize[sort.Count]; - - foreach (var (_, serialize) in sort) - { - var serializerIndex = 0; - - switch (serialize) - { - case ProtoBufPackHelper: - { - serializerIndex = FantasySerializerType.ProtoBuf; - break; - } - case BsonPackHelper: - { - serializerIndex = FantasySerializerType.Bson; - break; - } - default: - { - serializerIndex = ++index; - break; - } - } - - _serializers[serializerIndex] = serialize; - } - - _isInitialized = true; -#if FANTASY_DEBUG - Log.Info($"初始化序列化器成功,数量为:{_serializers.Length}"); -#endif - } - catch (Exception e) - { - Log.Error(e); - Dispose(); - } - } -#else - /// - /// 初始化方法 - /// - public static void Initialize() - { - if (_isInitialized) - { - return; - } - - _serializers = new ISerialize[1]; - _serializers[0] = new ProtoBufPackHelper(); - } -#endif - - /// - /// 销毁方法 - /// - public static void Dispose() - { - _isInitialized = false; - - if (_serializers == null || _serializers.Length == 0) - { - return; - } - - Array.Clear(_serializers, 0, _serializers.Length); - } - - /// - /// 根据协议类型获取序列化器 - /// - /// - /// - public static ISerialize GetSerializer(uint opCodeProtocolType) - { - return _serializers[opCodeProtocolType]; - } - - /// - /// 获得一个序列化器 - /// - /// - /// - /// - public static bool TryGetSerializer(uint opCodeProtocolType, out ISerialize serializer) - { - if (opCodeProtocolType < _serializers.Length) - { - serializer = _serializers[opCodeProtocolType]; - return true; - } - - serializer = default; - return false; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/icon.png b/Fantasy/Fantasy.Net/Fantasy.Net/icon.png deleted file mode 100644 index 8ae7488..0000000 Binary files a/Fantasy/Fantasy.Net/Fantasy.Net/icon.png and /dev/null differ diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Custom.txt b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Custom.txt deleted file mode 100644 index fd90a9b..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Custom.txt +++ /dev/null @@ -1 +0,0 @@ -// 自定义导出配置文件,用于配置自定义导出自定义程序的路径 diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/MachineConfig.xlsx b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/MachineConfig.xlsx deleted file mode 100644 index 999e939..0000000 Binary files a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/MachineConfig.xlsx and /dev/null differ diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/ProcessConfig.xlsx b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/ProcessConfig.xlsx deleted file mode 100644 index 001235a..0000000 Binary files a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/ProcessConfig.xlsx and /dev/null differ diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/SceneConfig.xlsx b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/SceneConfig.xlsx deleted file mode 100644 index 8d6684f..0000000 Binary files a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/SceneConfig.xlsx and /dev/null differ diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/WorldConfig.xlsx b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/WorldConfig.xlsx deleted file mode 100644 index 8194c9a..0000000 Binary files a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Server/WorldConfig.xlsx and /dev/null differ diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Version.txt b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Version.txt deleted file mode 100644 index 55b03f5..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Excel/Version.txt +++ /dev/null @@ -1 +0,0 @@ -{"WorksheetNames":[-8419147776733210060,-3495952183970875596,1720330851179383898,5812538452563588342],"Tables":{"-3495952183970875596":1747624043302,"-1088042625810372120":1731573652950,"1720330851179383898":1728449870789,"3730651590607244245":1731575713470,"5812538452563588342":1748394916174}} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/MachineConfigData.Json b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/MachineConfigData.Json deleted file mode 100644 index f56f98e..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/MachineConfigData.Json +++ /dev/null @@ -1,3 +0,0 @@ -{"List":[ -{"Id":1,"OuterIP":"127.0.0.1","OuterBindIP":"127.0.0.1","InnerBindIP":"127.0.0.1"} -]} diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/ProcessConfigData.Json b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/ProcessConfigData.Json deleted file mode 100644 index a05a13c..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/ProcessConfigData.Json +++ /dev/null @@ -1,3 +0,0 @@ -{"List":[ -{"Id":1,"MachineId":1,"StartupGroup":0} -]} diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/SceneConfigData.Json b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/SceneConfigData.Json deleted file mode 100644 index dbb3a7f..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/SceneConfigData.Json +++ /dev/null @@ -1,6 +0,0 @@ -{"List":[ -{"Id":1001,"ProcessConfigId":1,"WorldConfigId":1,"SceneRuntimeMode":"MultiThread","SceneTypeString":"Addressable","NetworkProtocol":null,"OuterPort":0,"InnerPort":11001,"SceneType":2}, -{"Id":1002,"ProcessConfigId":1,"WorldConfigId":1,"SceneRuntimeMode":"MultiThread","SceneTypeString":"Gate","NetworkProtocol":"KCP","OuterPort":20000,"InnerPort":11002,"SceneType":3}, -{"Id":1003,"ProcessConfigId":1,"WorldConfigId":1,"SceneRuntimeMode":"MultiThread","SceneTypeString":"Map","NetworkProtocol":null,"OuterPort":0,"InnerPort":11003,"SceneType":4}, -{"Id":1004,"ProcessConfigId":1,"WorldConfigId":1,"SceneRuntimeMode":"MultiThread","SceneTypeString":"Chat","NetworkProtocol":null,"OuterPort":0,"InnerPort":11004,"SceneType":8} -]} diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/WorldConfigData.Json b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/WorldConfigData.Json deleted file mode 100644 index 60dd090..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/Json/Server/WorldConfigData.Json +++ /dev/null @@ -1,3 +0,0 @@ -{"List":[ -{"Id":1,"WorldName":"测试服","DbConnection":null,"DbName":"fantasy_main","DbType":"MongoDB"} -]} diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/Inner/InnerMessage.proto b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/Inner/InnerMessage.proto deleted file mode 100644 index a8b51b8..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/Inner/InnerMessage.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; -package Sining.Message; -message G2A_TestRequest // IRouteRequest,G2A_TestResponse -{ - -} -message G2A_TestResponse // IRouteResponse -{ - -} -message G2M_RequestAddressableId // IRouteRequest,M2G_ResponseAddressableId -{ - -} -message M2G_ResponseAddressableId // IRouteResponse -{ - int64 AddressableId = 1; // Map服务器返回的AddressableId -} -/// 通知Chat服务器创建一个RouteId -message G2Chat_CreateRouteRequest // IRouteRequest,Chat2G_CreateRouteResponse -{ - int64 GateRouteId = 1; -} -message Chat2G_CreateRouteResponse // IRouteResponse -{ - int64 ChatRouteId = 1; -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/OpCode.Cache b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/OpCode.Cache deleted file mode 100644 index 9e26dfe..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/OpCode.Cache +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/Outer/OuterMessage.proto b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/Outer/OuterMessage.proto deleted file mode 100644 index b036a74..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/Outer/OuterMessage.proto +++ /dev/null @@ -1,64 +0,0 @@ -syntax = "proto3"; -package Fantasy.Network.Message; -// 协议分为: -// ProtoBuf:可以在Outer和Inner文件里使用。 -// MemoryPack:可以在Outer和Inner文件里使用。 -// Bson:仅支持在Inner文件里使用。 -// 使用方式: -// 在message协议上方添加// Protocol+空格+协议名字 -// 例如:// Protocol ProtoBuf 或 // Protocol MemoryPack -message C2G_TestMessage // IMessage -{ - string Tag = 1; -} -message C2G_TestRequest // IRequest,G2C_TestResponse -{ - string Tag = 1; -} -message G2C_TestResponse // IResponse -{ - string Tag = 1; -} -message C2G_CreateAddressableRequest // IRequest,G2C_CreateAddressableResponse -{ - -} -message G2C_CreateAddressableResponse // IResponse -{ - -} -message C2M_TestMessage // IAddressableRouteMessage -{ - string Tag = 1; -} -message C2M_TestRequest // IAddressableRouteRequest,M2C_TestResponse -{ - string Tag = 1; -} -message M2C_TestResponse // IAddressableRouteResponse -{ - string Tag = 1; -} -/// 通知Gate服务器创建一个Chat的Route连接 -message C2G_CreateChatRouteRequest // IRequest,G2C_CreateChatRouteResponse -{ - -} -message G2C_CreateChatRouteResponse // IResponse -{ - -} -/// 发送一个Route消息给Chat -message C2Chat_TestMessage // ICustomRouteMessage,ChatRoute -{ - string Tag = 1; -} -/// 发送一个RPCRoute消息给Chat -message C2Chat_TestMessageRequest // ICustomRouteRequest,Chat2C_TestMessageResponse,ChatRoute -{ - string Tag = 1; -} -message Chat2C_TestMessageResponse // ICustomRouteResponse -{ - string Tag = 1; -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/RouteType.Config b/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/RouteType.Config deleted file mode 100644 index 66082cf..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Config/NetworkProtocol/RouteType.Config +++ /dev/null @@ -1,3 +0,0 @@ -// Route协议定义(需要定义1000以上、因为1000以内的框架预留) -GateRoute = 1001 // Gate -ChatRoute = 1002 // Chat \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Fantasy-Net.Config.targets b/Fantasy/Fantasy.Packages/Fantasy.Config/Fantasy-Net.Config.targets deleted file mode 100644 index 19464f8..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Fantasy-Net.Config.targets +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - $(MSBuildProjectDirectory)\Tools\Exporter\ConfigTable\%(RecursiveDir)%(Filename)%(Extension) - - - - - - - - - - diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/Fantasy.Config.csproj b/Fantasy/Fantasy.Packages/Fantasy.Config/Fantasy.Config.csproj deleted file mode 100644 index bcb4e78..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/Fantasy.Config.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - Fantasy-Net.Config - 2024.1.4 - Fantasy-Net.Config - qq362946 - qq362946 - ../../nupkg - false - - Fantasy is a high-performance network development framework based on .NET, supporting mainstream protocols. It is designed for development teams or individuals needing a quick start, scalability, and a distributed, cross-platform solution at the commercial level. Fantasy aims to provide easy-to-use tools while ensuring high system performance and scalability. - Copyright 2026 qq362946 - README.md - https://www.code-fantasy.com/ - https://github.com/qq362946/Fantasy - git - Net, c#, Server, Game, GameServer, Fantasy , Network - icon.png - enable - enable - Fantasy-Net.Config - net8.0;net9.0 - default - - - - - - - - - - - - - diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/README.md b/Fantasy/Fantasy.Packages/Fantasy.Config/README.md deleted file mode 100644 index 697ec05..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.Config/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Fantasy-Net.Config -在Config文件夹中,存放着Fantasy所需的各种配置文件。这些文件涵盖了多个方面。每个配置文件都有其特定的格式和功能,通过精心设计的这些配置文件,开发团队能够快速调整框架参数,以实现更好的游戏体验,从而提升Fantasy的整体质量。 -## Excel文件夹 -里面存放了Fantasy.Net所需的四个Excel配置文件。用户可以利用Fantasy-Net.Exporter工具,依据这四个Excel文件生成相应的JSON文件,以供框架使用。这一过程不仅简化了数据处理,还确保了不同组件之间的无缝对接,使得工作流程更加高效。请确保在导出之前,Excel文件的格式和内容符合要求,以避免产生错误。 -## Json文件夹 -在该目录中存放了Fantasy.Net所需的四个JSON配置文件。用户可以根据这四个文件的模板进行添加或修改配置,以满足具体需求。每个项目的功能说明在相应的Excel文件中有详细描述,方便用户理解和使用这些配置文件。我们建议用户仔细阅读Excel文件中的说明,以确保配置的正确性和有效性。 -## NetworkProtocol文件夹 -存放框架所需定义网络协议的模版和文件夹 -### Inner文件夹 -定义服务器之间的网络协议 -### Outer文件夹 -定义客户端和服务器之间的网络协议 -### RouteType.Config -定义自定义Route协议的配置文件 -## 交流与讨论: -__讨论QQ群 : Fantasy服务器开发交流群 569888673 __ \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.Config/icon.png b/Fantasy/Fantasy.Packages/Fantasy.Config/icon.png deleted file mode 100644 index 8ae7488..0000000 Binary files a/Fantasy/Fantasy.Packages/Fantasy.Config/icon.png and /dev/null differ diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/ConfigTableHelper.cs b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/ConfigTableHelper.cs deleted file mode 100644 index e2d5ea9..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/ConfigTableHelper.cs +++ /dev/null @@ -1,194 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Fantasy.Assembly; -using Fantasy.Helper; -using Fantasy.Platform.Net; -using Fantasy.Serialize; -using Newtonsoft.Json.Linq; - -// ReSharper disable SuspiciousTypeConversion.Global - -namespace Fantasy.ConfigTable -{ - /// - /// 配置表帮助类 - /// - public static class ConfigTableHelper - { - private static readonly Dictionary _dictionary = new Dictionary(); - - /// - /// 初始化ConfigTableHelper - /// - public static void Initialize(string json, params System.Reflection.Assembly[] assemblies) - { - var jsonObj = JObject.Parse(json); - Dictionary tokens = new(); - foreach (var item in jsonObj) - { - try - { - var name = item.Key; - var value = item.Value; - if (value is JArray jArray) - { - tokens[name] = jArray; - } - } - catch (Exception e) - { - Log.Error($"读表异常,请检查,name={item.Key} ex={e}"); - } - } - - foreach (var type in GetAllConfigTableTypes(assemblies)) - { - var name = type.Name; - if (tokens.TryGetValue(name, out var jArray)) - { - // 通过反射调用 ParseJson 方法 - var parseMethod = type.GetMethod("ParseJson", BindingFlags.Public | BindingFlags.Static); - parseMethod?.Invoke(null, [jArray]); - } - } - - var d = _dictionary; - } - - public static ConfigContext Table() where T : IConfigTable - { - var type = typeof(T); - if (_dictionary.TryGetValue(type, out var context)) - { - return context as ConfigContext; - } - - var jsonContext = new ConfigContext(); - _dictionary[type] = jsonContext; - return jsonContext; - } - - public static List ParseLine(JArray arr) where T : IConfigTable, new() - { - List list = new List(); - foreach (var jToken in arr) - { - T instance = jToken.ToObject(); - - if (instance != null) - { - list.Add(instance); - } - } - - var context = Table(); - context.Association(list); - - return list; - } - - /// - /// 获取所有实现了 IConfigTable 接口的非抽象类 - /// - /// 所有非抽象的配置对象类 - private static List GetAllConfigTableTypes(params System.Reflection.Assembly[] assemblies) - { - var types = new List(); - var interfaceType = typeof(IConfigTable); - - // 遍历当前程序集中的所有类型 - foreach (var assembly in assemblies) - { - foreach (var type in assembly.GetTypes()) - { - // 检查是否实现了 IConfigTable 接口,并且不是抽象类 - if (interfaceType.IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface) - { - types.Add(type); - } - } - } - - return types; - } - - // private static string _configTableBinaryDirectory; - // private static readonly object Lock = new object(); - // // 配置表数据缓存字典 - // private static readonly Dictionary ConfigDic = new (); - // /// - // /// 初始化ConfigTableHelper - // /// - // /// - // public static void Initialize(string configTableBinaryDirectory) - // { - // _configTableBinaryDirectory = configTableBinaryDirectory; - // } - // /// - // /// 加载配置表数据 - // /// - // /// 配置表类型 - // /// 配置表数据 - // public static T Load() where T : ASerialize - // { - // lock (Lock) - // { - // try - // { - // var dataConfig = typeof(T).Name; - // - // if (ConfigDic.TryGetValue(dataConfig, out var aProto)) - // { - // return (T)aProto; - // } - // - // var configFile = GetConfigPath(dataConfig); - // var bytes = File.ReadAllBytes(configFile); - // // Log.Debug($"dataConfig:{dataConfig} {bytes.Length}"); - // var data = SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf).Deserialize(bytes); - // ConfigDic[dataConfig] = data; - // return data; - // } - // catch (Exception ex) - // { - // throw new Exception($"ConfigTableManage:{typeof(T).Name} 数据表加载之后反序列化时出错:{ex}"); - // } - // } - // } - // - // /// - // /// 获取配置表文件路径 - // /// - // /// 配置表名称 - // /// 配置表文件路径 - // private static string GetConfigPath(string name) - // { - // var configFile = Path.Combine(_configTableBinaryDirectory, $"{name}.bytes"); - // - // if (File.Exists(configFile)) - // { - // return configFile; - // } - // - // throw new FileNotFoundException($"{name}.byte not found: {configFile}"); - // } - // - // /// - // /// 重新加载配置表数据 - // /// - // public static void ReLoadConfigTable() - // { - // lock (Lock) - // { - // foreach (var (_, aProto) in ConfigDic) - // { - // ((IDisposable) aProto).Dispose(); - // } - // - // ConfigDic.Clear(); - // } - // } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/Fantasy.ConfigTable.csproj b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/Fantasy.ConfigTable.csproj deleted file mode 100644 index 5353c0c..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/Fantasy.ConfigTable.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - Fantasy-Net.ConfigTable - 2024.2.0 - Fantasy-Net.ConfigTable - qq362946 - qq362946 - ../../../nupkg - false - - Fantasy is a high-performance network development framework based on .NET, supporting mainstream protocols. It is designed for development teams or individuals needing a quick start, scalability, and a distributed, cross-platform solution at the commercial level. Fantasy aims to provide easy-to-use tools while ensuring high system performance and scalability. - Copyright 2026 qq362946 - https://www.code-fantasy.com/ - https://github.com/qq362946/Fantasy - git - Net, c#, Server, Game, GameServer, Fantasy , Network - icon.png - enable - enable - Fantasy-Net.ConfigTable - net8.0;net9.0 - default - - - - - - - - - - - diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/icon.png b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/icon.png deleted file mode 100644 index 8ae7488..0000000 Binary files a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/icon.png and /dev/null differ diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/README.md b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/README.md deleted file mode 100644 index aa00019..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# Fantasy.ConfigTable - -Fantasy配置表扩展包,配合Tools里面的配置导出工具使用,注意该包依赖Fantasy包。 - -- Unity : 需要先安装Fantasy.Unity -- Net : 需要先安装Fantasy.Net -## Unity - -在Unity中使用Package Manager,点击左上角➕选择add package from disk,选择package.json安装。 - -Unity端采用assetbundle方式加载配置文件,需要把配置文件放到一个包中,例如config的ab包。 - -可以在导出工具中设置导出到前端二进制文件的路径,设置到这个config包中。 - -用代码使用一个IConfigTableAssetBundle接口 - -```csharp -public sealed class AsserBundleManager : IConfigTableAssetBundle - { - public string Combine(string assetBundleDirectoryPath, string dataConfig) - { - // 该方法用于拼装ab包的路径,因为不同的ab包资源管理工具路径都不一样 - // 所以这里提供该方法自定义路径 - return Path.Combine(assetBundleDirectoryPath, $"{dataConfig}.bytes"); - } - - public byte[] LoadConfigTable(string assetBundlePath) - { - // 这里是加载包里的二进制文件的逻辑。 - // 正常的情况下需要分编辑器和打包环境下。 - // 这里只做了编辑器下拿取ab包里的某个配置文件的逻辑。 - // 正常情况下要把非编辑器环境的逻辑也要写好。 - if (File.Exists(assetBundlePath)) - { - return AssetDatabase.LoadAssetAtPath(assetBundlePath).bytes; - } - UnityEngine.Debug.LogError($"assetBundlePath:{assetBundlePath} not exist"); - return null; - } - } -``` - -上述工作完成够,可以在项目入口点执行初始化代码 - -```csharp -// 第一个参数是指定ab包的路径,但不包含配置名字,因为配置文件会在上面的AsserBundleManager里Combine方法拼接出的路径 -// 同样这里因为是编辑环境下,所以我输入的是一个路径。 -// 但如果打包后这个路径其实并不能使用,要把这个路径改成ab包发布都得正常路径。 -ConfigTableHelper.Initialize("Assets/Bundles/Config/", new AsserBundleManager()); -``` - -## Net - -```csharp -// 设置配置表的路径 -// 导出工具会把配置表的二进制数据导出到一个目录中。 -// 服务器启动的时候需要传入这个目录的路径。 -// 我这里使用了相对路径,大家可以根据自己的环境更改目录 -ConfigTableHelper.Initialize("../../../Config/Binary"); -``` - -## 使用 - -初始化完成后,就可以在项目中使用配置文件了 - -```csharp -// 例如我配置了一个表名为UnitConfig,那在导出在代码中使用只需要再这个表名后面加上Data -// 然后在使用下面的Instance就可以访问表里的数据了 - -// 获得表里的所有数据 -var instanceList = UnitConfigData.Instance.List; -// 根据表的主键Id来获得数据,这里的1就是表对应的Id -var unitConfig = UnitConfigData.Instance.Get(1); -``` \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Fantasy.ConfigTable.asmdef b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Fantasy.ConfigTable.asmdef deleted file mode 100644 index 7869fee..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Fantasy.ConfigTable.asmdef +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "Fantasy.ConfigTable", - "rootNamespace": "", - "references": [ - "GUID:0b7224b83ba514121aa026f3857f820a" - ], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Fantasy.ConfigTable.asmdef.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Fantasy.ConfigTable.asmdef.meta deleted file mode 100644 index 5caa0e4..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Fantasy.ConfigTable.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: c4d36c5a80dc44c6e822eba8db9ed704 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime.meta deleted file mode 100644 index 489b45f..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: cfbf88374cb6b49f2947ab95a9bc08ba -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/ConfigTableHelper.cs b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/ConfigTableHelper.cs deleted file mode 100644 index bbeace3..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/ConfigTableHelper.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Serialize; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -// ReSharper disable SuspiciousTypeConversion.Global - -namespace Fantasy.ConfigTable -{ - /// - /// 配置表帮助类 - /// - public static class ConfigTableHelper - { - private static string _assetBundleDirectoryPath; - private static IConfigTableAssetBundle _configTableAssetBundle; - private static readonly object Lock = new object(); - // 配置表数据缓存字典 - private static readonly Dictionary ConfigDic = new (); - - /// - /// 初始化ConfigTableHelper - /// - /// - /// - public static void Initialize(string assetBundleDirectoryPath, IConfigTableAssetBundle configTableAssetBundle) - { - _assetBundleDirectoryPath = assetBundleDirectoryPath; - _configTableAssetBundle = configTableAssetBundle; - } - /// - /// 加载配置表数据 - /// - /// 配置表类型 - /// 配置表数据 - public static T Load() where T : ASerialize - { - lock (Lock) - { - try - { - var dataConfig = typeof(T).Name; - - if (ConfigDic.TryGetValue(dataConfig, out var aProto)) - { - return (T)aProto; - } - - var dataConfigPath = _configTableAssetBundle.Combine(_assetBundleDirectoryPath, dataConfig); - var bytes = _configTableAssetBundle.LoadConfigTable(dataConfigPath); - var data = SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf).Deserialize(bytes); - ConfigDic[dataConfig] = data; - return data; - } - catch (Exception ex) - { - throw new Exception($"ConfigTableManage:{typeof(T).Name} 数据表加载之后反序列化时出错:{ex}"); - } - } - } - - /// - /// 重新加载配置表数据 - /// - public static void ReLoadConfigTable() - { - lock (Lock) - { - foreach (var (_, aProto) in ConfigDic) - { - ((IDisposable) aProto).Dispose(); - } - - ConfigDic.Clear(); - } - } - } -} diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/ConfigTableHelper.cs.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/ConfigTableHelper.cs.meta deleted file mode 100644 index 132e91c..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/ConfigTableHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2e3ca7a021b1c445a9f58c1e4645fe17 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary.meta deleted file mode 100644 index abc7cb3..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 6e10a07ad20ee4d7298ee808a3ea8b73 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/IntDictionaryConfig.cs b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/IntDictionaryConfig.cs deleted file mode 100644 index a9b13b3..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/IntDictionaryConfig.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Collections.Generic; -using ProtoBuf; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -// ReSharper disable CheckNamespace -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.ConfigTable -{ - [ProtoContract] - public partial class IntDictionaryConfig - { - [ProtoMember(1)] - public Dictionary Dic; - public int this[int key] => GetValue(key); - public bool TryGetValue(int key, out int value) - { - value = default; - - if (!Dic.ContainsKey(key)) - { - return false; - } - - value = Dic[key]; - return true; - } - private int GetValue(int key) - { - return Dic.TryGetValue(key, out var value) ? value : 0; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/IntDictionaryConfig.cs.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/IntDictionaryConfig.cs.meta deleted file mode 100644 index 692433f..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/IntDictionaryConfig.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 294753d61a7ac401f9f1b75e43d7536e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/StringDictionaryConfig.cs b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/StringDictionaryConfig.cs deleted file mode 100644 index 708ccd7..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/StringDictionaryConfig.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; -using ProtoBuf; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -// ReSharper disable CheckNamespace -// ReSharper disable CollectionNeverUpdated.Global -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -namespace Fantasy.ConfigTable -{ - [ProtoContract] - public sealed partial class StringDictionaryConfig - { - [ProtoMember(1)] - public Dictionary Dic; - public string this[int key] => GetValue(key); - public bool TryGetValue(int key, out string value) - { - value = default; - - if (!Dic.ContainsKey(key)) - { - return false; - } - - value = Dic[key]; - return true; - } - private string GetValue(int key) - { - return Dic.TryGetValue(key, out var value) ? value : null; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/StringDictionaryConfig.cs.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/StringDictionaryConfig.cs.meta deleted file mode 100644 index 7c61f54..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Dictionary/StringDictionaryConfig.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 295679520921148c685abac87ba609fd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface.meta deleted file mode 100644 index 92fa071..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e229cd1e867af419193a32fefaf271df -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTable.cs b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTable.cs deleted file mode 100644 index 0992677..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTable.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Fantasy.ConfigTable -{ - /// - /// 表示是一个配置文件 - /// - public interface IConfigTable { } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTable.cs.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTable.cs.meta deleted file mode 100644 index 4138cee..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTable.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ba91b698a7df846c185a3d9e384f71b6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTableAssetBundle.cs b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTableAssetBundle.cs deleted file mode 100644 index 0e17a06..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTableAssetBundle.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Fantasy.ConfigTable -{ - public interface IConfigTableAssetBundle - { - /// - /// 不同的资源管理器有各自独特的包加载方式。 - /// 为了满足不同的需求,我们提供了这个接口,允许用户自定义拼装包路径。 - /// 通过这个接口,用户可以根据自己的特定格式和要求,灵活地加载包,从而提高资源管理的灵活性和效率。 - /// - /// - /// - /// - public string Combine(string assetBundleDirectoryPath, string dataConfig); - public byte[] LoadConfigTable(string assetBundlePath); - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTableAssetBundle.cs.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTableAssetBundle.cs.meta deleted file mode 100644 index 65579ac..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/Runtime/Interface/IConfigTableAssetBundle.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: a819f57dfada43d9955a9b402772cf6d -timeCreated: 1728549292 \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/package.json b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/package.json deleted file mode 100644 index a07c9b7..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "com.fantasy.configtable", - "version": "2024.2.24", - "displayName": "Fantasy.ConfigTable", - "description": "Fantasy is a cross platform distributed server framework.", - "category": "Network Framework", - "documentationUrl": "https://www.code-fantasy.com/", - "changelogUrl": "https://www.code-fantasy.com/", - "licensesUrl": "https://www.code-fantasy.com/", - "keywords": [ - "Fantasy", - "Framework", - "hotfix", - "Server", - "Network" - ], - "author": { - "name": "Fantasy", - "email": "362946@qq.com", - "url": "https://www.code-fantasy.com/" - }, - "dependencies": {} -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/package.json.meta b/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/package.json.meta deleted file mode 100644 index fb85612..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Unity/package.json.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: db12b302eec284d61984b0798590173a -PackageManifestImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Fantasy/Fantasy.Packages/Fantasy.MemoryPack/Net/MemoryPack/MemoryPackHelper.cs b/Fantasy/Fantasy.Packages/Fantasy.MemoryPack/Net/MemoryPack/MemoryPackHelper.cs deleted file mode 100644 index e60da3e..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.MemoryPack/Net/MemoryPack/MemoryPackHelper.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.Buffers; -using MemoryPack; - -namespace Fantasy.Serialize -{ - /// - /// MemoryPack帮助类 - /// - public sealed class MemoryPackHelper : ISerialize - { - /// - /// 序列化器的名字 - /// - public string SerializeName { get; } = "MemoryPack"; - - /// - /// 反序列化 - /// - /// - /// - /// - public T Deserialize(byte[] bytes) - { - var @object = MemoryPackSerializer.Deserialize(bytes); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - public T Deserialize(MemoryStreamBuffer buffer) - { - var @object = MemoryPackSerializer.Deserialize(buffer.GetSpan()); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - public object Deserialize(Type type, byte[] bytes) - { - var @object = MemoryPackSerializer.Deserialize(type,bytes); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - public object Deserialize(Type type, MemoryStreamBuffer buffer) - { - var @object = MemoryPackSerializer.Deserialize(type, buffer.GetSpan()); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - public T Deserialize(byte[] bytes, int index, int count) - { - var @object = MemoryPackSerializer.Deserialize(new ReadOnlySpan(bytes, index, count)); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - public object Deserialize(Type type, byte[] bytes, int index, int count) - { - var @object = MemoryPackSerializer.Deserialize(type, new ReadOnlySpan(bytes, index, count)); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 序列化 - /// - /// - /// - /// - public void Serialize(T @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - MemoryPackSerializer.Serialize>(buffer, @object); - } - - /// - /// 序列化 - /// - /// - /// - public void Serialize(object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - MemoryPackSerializer.Serialize(@object.GetType(), buffer, @object); - } - - /// - /// 序列化 - /// - /// - /// - /// - public void Serialize(Type type, object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - MemoryPackSerializer.Serialize(type, buffer, @object); - } - - /// - /// 序列化 - /// - /// - /// - public byte[] Serialize(object @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - return MemoryPackSerializer.Serialize(@object.GetType(), @object); - } - - /// - /// 序列化 - /// - /// - /// - /// - public byte[] Serialize(T @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - return MemoryPackSerializer.Serialize(@object); - } - - /// - /// 克隆 - /// - /// - /// - /// - public T Clone(T t) - { - return Deserialize(Serialize(t)); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.MemoryPack/README.md b/Fantasy/Fantasy.Packages/Fantasy.MemoryPack/README.md deleted file mode 100644 index fe5b775..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.MemoryPack/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Fantasy.MemoryPack 扩展包 -## Unity -Unity使用,只需要再Unity文件夹里,导入Fantays.MemoryPack.unitypackage到Unity里即可。 -## Net - * 在你的项目里用Nuget或dotnet add package MemoryPack安装MemoryPack的库。 - * 再Net文件夹里把MemoryPack文件夹拷贝的项目中。 -## Tools -编辑改导表工具ExporterSettings.json文件,在文件Serializes里增加MemoryPack协议的说明. -```json -"Serializes": { - "Value": [ - { - "KeyIndex": 0, - "NameSpace" : "MemoryPack", - "SerializeName": "MemoryPack", - "Attribute": "\t[MemoryPackable]", - "Ignore": "\t\t[MemoryPackIgnore]", - "Member": "MemoryPackOrder" - } - ], - "Comment": "自定义序列化器" - } -``` -## 使用注意 -无论是Unity或Net下,导入所在的项目,必须要把当前程序集装载到框架中才可以。 diff --git a/Fantasy/Fantasy.Packages/Fantasy.MemoryPack/Unity/Fantays.MemoryPack.unitypackage b/Fantasy/Fantasy.Packages/Fantasy.MemoryPack/Unity/Fantays.MemoryPack.unitypackage deleted file mode 100644 index eea504b..0000000 Binary files a/Fantasy/Fantasy.Packages/Fantasy.MemoryPack/Unity/Fantays.MemoryPack.unitypackage and /dev/null differ diff --git a/Fantasy/Fantasy.Packages/Fantasy.NLog/Fantasy-Net.NLog.targets b/Fantasy/Fantasy.Packages/Fantasy.NLog/Fantasy-Net.NLog.targets deleted file mode 100644 index 9a3ba44..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.NLog/Fantasy-Net.NLog.targets +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - Always - - - - Always - - - - diff --git a/Fantasy/Fantasy.Packages/Fantasy.NLog/Fantasy.NLog.csproj b/Fantasy/Fantasy.Packages/Fantasy.NLog/Fantasy.NLog.csproj deleted file mode 100644 index ce9168a..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.NLog/Fantasy.NLog.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - Fantasy-Net.NLog - 2024.1.20 - Fantasy-Net.NLog - qq362946 - qq362946 - ../../nupkg - false - - Fantasy is a high-performance network development framework based on .NET, supporting mainstream protocols. It is designed for development teams or individuals needing a quick start, scalability, and a distributed, cross-platform solution at the commercial level. Fantasy aims to provide easy-to-use tools while ensuring high system performance and scalability. - Copyright 2026 qq362946 - https://www.code-fantasy.com/ - https://github.com/qq362946/Fantasy - git - Net, c#, Server, Game, GameServer, Fantasy , Network - icon.png - enable - enable - Fantasy-Net.NLog - net8.0;net9.0 - default - - - - - - - - - - - - - - - diff --git a/Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.cs b/Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.cs deleted file mode 100644 index efe9672..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.cs +++ /dev/null @@ -1,167 +0,0 @@ -using Fantasy.Platform.Net; -using NLog; - -namespace Fantasy -{ - /// - /// 使用 NLog 实现的日志记录器。 - /// - public class NLog : ILog - { - private readonly Logger _logger; // NLog 日志记录器实例 - - /// - /// 初始化 NLog 实例。 - /// - /// 日志记录器的名称。 - public NLog(string name) - { - // 获取指定名称的 NLog 日志记录器 - _logger = LogManager.GetLogger(name); - } - - /// - /// 初始化方法 - /// - /// - public void Initialize(ProcessMode processMode) - { - // 非Benchmark模式、根据不同的运行模式来选择日志的方式 - switch (processMode) - { - case ProcessMode.Develop: - { - LogManager.Configuration.RemoveRuleByName("ServerDebug"); - LogManager.Configuration.RemoveRuleByName("ServerTrace"); - LogManager.Configuration.RemoveRuleByName("ServerInfo"); - LogManager.Configuration.RemoveRuleByName("ServerWarn"); - LogManager.Configuration.RemoveRuleByName("ServerError"); - break; - } - case ProcessMode.Release: - { - LogManager.Configuration.RemoveRuleByName("ConsoleTrace"); - LogManager.Configuration.RemoveRuleByName("ConsoleDebug"); - LogManager.Configuration.RemoveRuleByName("ConsoleInfo"); - LogManager.Configuration.RemoveRuleByName("ConsoleWarn"); - LogManager.Configuration.RemoveRuleByName("ConsoleError"); - break; - } - } - } - - /// - /// 记录跟踪级别的日志消息。 - /// - /// 日志消息。 - public void Trace(string message) - { - _logger.Trace(message); - } - - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - public void Warning(string message) - { - _logger.Warn(message); - } - - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - public void Info(string message) - { - _logger.Info(message); - } - - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - public void Debug(string message) - { - _logger.Debug(message); - } - - /// - /// 记录错误级别的日志消息。 - /// - /// 日志消息。 - public void Error(string message) - { - _logger.Error(message); - } - - /// - /// 记录严重错误级别的日志消息。 - /// - /// 日志消息。 - public void Fatal(string message) - { - _logger.Fatal(message); - } - - /// - /// 记录跟踪级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Trace(string message, params object[] args) - { - _logger.Trace(message, args); - } - - /// - /// 记录警告级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Warning(string message, params object[] args) - { - _logger.Warn(message, args); - } - - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Info(string message, params object[] args) - { - _logger.Info(message, args); - } - - /// - /// 记录调试级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Debug(string message, params object[] args) - { - _logger.Debug(message, args); - } - - /// - /// 记录错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Error(string message, params object[] args) - { - _logger.Error(message, args); - } - - /// - /// 记录严重错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Fatal(string message, params object[] args) - { - _logger.Fatal(message, args); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.xsd b/Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.xsd deleted file mode 100644 index 63c9a0c..0000000 --- a/Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.xsd +++ /dev/null @@ -1,3483 +0,0 @@ - - - - - - - - - - - - - - - Watch config file for changes and reload automatically. - - - - - Print internal NLog messages to the console. Default value is: false - - - - - Print internal NLog messages to the console error output. Default value is: false - - - - - Write internal NLog messages to the specified file. - - - - - Log level threshold for internal log messages. Default value is: Info. - - - - - Global log level threshold for application log messages. Messages below this level won't be logged. - - - - - Throw an exception when there is an internal error. Default value is: false. Not recommend to set to true in production! - - - - - Throw an exception when there is a configuration error. If not set, determined by throwExceptions. - - - - - Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false. - - - - - Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false. - - - - - Write timestamps for internal NLog messages. Default value is: true. - - - - - Use InvariantCulture as default culture instead of CurrentCulture. Default value is: false. - - - - - Perform message template parsing and formatting of LogEvent messages (true = Always, false = Never, empty = Auto Detect). Default value is: empty. - - - - - - - - - - - - - - Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes). - - - - - - - - - - - - - - - - - Prefix for targets/layout renderers/filters/conditions loaded from this assembly. - - - - - Load NLog extensions from the specified file (*.dll) - - - - - Load NLog extensions from the specified assembly. Assembly name should be fully qualified. - - - - - - - - - - Filter on the name of the logger. May include wildcard characters ('*' or '?'). - - - - - Comma separated list of levels that this rule matches. - - - - - Minimum level that this rule matches. - - - - - Maximum level that this rule matches. - - - - - Level that this rule matches. - - - - - Comma separated list of target names. - - - - - Ignore further rules if this one matches. - - - - - Enable this rule. Note: disabled rules aren't available from the API. - - - - - Rule identifier to allow rule lookup with Configuration.FindRuleByName and Configuration.RemoveRuleByName. - - - - - Loggers matching will be restricted to specified minimum level for following rules. - - - - - - - - - - - - - - - Default action if none of the filters match. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file. - - - - - Ignore any errors in the include file. - - - - - - - - Variable value. Note, the 'value' attribute has precedence over this one. - - - - - - Variable name. - - - - - Variable value. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Action to be taken when the lazy writer thread request queue count exceeds the set limit. - - - - - Limit on the number of requests in the lazy writer thread request queue. - - - - - Number of log events that should be processed in a batch by the lazy writer thread. - - - - - Whether to use the locking queue, instead of a lock-free concurrent queue - - - - - Number of batches of P:NLog.Targets.Wrappers.AsyncTargetWrapper.BatchSize to write before yielding into P:NLog.Targets.Wrappers.AsyncTargetWrapper.TimeToSleepBetweenBatches - - - - - Time in milliseconds to sleep between batches. (1 or less means trigger on new activity) - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Delay the flush until the LogEvent has been confirmed as written - - - - - Condition expression. Log events who meet this condition will cause a flush on the wrapped target. - - - - - Only flush when LogEvent matches condition. Ignore explicit-flush, config-reload-flush and shutdown-flush - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Number of log events to be buffered. - - - - - Action to take if the buffer overflows. - - - - - Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes. - - - - - Indicates whether to use sliding timeout. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Separator for T:NLog.ScopeContext operation-states-stack. - - - - - Stack separator for log4j:NDC in output from T:NLog.ScopeContext nested context. - - - - - Renderer for log4j:event logger-xml-attribute (Default ${logger}) - - - - - Whether to include the contents of the T:NLog.ScopeContext properties-dictionary. - - - - - Whether to include log4j:NDC in output from T:NLog.ScopeContext nested context. - - - - - Indicates whether to include source info (file name and line number) in the information sent over the network. - - - - - Whether to include log4j:NDC in output from T:NLog.ScopeContext nested context. - - - - - Option to include all properties from the log events - - - - - Indicates whether to include call site (class and method name) in the information sent over the network. - - - - - AppInfo field. By default it's the friendly name of the current AppDomain. - - - - - Instance of T:NLog.Layouts.Log4JXmlEventLayout that is used to format log messages. - - - - - Indicates whether to include NLog-specific extensions to log4j schema. - - - - - Action that should be taken, when more connections than P:NLog.Targets.NetworkTarget.MaxConnections. - - - - - SSL/TLS protocols. Default no SSL/TLS is used. Currently only implemented for TCP. - - - - - Action that should be taken, when more pending messages than P:NLog.Targets.NetworkTarget.MaxQueueSize. - - - - - Action that should be taken if the message is larger than P:NLog.Targets.NetworkTarget.MaxMessageSize - - - - - Maximum queue size for a single connection. Requires P:NLog.Targets.NetworkTarget.KeepConnection = true - - - - - Network address. - - - - - Indicates whether to keep connection open whenever possible. - - - - - The number of seconds a connection will remain idle before the first keep-alive probe is sent - - - - - Size of the connection cache (number of connections which are kept alive). Requires P:NLog.Targets.NetworkTarget.KeepConnection = true - - - - - Maximum simultaneous connections. Requires P:NLog.Targets.NetworkTarget.KeepConnection = false - - - - - Type of compression for protocol payload. Useful for UDP where datagram max-size is 8192 bytes. - - - - - Skip compression when protocol payload is below limit to reduce overhead in cpu-usage and additional headers - - - - - Maximum message size in bytes. On limit breach then P:NLog.Targets.NetworkTarget.OnOverflow action is activated. - - - - - Encoding to be used. - - - - - End of line value if a newline is appended at the end of log message P:NLog.Targets.NetworkTarget.NewLine. - - - - - Indicates whether to append newline at the end of log message. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Viewer parameter name. - - - - - Layout that should be use to calculate the value for the parameter. - - - - - Whether an attribute with empty value should be included in the output - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Text to be rendered. - - - - - Header. - - - - - Footer. - - - - - Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) - - - - - Enables output using ANSI Color Codes - - - - - The encoding for writing messages to the T:System.Console. - - - - - Indicates whether to send the log messages to the standard error instead of the standard output. - - - - - Indicates whether to auto-flush after M:System.Console.WriteLine - - - - - Indicates whether to auto-check if the console has been redirected to file - Disables coloring logic when System.Console.IsOutputRedirected = true - - - - - Indicates whether to use default row highlighting rules. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Background color. - - - - - Condition that must be met in order to set the specified foreground and background color. - - - - - Foreground color. - - - - - - - - - - - - - - - - - Background color. - - - - - Compile the P:NLog.Targets.ConsoleWordHighlightingRule.Regex? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used. - - - - - Condition that must be met before scanning the row for highlight of words - - - - - Foreground color. - - - - - Indicates whether to ignore case when comparing texts. - - - - - Regular expression to be matched. You must specify either text or regex. - - - - - Text to be matched. You must specify either text or regex. - - - - - Indicates whether to match whole words only. - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Text to be rendered. - - - - - Header. - - - - - Footer. - - - - - Indicates whether to auto-flush after M:System.Console.WriteLine - - - - - Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) - - - - - The encoding for writing messages to the T:System.Console. - - - - - Indicates whether to send the log messages to the standard error instead of the standard output. - - - - - Whether to activate internal buffering to allow batch writing, instead of using M:System.Console.WriteLine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string. - - - - - Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string. - - - - - Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string. - - - - - Name of the connection string (as specified in <connectionStrings> configuration section. - - - - - Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string. - - - - - Indicates whether to keep the database connection open between the log events. - - - - - Name of the database provider. - - - - - Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase. - - - - - Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used. - - - - - Configures isolated transaction batch writing. If supported by the database, then it will improve insert performance. - - - - - Text of the SQL command to be run on each log level. - - - - - Type of the SQL command to be run on each log level. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Convert format of the property value - - - - - Culture used for parsing property string-value for type-conversion - - - - - Value to assign on the object-property - - - - - Name for the object-property - - - - - Type of the object-property - - - - - - - - - - - - - - Type of the command. - - - - - Connection string to run the command against. If not provided, connection string from the target is used. - - - - - Indicates whether to ignore failures. - - - - - Command text. - - - - - - - - - - - - - - - - - - - - Database parameter name. - - - - - Layout that should be use to calculate the value for the parameter. - - - - - Database parameter DbType. - - - - - Database parameter size. - - - - - Database parameter precision. - - - - - Database parameter scale. - - - - - Type of the parameter. - - - - - Fallback value when result value is not available - - - - - Convert format of the database parameter value. - - - - - Culture used for parsing parameter string-value for type-conversion - - - - - Whether empty value should translate into DbNull. Requires database column to allow NULL values. - - - - - - - - - - - - - - - Name of the target. - - - - - Text to be rendered. - - - - - Header. - - - - - Footer. - - - - - - - - - - - - - - - - - Name of the target. - - - - - Text to be rendered. - - - - - Header. - - - - - Footer. - - - - - - - - - - - - - - - Name of the target. - - - - - Layout used to format log messages. - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Layout used to format log messages. - - - - - Layout that renders event Category. - - - - - Optional entry type. When not set, or when not convertible to T:System.Diagnostics.EventLogEntryType then determined by T:NLog.LogLevel - - - - - Layout that renders event ID. - - - - - Name of the Event Log to write to. This can be System, Application or any user-defined name. - - - - - Name of the machine on which Event Log service is running. - - - - - Maximum Event log size in kilobytes. - - - - - Message length limit to write to the Event Log. - - - - - Value to be used as the event Source. - - - - - Action to take if the message is larger than the P:NLog.Targets.EventLogTarget.MaxMessageLength option. - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Indicates whether to return to the first target after any successful write. - - - - - Whether to enable batching, but fallback will be handled individually - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Name of the file to write to. - - - - - Text to be rendered. - - - - - Header. - - - - - Footer. - - - - - Indicates whether the footer should be written only when the file is archived. - - - - - Maximum number of archive files that should be kept. - - - - - Maximum days of archive files that should be kept. - - - - - Value of the file size threshold to archive old log file on startup. - - - - - Indicates whether to archive old log file on startup. - - - - - Indicates whether to compress archive files into the zip archive format. - - - - - Name of the file to be used for an archive. - - - - - Is the P:NLog.Targets.FileTarget.ArchiveFileName an absolute or relative path? - - - - - Indicates whether to automatically archive log files every time the specified time passes. - - - - - Value specifying the date format to use when archiving files. - - - - - Size in bytes above which log files will be automatically archived. - - - - - Way file archives are numbered. - - - - - Indicates whether to create directories if they do not exist. - - - - - Indicates whether file creation calls should be synchronized by a system global mutex. - - - - - Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation. - - - - - Is the P:NLog.Targets.FileTarget.FileName an absolute or relative path? - - - - - File attributes (Windows only). - - - - - Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong. - - - - - Indicates whether to write BOM (byte order mark) in created files. Defaults to true for UTF-16 and UTF-32 - - - - - Indicates whether to enable log file(s) to be deleted. - - - - - Indicates whether to delete old log file on startup. - - - - - File encoding. - - - - - Indicates whether to replace file contents on each write instead of appending log message at the end. - - - - - Line ending mode. - - - - - Number of times the write is appended on the file before NLog discards the log message. - - - - - Delay in milliseconds to wait before attempting to write to the file again. - - - - - Maximum number of seconds before open files are flushed. Zero or negative means disabled. - - - - - Maximum number of seconds that files are kept open. Zero or negative means disabled. - - - - - Indicates whether concurrent writes to the log file by multiple processes on different network hosts. - - - - - Log file buffer size in bytes. - - - - - Indicates whether to automatically flush the file buffers after each log message. - - - - - Indicates whether to keep log file open instead of opening and closing it on each logging event. - - - - - Indicates whether concurrent writes to the log file by multiple processes on the same host. - - - - - Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write - - - - - Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Condition expression. Log events who meet this condition will be forwarded to the wrapped target. - - - - - - - - - - - - - - - Name of the target. - - - - - Identifier to perform group-by - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Windows domain name to change context to. - - - - - Required impersonation level. - - - - - Type of the logon provider. - - - - - Logon Type. - - - - - User account password. - - - - - Indicates whether to revert to the credentials of the process instead of impersonating another user. - - - - - Username to change context to. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Interval in which messages will be written up to the P:NLog.Targets.Wrappers.LimitingTargetWrapper.MessageLimit number of messages. - - - - - Maximum allowed number of messages written per P:NLog.Targets.Wrappers.LimitingTargetWrapper.Interval. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Text to be rendered. - - - - - Header. - - - - - Footer. - - - - - Indicates whether NewLine characters in the body should be replaced with tags. - - - - - Priority used for sending mails. - - - - - Encoding to be used for sending e-mail. - - - - - BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). - - - - - CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). - - - - - Indicates whether to add new lines between log entries. - - - - - Indicates whether to send message as HTML instead of plain text. - - - - - Sender's email address (e.g. joe@domain.com). - - - - - Mail message body (repeated for each log message send in one mail). - - - - - Mail subject. - - - - - Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). - - - - - Specifies how outgoing email messages will be handled. - - - - - SMTP Server to be used for sending. - - - - - SMTP Authentication mode. - - - - - Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic"). - - - - - Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic"). - - - - - Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server. - - - - - Port number that SMTP Server is listening on. - - - - - Indicates whether the default Settings from System.Net.MailSettings should be used. - - - - - Folder where applications save mail messages to be processed by the local SMTP server. - - - - - Indicates the SMTP client timeout. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Text to be rendered. - - - - - Header. - - - - - Footer. - - - - - Max number of items to have in memory - - - - - - - - - - - - - - - - - Name of the target. - - - - - Class name. - - - - - Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g. - - - - - - - - - - - - - - - Name of the parameter. - - - - - Layout that should be use to calculate the value for the parameter. - - - - - Fallback value when result value is not available - - - - - Type of the parameter. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Layout used to format log messages. - - - - - SSL/TLS protocols. Default no SSL/TLS is used. Currently only implemented for TCP. - - - - - Action that should be taken, when more pending messages than P:NLog.Targets.NetworkTarget.MaxQueueSize. - - - - - Action that should be taken if the message is larger than P:NLog.Targets.NetworkTarget.MaxMessageSize - - - - - Maximum queue size for a single connection. Requires P:NLog.Targets.NetworkTarget.KeepConnection = true - - - - - Action that should be taken, when more connections than P:NLog.Targets.NetworkTarget.MaxConnections. - - - - - Indicates whether to keep connection open whenever possible. - - - - - The number of seconds a connection will remain idle before the first keep-alive probe is sent - - - - - Size of the connection cache (number of connections which are kept alive). Requires P:NLog.Targets.NetworkTarget.KeepConnection = true - - - - - Network address. - - - - - Maximum simultaneous connections. Requires P:NLog.Targets.NetworkTarget.KeepConnection = false - - - - - Type of compression for protocol payload. Useful for UDP where datagram max-size is 8192 bytes. - - - - - Skip compression when protocol payload is below limit to reduce overhead in cpu-usage and additional headers - - - - - Maximum message size in bytes. On limit breach then P:NLog.Targets.NetworkTarget.OnOverflow action is activated. - - - - - Encoding to be used. - - - - - End of line value if a newline is appended at the end of log message P:NLog.Targets.NetworkTarget.NewLine. - - - - - Indicates whether to append newline at the end of log message. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Separator for T:NLog.ScopeContext operation-states-stack. - - - - - Stack separator for log4j:NDC in output from T:NLog.ScopeContext nested context. - - - - - Renderer for log4j:event logger-xml-attribute (Default ${logger}) - - - - - Whether to include the contents of the T:NLog.ScopeContext properties-dictionary. - - - - - Whether to include log4j:NDC in output from T:NLog.ScopeContext nested context. - - - - - Indicates whether to include source info (file name and line number) in the information sent over the network. - - - - - Whether to include log4j:NDC in output from T:NLog.ScopeContext nested context. - - - - - Option to include all properties from the log events - - - - - Indicates whether to include call site (class and method name) in the information sent over the network. - - - - - AppInfo field. By default it's the friendly name of the current AppDomain. - - - - - Instance of T:NLog.Layouts.Log4JXmlEventLayout that is used to format log messages. - - - - - Indicates whether to include NLog-specific extensions to log4j schema. - - - - - Action that should be taken, when more connections than P:NLog.Targets.NetworkTarget.MaxConnections. - - - - - SSL/TLS protocols. Default no SSL/TLS is used. Currently only implemented for TCP. - - - - - Action that should be taken, when more pending messages than P:NLog.Targets.NetworkTarget.MaxQueueSize. - - - - - Action that should be taken if the message is larger than P:NLog.Targets.NetworkTarget.MaxMessageSize - - - - - Maximum queue size for a single connection. Requires P:NLog.Targets.NetworkTarget.KeepConnection = true - - - - - Network address. - - - - - Indicates whether to keep connection open whenever possible. - - - - - The number of seconds a connection will remain idle before the first keep-alive probe is sent - - - - - Size of the connection cache (number of connections which are kept alive). Requires P:NLog.Targets.NetworkTarget.KeepConnection = true - - - - - Maximum simultaneous connections. Requires P:NLog.Targets.NetworkTarget.KeepConnection = false - - - - - Type of compression for protocol payload. Useful for UDP where datagram max-size is 8192 bytes. - - - - - Skip compression when protocol payload is below limit to reduce overhead in cpu-usage and additional headers - - - - - Maximum message size in bytes. On limit breach then P:NLog.Targets.NetworkTarget.OnOverflow action is activated. - - - - - Encoding to be used. - - - - - End of line value if a newline is appended at the end of log message P:NLog.Targets.NetworkTarget.NewLine. - - - - - Indicates whether to append newline at the end of log message. - - - - - - - - - - - - - - - - Name of the target. - - - - - Layout used to format log messages. - - - - - Indicates whether to perform layout calculation. - - - - - - - - - - - - - - - - Name of the target. - - - - - Default filter to be applied when no specific rule matches. - - - - - - - - - - - - - Condition to be tested. - - - - - Resulting filter to be applied when the condition matches. - - - - - - - - - - - - Name of the target. - - - - - - - - - - - - - - - Name of the target. - - - - - Number of times to repeat each log message. - - - - - - - - - - - - - - - - - Name of the target. - - - - - Whether to enable batching, and only apply single delay when a whole batch fails - - - - - Number of retries that should be attempted on the wrapped target in case of a failure. - - - - - Time to wait between retries in milliseconds. - - - - - - - - - - - - - - Name of the target. - - - - - - - - - - - - - - Name of the target. - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Text to be rendered. - - - - - Header. - - - - - Footer. - - - - - Forward F:NLog.LogLevel.Fatal to M:System.Diagnostics.Trace.Fail(System.String) (Instead of M:System.Diagnostics.Trace.TraceError(System.String)) - - - - - Force use M:System.Diagnostics.Trace.WriteLine(System.String) independent of T:NLog.LogLevel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the target. - - - - - Indicates whether to pre-authenticate the HttpWebRequest (Requires 'Authorization' in P:NLog.Targets.WebServiceTarget.Headers parameters) - - - - - Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs) - - - - - Value whether escaping be done according to the old NLog style (Very non-standard) - - - - - Value of the User-agent HTTP header. - - - - - Web service URL. - - - - - Proxy configuration when calling web service - - - - - Custom proxy address, include port separated by a colon - - - - - Protocol to be used when calling web service. - - - - - Web service namespace. Only used with Soap. - - - - - Web service method name. Only used with Soap. - - - - - Should we include the BOM (Byte-order-mark) for UTF? Influences the P:NLog.Targets.WebServiceTarget.Encoding property. This will only work for UTF-8. - - - - - Encoding. - - - - - Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see P:NLog.Targets.WebServiceTarget.Protocol and F:NLog.Targets.WebServiceProtocol.XmlPost). - - - - - (optional) root namespace of the XML document, if POST of XML document chosen. (see P:NLog.Targets.WebServiceTarget.Protocol and F:NLog.Targets.WebServiceProtocol.XmlPost). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom'). - - - - - Column delimiter. - - - - - Footer layout. - - - - - Header layout. - - - - - Body layout (can be repeated multiple times). - - - - - Quote Character. - - - - - Quoting mode. - - - - - Indicates whether CVS should include header. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the column. - - - - - Layout of the column. - - - - - Override of Quoting mode - - - - - - - - - - - - - - Option to render the empty object value {} - - - - - Option to suppress the extra spaces in the output json - - - - - - - - - - - - - - - - - - - - - - - Option to include all properties from the log event (as JSON) - - - - - Indicates whether to include contents of the T:NLog.GlobalDiagnosticsContext dictionary. - - - - - Whether to include the contents of the T:NLog.ScopeContext dictionary. - - - - - Should forward slashes be escaped? If true, / will be converted to \/ - - - - - Option to exclude null/empty properties from the log event (as JSON) - - - - - List of property names to exclude when P:NLog.Layouts.JsonLayout.IncludeAllProperties is true - - - - - How far should the JSON serializer follow object references before backing off - - - - - Option to render the empty object value {} - - - - - Option to suppress the extra spaces in the output json - - - - - - - - - - - - - - - - - - - Name of the attribute. - - - - - Layout that will be rendered as the attribute's value. - - - - - Fallback value when result value is not available - - - - - Determines whether or not this attribute will be Json encoded. - - - - - Should forward slashes be escaped? If true, / will be converted to \/ - - - - - Indicates whether to escape non-ascii characters - - - - - Whether an attribute with empty value should be included in the output - - - - - Result value type, for conversion of layout rendering output - - - - - - - - - - - - - - Footer layout. - - - - - Header layout. - - - - - Body layout (can be repeated multiple times). - - - - - - - - - - - - - - - - - - - - - - - Option to include all properties from the log events - - - - - Whether to include log4j:NDC in output from T:NLog.ScopeContext nested context. - - - - - Whether to include log4j:NDC in output from T:NLog.ScopeContext nested context. - - - - - Whether to include the contents of the T:NLog.ScopeContext properties-dictionary. - - - - - AppInfo field. By default it's the friendly name of the current AppDomain. - - - - - Indicates whether to include call site (class and method name) in the information sent over the network. - - - - - Indicates whether to include source info (file name and line number) in the information sent over the network. - - - - - Log4j:event logger-xml-attribute (Default ${logger}) - - - - - Whether the log4j:throwable xml-element should be written as CDATA - - - - - - - - - - - - - - Layout text. - - - - - - - - - - - - - - - - - - - - - - - - - - - - Name of the root XML element - - - - - Value inside the root XML element - - - - - Whether to include the contents of the T:NLog.ScopeContext dictionary. - - - - - Determines whether or not this attribute will be Xml encoded. - - - - - List of property names to exclude when P:NLog.Layouts.XmlElementBase.IncludeAllProperties is true - - - - - Whether a ElementValue with empty value should be included in the output - - - - - Auto indent and create new lines - - - - - How far should the XML serializer follow object references before backing off - - - - - XML element name to use for rendering IList-collections items - - - - - XML attribute name to use when rendering property-key When null (or empty) then key-attribute is not included - - - - - XML element name to use when rendering properties - - - - - XML attribute name to use when rendering property-value When null (or empty) then value-attribute is not included and value is formatted as XML-element-value - - - - - Option to include all properties from the log event (as XML) - - - - - - - - - - - - - - - - - Name of the attribute. - - - - - Layout that will be rendered as the attribute's value. - - - - - Fallback value when result value is not available - - - - - Determines whether or not this attribute will be Xml encoded. - - - - - Whether an attribute with empty value should be included in the output - - - - - Result value type, for conversion of layout rendering output - - - - - - - - - - - - - - - - - - - - - - - - Name of the element - - - - - Whether to include the contents of the T:NLog.ScopeContext dictionary. - - - - - Value inside the element - - - - - Determines whether or not this attribute will be Xml encoded. - - - - - List of property names to exclude when P:NLog.Layouts.XmlElementBase.IncludeAllProperties is true - - - - - Whether a ElementValue with empty value should be included in the output - - - - - Auto indent and create new lines - - - - - How far should the XML serializer follow object references before backing off - - - - - XML element name to use for rendering IList-collections items - - - - - XML attribute name to use when rendering property-key When null (or empty) then key-attribute is not included - - - - - XML element name to use when rendering properties - - - - - XML attribute name to use when rendering property-value When null (or empty) then value-attribute is not included and value is formatted as XML-element-value - - - - - Option to include all properties from the log event (as XML) - - - - - - - - - - - - - Action to be taken when filter matches. - - - - - Condition expression. - - - - - - - - - - - - - - - - - - - - - - - - - - Action to be taken when filter matches. - - - - - Indicates whether to ignore case when comparing strings. - - - - - Layout to be used to filter log messages. - - - - - Substring to be matched. - - - - - - - - - - - - - - - - - Action to be taken when filter matches. - - - - - String to compare the layout to. - - - - - Indicates whether to ignore case when comparing strings. - - - - - Layout to be used to filter log messages. - - - - - - - - - - - - - - - - - Action to be taken when filter matches. - - - - - Indicates whether to ignore case when comparing strings. - - - - - Layout to be used to filter log messages. - - - - - Substring to be matched. - - - - - - - - - - - - - - - - - Action to be taken when filter matches. - - - - - String to compare the layout to. - - - - - Indicates whether to ignore case when comparing strings. - - - - - Layout to be used to filter log messages. - - - - - - - - - - - - - - - - - - - - - - - Action to be taken when filter matches. - - - - - Append FilterCount to the P:NLog.LogEventInfo.Message when an event is no longer filtered - - - - - Insert FilterCount value into P:NLog.LogEventInfo.Properties when an event is no longer filtered - - - - - Applies the configured action to the initial logevent that starts the timeout period. Used to configure that it should ignore all events until timeout. - - - - - Layout to be used to filter log messages. - - - - - Max length of filter values, will truncate if above limit - - - - - How long before a filter expires, and logging is accepted again - - - - - Default number of unique filter values to expect, will automatically increase if needed - - - - - Max number of unique filter values to expect simultaneously - - - - - Default buffer size for the internal buffers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Fantasy/Fantasy.Packages/Fantasy.NLog/icon.png b/Fantasy/Fantasy.Packages/Fantasy.NLog/icon.png deleted file mode 100644 index 8ae7488..0000000 Binary files a/Fantasy/Fantasy.Packages/Fantasy.NLog/icon.png and /dev/null differ diff --git a/Fantasy/Fantays.Console/Fantasy.Console.csproj b/Fantasy/Fantays.Console/Fantasy.Console.csproj deleted file mode 100644 index ad2a092..0000000 --- a/Fantasy/Fantays.Console/Fantasy.Console.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - enable - enable - net8.0;net9.0 - default - - - - TRACE;FANTASY_CONSOLE - true - true - - - - TRACE;FANTASY_CONSOLE - true - - - - - - - - - - - - - diff --git a/Fantasy/Fantays.Console/Runtime/Core/Assembly/AssemblyInfo.cs b/Fantasy/Fantays.Console/Runtime/Core/Assembly/AssemblyInfo.cs deleted file mode 100644 index 3957539..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Assembly/AssemblyInfo.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Fantasy.DataStructure.Collection; - -// ReSharper disable CollectionNeverQueried.Global -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Assembly -{ - /// - /// AssemblyInfo提供有关程序集和类型的信息 - /// - public sealed class AssemblyInfo - { - /// - /// 唯一标识 - /// - public readonly long AssemblyIdentity; - /// - /// 获取或设置与此程序集相关联的 实例。 - /// - public System.Reflection.Assembly Assembly { get; private set; } - /// - /// 程序集类型集合,获取一个列表,包含从程序集加载的所有类型。 - /// - public readonly List AssemblyTypeList = new List(); - /// - /// 程序集类型分组集合,获取一个分组列表,将接口类型映射到实现这些接口的类型。 - /// - public readonly OneToManyList AssemblyTypeGroupList = new OneToManyList(); - - /// - /// 初始化 类的新实例。 - /// - /// - public AssemblyInfo(long assemblyIdentity) - { - AssemblyIdentity = assemblyIdentity; - } - - /// - /// 从指定的程序集加载类型信息并进行分类。 - /// - /// 要加载信息的程序集。 - public void Load(System.Reflection.Assembly assembly) - { - Assembly = assembly; - var assemblyTypes = assembly.GetTypes().ToList(); - - foreach (var type in assemblyTypes) - { - if (type.IsAbstract || type.IsInterface) - { - continue; - } - - var interfaces = type.GetInterfaces(); - - foreach (var interfaceType in interfaces) - { - AssemblyTypeGroupList.Add(interfaceType, type); - } - } - - AssemblyTypeList.AddRange(assemblyTypes); - } - - /// - /// 重新加载程序集的类型信息。 - /// - /// - public void ReLoad(System.Reflection.Assembly assembly) - { - Unload(); - Load(assembly); - } - - /// - /// 卸载程序集的类型信息。 - /// - public void Unload() - { - AssemblyTypeList.Clear(); - AssemblyTypeGroupList.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Assembly/AssemblySystem.cs b/Fantasy/Fantays.Console/Runtime/Core/Assembly/AssemblySystem.cs deleted file mode 100644 index deb9da6..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Assembly/AssemblySystem.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Security.Cryptography; -using System.Text; -using Fantasy.Async; -using Fantasy.Helper; -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8603 -#pragma warning disable CS8618 -namespace Fantasy.Assembly -{ - /// - /// 管理程序集加载和卸载的帮助类。 - /// - public static class AssemblySystem - { -#if FANTASY_WEBGL - private static readonly List AssemblySystems = new List(); - private static readonly Dictionary AssemblyList = new Dictionary(); -#else - private static readonly ConcurrentQueue AssemblySystems = new ConcurrentQueue(); - private static readonly ConcurrentDictionary AssemblyList = new ConcurrentDictionary(); -#endif - /// - /// 初始化 AssemblySystem。(仅限内部) - /// - /// - internal static async FTask InnerInitialize(params System.Reflection.Assembly[] assemblies) - { - await LoadAssembly(typeof(AssemblySystem).Assembly); - foreach (var assembly in assemblies) - { - await LoadAssembly(assembly); - } - } - - /// - /// 加载指定的程序集,并触发相应的事件。 - /// - /// 要加载的程序集。 - /// 如果当前Domain中已经存在同名的Assembly,使用Domain中的程序集。 - public static async FTask LoadAssembly(System.Reflection.Assembly assembly, bool isCurrentDomain = true) - { - if (isCurrentDomain) - { - var currentDomainAssemblies = System.AppDomain.CurrentDomain.GetAssemblies(); - var currentAssembly = currentDomainAssemblies.FirstOrDefault(d => d.GetName().Name == assembly.GetName().Name); - if (currentAssembly != null) - { - assembly = currentAssembly; - } - } - - var assemblyIdentity = AssemblyIdentity(assembly); - - if (AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo)) - { - assemblyInfo.ReLoad(assembly); - foreach (var assemblySystem in AssemblySystems) - { - await assemblySystem.ReLoad(assemblyIdentity); - } - } - else - { - assemblyInfo = new AssemblyInfo(assemblyIdentity); - assemblyInfo.Load(assembly); - AssemblyList.TryAdd(assemblyIdentity, assemblyInfo); - foreach (var assemblySystem in AssemblySystems) - { - await assemblySystem.Load(assemblyIdentity); - } - } - } - - /// - /// 卸载程序集 - /// - /// - public static async FTask UnLoadAssembly(System.Reflection.Assembly assembly) - { - var assemblyIdentity = AssemblyIdentity(assembly); - - if (!AssemblyList.Remove(assemblyIdentity, out var assemblyInfo)) - { - return; - } - - assemblyInfo.Unload(); - foreach (var assemblySystem in AssemblySystems) - { - await assemblySystem.OnUnLoad(assemblyIdentity); - } - } - - /// - /// 将AssemblySystem接口的object注册到程序集管理中心 - /// - /// - public static async FTask Register(object obj) - { - if (obj is not IAssembly assemblySystem) - { - return; - } -#if FANTASY_WEBGL - AssemblySystems.Add(assemblySystem); -#else - AssemblySystems.Enqueue(assemblySystem); -#endif - foreach (var (assemblyIdentity, _) in AssemblyList) - { - await assemblySystem.Load(assemblyIdentity); - } - } - - /// - /// 程序集管理中心卸载注册的Load、ReLoad、UnLoad的接口 - /// - /// - public static void UnRegister(object obj) - { - if (obj is not IAssembly assemblySystem) - { - return; - } -#if FANTASY_WEBGL - AssemblySystems.Remove(assemblySystem); -#else - var count = AssemblySystems.Count; - - for (var i = 0; i < count; i++) - { - if (!AssemblySystems.TryDequeue(out var removeAssemblySystem)) - { - continue; - } - - if (removeAssemblySystem == assemblySystem) - { - break; - } - - AssemblySystems.Enqueue(removeAssemblySystem); - } -#endif - } - - /// - /// 获取所有已加载程序集中的所有类型。 - /// - /// 所有已加载程序集中的类型。 - public static IEnumerable ForEach() - { - foreach (var (_, assemblyInfo) in AssemblyList) - { - foreach (var type in assemblyInfo.AssemblyTypeList) - { - yield return type; - } - } - } - - /// - /// 获取指定程序集中的所有类型。 - /// - /// 程序集唯一标识。 - /// 指定程序集中的类型。 - public static IEnumerable ForEach(long assemblyIdentity) - { - if (!AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo)) - { - yield break; - } - - foreach (var type in assemblyInfo.AssemblyTypeList) - { - yield return type; - } - } - - /// - /// 获取所有已加载程序集中实现指定类型的所有类型。 - /// - /// 要查找的基类或接口类型。 - /// 所有已加载程序集中实现指定类型的类型。 - public static IEnumerable ForEach(Type findType) - { - foreach (var (_, assemblyInfo) in AssemblyList) - { - if (!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType, out var assemblyLoad)) - { - continue; - } - - foreach (var type in assemblyLoad) - { - yield return type; - } - } - } - - /// - /// 获取指定程序集中实现指定类型的所有类型。 - /// - /// 程序集唯一标识。 - /// 要查找的基类或接口类型。 - /// 指定程序集中实现指定类型的类型。 - public static IEnumerable ForEach(long assemblyIdentity, Type findType) - { - if (!AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo)) - { - yield break; - } - - if (!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType, out var assemblyLoad)) - { - yield break; - } - - foreach (var type in assemblyLoad) - { - yield return type; - } - } - - /// - /// 获取指定程序集的实例。 - /// - /// 程序集名称。 - /// 指定程序集的实例,如果未加载则返回 null。 - public static System.Reflection.Assembly GetAssembly(long assemblyIdentity) - { - return !AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo) ? null : assemblyInfo.Assembly; - } - - /// - /// 获取当前框架注册的Assembly - /// - /// - public static IEnumerable ForEachAssembly - { - get - { - foreach (var (_, assemblyInfo) in AssemblyList) - { - yield return assemblyInfo.Assembly; - } - } - } - - /// - /// 根据Assembly的强命名计算唯一标识。 - /// - /// - /// - private static long AssemblyIdentity(System.Reflection.Assembly assembly) - { - return HashCodeHelper.ComputeHash64(assembly.GetName().Name); - } - - /// - /// 释放资源,卸载所有加载的程序集。 - /// - public static void Dispose() - { - DisposeAsync().Coroutine(); - } - - private static async FTask DisposeAsync() - { - foreach (var (_, assemblyInfo) in AssemblyList.ToArray()) - { - await UnLoadAssembly(assemblyInfo.Assembly); - } - - AssemblyList.Clear(); - AssemblySystems.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Assembly/IAssembly.cs b/Fantasy/Fantays.Console/Runtime/Core/Assembly/IAssembly.cs deleted file mode 100644 index 185e037..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Assembly/IAssembly.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Assembly -{ - /// - /// 实现这个接口、会再程序集首次加载、卸载、重载的时候调用 - /// - public interface IAssembly : IDisposable - { - /// - /// 程序集加载时调用 - /// - /// 程序集标识 - public FTask Load(long assemblyIdentity); - /// - /// 程序集重新加载的时候调用 - /// - /// 程序集标识 - public FTask ReLoad(long assemblyIdentity); - /// - /// 卸载的时候调用 - /// - /// 程序集标识 - public FTask OnUnLoad(long assemblyIdentity); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Benchmark/Handler/BenchmarkRequestHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Benchmark/Handler/BenchmarkRequestHandler.cs deleted file mode 100644 index 8532547..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Benchmark/Handler/BenchmarkRequestHandler.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Benchmark.Handler; - -/// -/// BenchmarkRequestHandler -/// -public sealed class BenchmarkRequestHandler : MessageRPC -{ - /// - /// Run方法 - /// - /// - /// - /// - /// - protected override async FTask Run(Session session, BenchmarkRequest request, BenchmarkResponse response, Action reply) - { - await FTask.CompletedTask; - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataBase/DataBaseType.cs b/Fantasy/Fantays.Console/Runtime/Core/DataBase/DataBaseType.cs deleted file mode 100644 index 2fb03ec..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataBase/DataBaseType.cs +++ /dev/null @@ -1,20 +0,0 @@ -// ReSharper disable CheckNamespace -// ReSharper disable InconsistentNaming -#if FANTASY_NET -namespace Fantasy.DataBase; - -/// -/// 数据库类型 -/// -public enum DataBaseType -{ - /// - /// 默认 - /// - None = 0, - /// - /// MongoDB - /// - MongoDB = 1 -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataBase/IDataBase.cs b/Fantasy/Fantays.Console/Runtime/Core/DataBase/IDataBase.cs deleted file mode 100644 index 6a2fe8b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataBase/IDataBase.cs +++ /dev/null @@ -1,210 +0,0 @@ -#if FANTASY_NET -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using Fantasy.Async; -using Fantasy.Entitas; -using MongoDB.Driver; -// ReSharper disable InconsistentNaming -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -#pragma warning disable CS8625 - -namespace Fantasy.DataBase -{ - /// - /// 数据库设置助手 - /// - public static class DataBaseSetting - { - /// - /// 初始化自定义委托,当设置了这个委托后,就不会自动创建MongoClient,需要自己在委托里创建MongoClient。 - /// - public static Func? MongoDBCustomInitialize; - } - - /// - /// MongoDB自定义连接参数 - /// - public sealed class DataBaseCustomConfig - { - /// - /// 当前Scene - /// - public Scene Scene; - /// - /// 连接字符串 - /// - public string ConnectionString; - /// - /// 数据库名字 - /// - public string DBName; - } - - /// - /// 表示用于执行各种数据库操作的数据库接口。 - /// - public interface IDataBase : IDisposable - { - /// - /// 获得当前数据的类型 - /// - public DataBaseType GetDataBaseType { get;} - /// - /// 获得对应数据的操作实例 - /// - /// 如MongoDB就是IMongoDatabase - public object GetDataBaseInstance { get;} - /// - /// 初始化数据库连接。 - /// - IDataBase Initialize(Scene scene, string connectionString, string dbName); - /// - /// 在指定的集合中检索类型 的实体数量。 - /// - FTask Count(string collection = null) where T : Entity; - /// - /// 在指定的集合中检索满足给定筛选条件的类型 的实体数量。 - /// - FTask Count(Expression> filter, string collection = null) where T : Entity; - /// - /// 检查指定集合中是否存在类型 的实体。 - /// - FTask Exist(string collection = null) where T : Entity; - /// - /// 检查指定集合中是否存在满足给定筛选条件的类型 的实体。 - /// - FTask Exist(Expression> filter, string collection = null) where T : Entity; - /// - /// 从指定集合中检索指定 ID 的类型 的实体,不锁定。 - /// - FTask QueryNotLock(long id, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 从指定集合中检索指定 ID 的类型 的实体。 - /// - FTask Query(long id, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 按页查询满足给定筛选条件的类型 的实体数量和日期。 - /// - FTask<(int count, List dates)> QueryCountAndDatesByPage(Expression> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 按页查询满足给定筛选条件的类型 的实体数量和日期。 - /// - FTask<(int count, List dates)> QueryCountAndDatesByPage(Expression> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 分页查询指定集合中满足给定筛选条件的类型 的实体列表。 - /// - FTask> QueryByPage(Expression> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 分页查询指定集合中满足给定筛选条件的类型 的实体列表,仅返回指定列的数据。 - /// - FTask> QueryByPage(Expression> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 从指定集合中按页查询满足给定筛选条件的类型 的实体列表,按指定字段排序。 - /// - FTask> QueryByPageOrderBy(Expression> filter, int pageIndex, int pageSize, Expression> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 检索满足给定筛选条件的类型 的第一个实体,从指定集合中。 - /// - FTask First(Expression> filter, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 查询指定集合中满足给定 JSON 查询字符串的类型 的第一个实体,仅返回指定列的数据。 - /// - FTask First(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 从指定集合中按页查询满足给定筛选条件的类型 的实体列表,按指定字段排序。 - /// - FTask> QueryOrderBy(Expression> filter, Expression> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 从指定集合中按页查询满足给定筛选条件的类型 的实体列表。 - /// - FTask> Query(Expression> filter, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 查询指定集合中满足给定筛选条件的类型 实体列表,仅返回指定字段的数据。 - /// - FTask> Query(Expression> filter, Expression>[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 查询指定 ID 的多个集合,将结果存储在给定的实体列表中。 - /// - FTask Query(long id, List collectionNames, List result, bool isDeserialize = false); - /// - /// 根据给定的 JSON 查询字符串查询指定集合中的类型 实体列表。 - /// - FTask> QueryJson(string json, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 根据给定的 JSON 查询字符串查询指定集合中的类型 实体列表,仅返回指定列的数据。 - /// - FTask> QueryJson(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 根据给定的 JSON 查询字符串查询指定集合中的类型 实体列表,通过指定的任务 ID 进行标识。 - /// - FTask> QueryJson(long taskId, string json, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 查询指定集合中满足给定筛选条件的类型 实体列表,仅返回指定列的数据。 - /// - FTask> Query(Expression> filter, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity; - /// - /// 保存类型 实体到指定集合中,如果集合不存在将自动创建。 - /// - FTask Save(T entity, string collection = null) where T : Entity, new(); - /// - /// 保存一组实体到数据库中,根据实体列表的 ID 进行区分和存储。 - /// - FTask Save(long id, List entities); - /// - /// 通过事务会话将类型 实体保存到指定集合中,如果集合不存在将自动创建。 - /// - FTask Save(object transactionSession, T entity, string collection = null) where T : Entity; - /// - /// 向指定集合中插入一个类型 实体,如果集合不存在将自动创建。 - /// - FTask Insert(T entity, string collection = null) where T : Entity, new(); - /// - /// 批量插入一组类型 实体到指定集合中,如果集合不存在将自动创建。 - /// - FTask InsertBatch(IEnumerable list, string collection = null) where T : Entity, new(); - /// - /// 通过事务会话,批量插入一组类型 实体到指定集合中,如果集合不存在将自动创建。 - /// - FTask InsertBatch(object transactionSession, IEnumerable list, string collection = null) where T : Entity, new(); - /// - /// 通过事务会话,根据指定的 ID 从数据库中删除指定类型 实体。 - /// - FTask Remove(object transactionSession, long id, string collection = null) where T : Entity, new(); - /// - /// 根据指定的 ID 从数据库中删除指定类型 实体。 - /// - FTask Remove(long id, string collection = null) where T : Entity, new(); - /// - /// 通过事务会话,根据给定的筛选条件从数据库中删除指定类型 实体。 - /// - FTask Remove(long coroutineLockQueueKey, object transactionSession, Expression> filter, string collection = null) where T : Entity, new(); - /// - /// 根据给定的筛选条件从数据库中删除指定类型 实体。 - /// - FTask Remove(long coroutineLockQueueKey, Expression> filter, string collection = null) where T : Entity, new(); - /// - /// 根据给定的筛选条件计算指定集合中类型 实体某个属性的总和。 - /// - FTask Sum(Expression> filter, Expression> sumExpression, string collection = null) where T : Entity; - /// - /// 在指定的集合中创建索引,以提高类型 实体的查询性能。 - /// - FTask CreateIndex(string collection, params object[] keys) where T : Entity; - /// - /// 在默认集合中创建索引,以提高类型 实体的查询性能。 - /// - FTask CreateIndex(params object[] keys) where T : Entity; - /// - /// 创建指定类型 的数据库,用于存储实体。 - /// - FTask CreateDB() where T : Entity; - /// - /// 根据指定类型创建数据库,用于存储实体。 - /// - FTask CreateDB(Type type); - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataBase/MongoDataBase.cs b/Fantasy/Fantays.Console/Runtime/Core/DataBase/MongoDataBase.cs deleted file mode 100644 index 49948f4..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataBase/MongoDataBase.cs +++ /dev/null @@ -1,1081 +0,0 @@ -#if FANTASY_NET -using System.Linq.Expressions; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; -using Fantasy.Helper; -using Fantasy.Serialize; -using MongoDB.Bson; -using MongoDB.Driver; -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.DataBase -{ - /// - /// 使用 MongoDB 数据库的实现。 - /// - public sealed class MongoDataBase : IDataBase - { - private const int DefaultTaskSize = 1024; - private Scene _scene; - private MongoClient _mongoClient; - private ISerialize _serializer; - private IMongoDatabase _mongoDatabase; - private CoroutineLock _dataBaseLock; - private readonly HashSet _collections = new HashSet(); - /// - /// 获得当前数据的类型 - /// - public DataBaseType GetDataBaseType { get; } = DataBaseType.MongoDB; - /// - /// 获得对应数据的操作实例 - /// - public object GetDataBaseInstance => _mongoDatabase; - /// - /// 初始化 MongoDB 数据库连接并记录所有集合名。 - /// - /// 场景对象。 - /// 数据库连接字符串。 - /// 数据库名称。 - /// 初始化后的数据库实例。 - public IDataBase Initialize(Scene scene, string connectionString, string dbName) - { - _scene = scene; - _mongoClient = DataBaseSetting.MongoDBCustomInitialize != null - ? DataBaseSetting.MongoDBCustomInitialize(new DataBaseCustomConfig() - { - Scene = scene, ConnectionString = connectionString, DBName = dbName - }) - : new MongoClient(connectionString); - _mongoDatabase = _mongoClient.GetDatabase(dbName); - _dataBaseLock = scene.CoroutineLockComponent.Create(GetType().TypeHandle.Value.ToInt64()); - // 记录所有集合名 - _collections.UnionWith(_mongoDatabase.ListCollectionNames().ToList()); - _serializer = SerializerManager.GetSerializer(FantasySerializerType.Bson); - return this; - } - - /// - /// 销毁释放资源。 - /// - public void Dispose() - { - // 优先释放协程锁。 - _dataBaseLock.Dispose(); - // 清理资源。 - _scene = null; - _serializer = null; - _mongoDatabase = null; - _dataBaseLock = null; - _collections.Clear(); - _mongoClient.Dispose(); - } - - #region Other - - /// - /// 对满足条件的文档中的某个数值字段进行求和操作。 - /// - /// 实体类型。 - /// 用于筛选文档的表达式。 - /// 要对其进行求和的字段表达式。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 满足条件的文档中指定字段的求和结果。 - public async FTask Sum(Expression> filter, Expression> sumExpression, string collection = null) where T : Entity - { - var member = (MemberExpression)((UnaryExpression)sumExpression.Body).Operand; - var projection = new BsonDocument("_id", "null").Add("Result", new BsonDocument("$sum", $"${member.Member.Name}")); - var data = await GetCollection(collection).Aggregate().Match(filter).Group(projection).FirstOrDefaultAsync(); - return data == null ? 0 : Convert.ToInt64(data["Result"]); - } - - #endregion - - #region GetCollection - - /// - /// 获取指定集合中的 MongoDB 文档的 IMongoCollection 对象。 - /// - /// 实体类型。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// IMongoCollection 对象。 - private IMongoCollection GetCollection(string collection = null) - { - return _mongoDatabase.GetCollection(collection ?? typeof(T).Name); - } - - /// - /// 获取指定集合中的 MongoDB 文档的 IMongoCollection 对象,其中实体类型为 Entity。 - /// - /// 集合名称。 - /// IMongoCollection 对象。 - private IMongoCollection GetCollection(string name) - { - return _mongoDatabase.GetCollection(name); - } - - #endregion - - #region Count - - /// - /// 统计指定集合中满足条件的文档数量。 - /// - /// 实体类型。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 满足条件的文档数量。 - public async FTask Count(string collection = null) where T : Entity - { - return await GetCollection(collection).CountDocumentsAsync(d => true); - } - - /// - /// 统计指定集合中满足条件的文档数量。 - /// - /// 实体类型。 - /// 用于筛选文档的表达式。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 满足条件的文档数量。 - public async FTask Count(Expression> filter, string collection = null) where T : Entity - { - return await GetCollection(collection).CountDocumentsAsync(filter); - } - - #endregion - - #region Exist - - /// - /// 判断指定集合中是否存在文档。 - /// - /// 实体类型。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 如果存在文档则返回 true,否则返回 false。 - public async FTask Exist(string collection = null) where T : Entity - { - return await Count(collection) > 0; - } - - /// - /// 判断指定集合中是否存在满足条件的文档。 - /// - /// 实体类型。 - /// 用于筛选文档的表达式。 - /// 集合名称,可选。如果未指定,将使用实体类型的名称。 - /// 如果存在满足条件的文档则返回 true,否则返回 false。 - public async FTask Exist(Expression> filter, string collection = null) where T : Entity - { - return await Count(filter, collection) > 0; - } - - #endregion - - #region Query - - /// - /// 在不加数据库锁定的情况下,查询指定 ID 的文档。 - /// - /// 文档实体类型。 - /// 要查询的文档 ID。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 查询到的文档。 - public async FTask QueryNotLock(long id, bool isDeserialize = false, string collection = null) where T : Entity - { - var cursor = await GetCollection(collection).FindAsync(d => d.Id == id); - var v = await cursor.FirstOrDefaultAsync(); - - if (isDeserialize && v != null) - { - v.Deserialize(_scene); - } - - return v; - } - - /// - /// 查询指定 ID 的文档,并加数据库锁定以确保数据一致性。 - /// - /// 文档实体类型。 - /// 要查询的文档 ID。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 查询到的文档。 - public async FTask Query(long id, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(id)) - { - var cursor = await GetCollection(collection).FindAsync(d => d.Id == id); - var v = await cursor.FirstOrDefaultAsync(); - - if (isDeserialize && v != null) - { - v.Deserialize(_scene); - } - - return v; - } - } - - /// - /// 通过分页查询并返回满足条件的文档数量和日期列表(不加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档数量和日期列表。 - public async FTask<(int count, List dates)> QueryCountAndDatesByPage(Expression> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var count = await Count(filter); - var dates = await QueryByPage(filter, pageIndex, pageSize, isDeserialize, collection); - return ((int)count, dates); - } - } - - /// - /// 通过分页查询并返回满足条件的文档数量和日期列表(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档数量和日期列表。 - public async FTask<(int count, List dates)> QueryCountAndDatesByPage(Expression> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var count = await Count(filter); - var dates = await QueryByPage(filter, pageIndex, pageSize, cols, isDeserialize, collection); - return ((int)count, dates); - } - } - - /// - /// 通过分页查询并返回满足条件的文档列表(不加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryByPage(Expression> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var list = await GetCollection(collection).Find(filter).Skip((pageIndex - 1) * pageSize) - .Limit(pageSize) - .ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 通过分页查询并返回满足条件的文档列表(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryByPage(Expression> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include(""); - - foreach (var col in cols) - { - projection = projection.Include(col); - } - - var list = await GetCollection(collection).Find(filter).Project(projection) - .Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 通过分页查询并返回满足条件的文档列表,并按指定表达式进行排序(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 页码。 - /// 每页大小。 - /// 排序表达式。 - /// 是否升序排序。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryByPageOrderBy(Expression> filter, int pageIndex, int pageSize, Expression> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - List list; - - if (isAsc) - { - list = await GetCollection(collection).Find(filter).SortBy(orderByExpression).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); - } - else - { - list = await GetCollection(collection).Find(filter).SortByDescending(orderByExpression).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); - } - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 通过指定过滤条件查询并返回满足条件的第一个文档(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的第一个文档,如果未找到则为 null。 - public async FTask First(Expression> filter, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var cursor = await GetCollection(collection).FindAsync(filter); - var t = await cursor.FirstOrDefaultAsync(); - - if (isDeserialize && t != null) - { - t.Deserialize(_scene); - } - - return t; - } - } - - /// - /// 通过指定 JSON 格式查询并返回满足条件的第一个文档(加锁)。 - /// - /// 文档实体类型。 - /// JSON 查询条件。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的第一个文档。 - public async FTask First(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include(""); - - foreach (var col in cols) - { - projection = projection.Include(col); - } - - var options = new FindOptions { Projection = projection }; - - FilterDefinition filterDefinition = new JsonFilterDefinition(json); - - var cursor = await GetCollection(collection).FindAsync(filterDefinition, options); - var t = await cursor.FirstOrDefaultAsync(); - - if (isDeserialize && t != null) - { - t.Deserialize(_scene); - } - - return t; - } - } - - /// - /// 通过指定过滤条件查询并返回满足条件的文档列表,并按指定表达式进行排序(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 排序表达式。 - /// 是否升序排序。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryOrderBy(Expression> filter, Expression> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - List list; - - if (isAsc) - { - list = await GetCollection(collection).Find(filter).SortBy(orderByExpression).ToListAsync(); - } - else - { - list = await GetCollection(collection).Find(filter).SortByDescending(orderByExpression).ToListAsync(); - } - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 通过指定过滤条件查询并返回满足条件的文档列表(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> Query(Expression> filter, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var cursor = await GetCollection(collection).FindAsync(filter); - var list = await cursor.ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定 ID 加锁查询多个集合中的文档。 - /// - /// 文档 ID。 - /// 要查询的集合名称列表。 - /// 查询结果存储列表。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - public async FTask Query(long id, List? collectionNames, List result, bool isDeserialize = false) - { - using (await _dataBaseLock.Wait(id)) - { - if (collectionNames == null || collectionNames.Count == 0) - { - return; - } - - foreach (var collectionName in collectionNames) - { - var cursor = await GetCollection(collectionName).FindAsync(d => d.Id == id); - - var e = await cursor.FirstOrDefaultAsync(); - - if (e == null) - { - continue; - } - - if (isDeserialize) - { - e.Deserialize(_scene); - } - - result.Add(e); - } - } - } - - /// - /// 根据指定的 JSON 查询条件查询并返回满足条件的文档列表(加锁)。 - /// - /// 文档实体类型。 - /// JSON 查询条件。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryJson(string json, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - FilterDefinition filterDefinition = new JsonFilterDefinition(json); - var cursor = await GetCollection(collection).FindAsync(filterDefinition); - var list = await cursor.ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定的 JSON 查询条件查询并返回满足条件的文档列表,并选择指定的列(加锁)。 - /// - /// 文档实体类型。 - /// JSON 查询条件。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryJson(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include(""); - - foreach (var col in cols) - { - projection = projection.Include(col); - } - - var options = new FindOptions { Projection = projection }; - - FilterDefinition filterDefinition = new JsonFilterDefinition(json); - - var cursor = await GetCollection(collection).FindAsync(filterDefinition, options); - var list = await cursor.ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定的 JSON 查询条件和任务 ID 查询并返回满足条件的文档列表(加锁)。 - /// - /// 文档实体类型。 - /// 任务 ID。 - /// JSON 查询条件。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> QueryJson(long taskId, string json, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(taskId)) - { - FilterDefinition filterDefinition = new JsonFilterDefinition(json); - var cursor = await GetCollection(collection).FindAsync(filterDefinition); - var list = await cursor.ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定过滤条件查询并返回满足条件的文档列表,选择指定的列(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// 满足条件的文档列表。 - public async FTask> Query(Expression> filter, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include("_id"); - - foreach (var t in cols) - { - projection = projection.Include(t); - } - - var list = await GetCollection(collection).Find(filter).Project(projection).ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - /// - /// 根据指定过滤条件查询并返回满足条件的文档列表,选择指定的列(加锁)。 - /// - /// 文档实体类型。 - /// 查询过滤条件。 - /// 要查询的列名称数组。 - /// 是否在查询后反序列化,执行反序列化后会自动将实体注册到框架系统中,并且能正常使用组件相关功能。 - /// 集合名称。 - /// - public async FTask> Query(Expression> filter, Expression>[] cols, bool isDeserialize = false, string collection = null) where T : Entity - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - var projection = Builders.Projection.Include("_id"); - - foreach (var col in cols) - { - if (col.Body is not MemberExpression memberExpression) - { - throw new ArgumentException("Lambda expression must be a member access expression."); - } - - projection = projection.Include(memberExpression.Member.Name); - } - - var list = await GetCollection(collection).Find(filter).Project(projection).ToListAsync(); - - if (!isDeserialize || list is not { Count: > 0 }) - { - return list; - } - - foreach (var entity in list) - { - entity.Deserialize(_scene); - } - - return list; - } - } - - #endregion - - #region Save - - /// - /// 保存实体对象到数据库(加锁)。 - /// - /// 实体类型。 - /// 事务会话对象。 - /// 要保存的实体对象。 - /// 集合名称。 - public async FTask Save(object transactionSession, T? entity, string collection = null) where T : Entity - { - if (entity == null) - { - Log.Error($"save entity is null: {typeof(T).Name}"); - return; - } - - var clone = _serializer.Clone(entity); - - using (await _dataBaseLock.Wait(clone.Id)) - { - await GetCollection(collection).ReplaceOneAsync( - (IClientSessionHandle)transactionSession, d => d.Id == clone.Id, clone, - new ReplaceOptions { IsUpsert = true }); - } - } - - /// - /// 保存实体对象到数据库(加锁)。 - /// - /// 实体类型。 - /// 要保存的实体对象。 - /// 集合名称。 - public async FTask Save(T? entity, string collection = null) where T : Entity, new() - { - if (entity == null) - { - Log.Error($"save entity is null: {typeof(T).Name}"); - - return; - } - - var clone = _serializer.Clone(entity); - - using (await _dataBaseLock.Wait(clone.Id)) - { - await GetCollection(collection).ReplaceOneAsync(d => d.Id == clone.Id, clone, new ReplaceOptions { IsUpsert = true }); - } - } - - /// - /// 保存实体对象到数据库(加锁)。 - /// - /// 保存的条件表达式。 - /// 实体类型。 - /// 集合名称。 - /// - public async FTask Save(Expression> filter, T? entity, string collection = null) where T : Entity, new() - { - if (entity == null) - { - Log.Error($"save entity is null: {typeof(T).Name}"); - return; - } - - T clone = _serializer.Clone(entity); - - using (await _dataBaseLock.Wait(clone.Id)) - { - await GetCollection(collection).ReplaceOneAsync(filter, clone, new ReplaceOptions { IsUpsert = true }); - } - } - - /// - /// 保存多个实体对象到数据库(加锁)。 - /// - /// 文档 ID。 - /// 要保存的实体对象列表。 - public async FTask Save(long id, List? entities) - { - if (entities == null || entities.Count == 0) - { - Log.Error("save entity is null"); - return; - } - - using var listPool = ListPool.Create(); - - foreach (var entity in entities) - { - listPool.Add(_serializer.Clone(entity)); - } - - using (await _dataBaseLock.Wait(id)) - { - foreach (var clone in listPool) - { - try - { - await GetCollection(clone.GetType().Name).ReplaceOneAsync(d => d.Id == clone.Id, clone, new ReplaceOptions { IsUpsert = true }); - } - catch (Exception e) - { - Log.Error($"Save List Entity Error: {clone.GetType().Name} {clone}\n{e}"); - } - } - } - } - - #endregion - - #region Insert - - /// - /// 插入单个实体对象到数据库(加锁)。 - /// - /// 实体类型。 - /// 要插入的实体对象。 - /// 集合名称。 - public async FTask Insert(T? entity, string collection = null) where T : Entity, new() - { - if (entity == null) - { - Log.Error($"insert entity is null: {typeof(T).Name}"); - return; - } - - var clone = _serializer.Clone(entity); - - using (await _dataBaseLock.Wait(entity.Id)) - { - await GetCollection(collection).InsertOneAsync(clone); - } - } - - /// - /// 批量插入实体对象列表到数据库(加锁)。 - /// - /// 实体类型。 - /// 要插入的实体对象列表。 - /// 集合名称。 - public async FTask InsertBatch(IEnumerable list, string collection = null) where T : Entity, new() - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - await GetCollection(collection).InsertManyAsync(list); - } - } - - /// - /// 批量插入实体对象列表到数据库(加锁)。 - /// - /// 实体类型。 - /// 事务会话对象。 - /// 要插入的实体对象列表。 - /// 集合名称。 - public async FTask InsertBatch(object transactionSession, IEnumerable list, string collection = null) - where T : Entity, new() - { - using (await _dataBaseLock.Wait(RandomHelper.RandInt64() % DefaultTaskSize)) - { - await GetCollection(collection).InsertManyAsync((IClientSessionHandle)transactionSession, list); - } - } - - /// - /// 插入BsonDocument到数据库(加锁)。 - /// - /// - /// - /// - public async Task Insert(BsonDocument bsonDocument, long taskId) where T : Entity - { - using (await _dataBaseLock.Wait(taskId)) - { - await GetCollection(typeof(T).Name).InsertOneAsync(bsonDocument); - } - } - - #endregion - - #region Remove - - /// - /// 根据ID删除单个实体对象(加锁)。 - /// - /// 实体类型。 - /// 事务会话对象。 - /// 要删除的实体的ID。 - /// 集合名称。 - /// 删除的实体数量。 - public async FTask Remove(object transactionSession, long id, string collection = null) - where T : Entity, new() - { - using (await _dataBaseLock.Wait(id)) - { - var result = await GetCollection(collection) - .DeleteOneAsync((IClientSessionHandle)transactionSession, d => d.Id == id); - return result.DeletedCount; - } - } - - /// - /// 根据ID删除单个实体对象(加锁)。 - /// - /// 实体类型。 - /// 要删除的实体的ID。 - /// 集合名称。 - /// 删除的实体数量。 - public async FTask Remove(long id, string collection = null) where T : Entity, new() - { - using (await _dataBaseLock.Wait(id)) - { - var result = await GetCollection(collection).DeleteOneAsync(d => d.Id == id); - return result.DeletedCount; - } - } - - /// - /// 根据ID和筛选条件删除多个实体对象(加锁)。 - /// - /// 实体类型。 - /// 异步锁Id。 - /// 事务会话对象。 - /// 筛选条件。 - /// 集合名称。 - /// 删除的实体数量。 - public async FTask Remove(long coroutineLockQueueKey, object transactionSession, - Expression> filter, string collection = null) where T : Entity, new() - { - using (await _dataBaseLock.Wait(coroutineLockQueueKey)) - { - var result = await GetCollection(collection) - .DeleteManyAsync((IClientSessionHandle)transactionSession, filter); - return result.DeletedCount; - } - } - - /// - /// 根据ID和筛选条件删除多个实体对象(加锁)。 - /// - /// 实体类型。 - /// 异步锁Id。 - /// 筛选条件。 - /// 集合名称。 - /// 删除的实体数量。 - public async FTask Remove(long coroutineLockQueueKey, Expression> filter, - string collection = null) where T : Entity, new() - { - using (await _dataBaseLock.Wait(coroutineLockQueueKey)) - { - var result = await GetCollection(collection).DeleteManyAsync(filter); - return result.DeletedCount; - } - } - - #endregion - - #region Index - - /// - /// 创建数据库索引(加锁)。 - /// - /// - /// - /// - /// - /// 使用例子(可多个): - /// 1 : Builders.IndexKeys.Ascending(d=>d.Id) - /// 2 : Builders.IndexKeys.Descending(d=>d.Id).Ascending(d=>d.Name) - /// 3 : Builders.IndexKeys.Descending(d=>d.Id),Builders.IndexKeys.Descending(d=>d.Name) - /// - public async FTask CreateIndex(string collection, params object[]? keys) where T : Entity - { - if (keys == null || keys.Length <= 0) - { - return; - } - - var indexModels = new List>(); - - foreach (object key in keys) - { - IndexKeysDefinition indexKeysDefinition = (IndexKeysDefinition)key; - - indexModels.Add(new CreateIndexModel(indexKeysDefinition)); - } - - await GetCollection(collection).Indexes.CreateManyAsync(indexModels); - } - - /// - /// 创建数据库的索引(加锁)。 - /// - /// 实体类型。 - /// 索引键定义。 - public async FTask CreateIndex(params object[]? keys) where T : Entity - { - if (keys == null) - { - return; - } - - List> indexModels = new List>(); - - foreach (object key in keys) - { - IndexKeysDefinition indexKeysDefinition = (IndexKeysDefinition)key; - - indexModels.Add(new CreateIndexModel(indexKeysDefinition)); - } - - await GetCollection().Indexes.CreateManyAsync(indexModels); - } - - #endregion - - #region CreateDB - - /// - /// 创建数据库集合(如果不存在)。 - /// - /// 实体类型。 - public async FTask CreateDB() where T : Entity - { - // 已经存在数据库表 - string name = typeof(T).Name; - - if (_collections.Contains(name)) - { - return; - } - - await _mongoDatabase.CreateCollectionAsync(name); - - _collections.Add(name); - } - - /// - /// 创建数据库集合(如果不存在)。 - /// - /// 实体类型。 - public async FTask CreateDB(Type type) - { - string name = type.Name; - - if (_collections.Contains(name)) - { - return; - } - - await _mongoDatabase.CreateCollectionAsync(name); - - _collections.Add(name); - } - - #endregion - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataBase/World.cs b/Fantasy/Fantays.Console/Runtime/Core/DataBase/World.cs deleted file mode 100644 index c53351f..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataBase/World.cs +++ /dev/null @@ -1,77 +0,0 @@ -#pragma warning disable CS8603 // Possible null reference return. -#if FANTASY_NET -using Fantasy.Platform.Net; - -namespace Fantasy.DataBase -{ - /// - /// 表示一个游戏世界。 - /// - public sealed class World : IDisposable - { - /// - /// 获取游戏世界的唯一标识。 - /// - public byte Id { get; private init; } - /// - /// 获取游戏世界的数据库接口。 - /// - public IDataBase DataBase { get; private init; } - /// - /// 获取游戏世界的配置信息。 - /// - public WorldConfig Config => WorldConfigData.Instance.Get(Id); - - /// - /// 使用指定的配置信息创建一个游戏世界实例。 - /// - /// - /// - private World(Scene scene, byte worldConfigId) - { - Id = worldConfigId; - var worldConfig = Config; - var dbType = worldConfig.DbType.ToLower(); - - switch (dbType) - { - case "mongodb": - { - DataBase = new MongoDataBase(); - DataBase.Initialize(scene, worldConfig.DbConnection, worldConfig.DbName); - break; - } - default: - { - throw new Exception("No supported database"); - } - } - } - - /// - /// 创建一个指定唯一标识的游戏世界实例。 - /// - /// - /// 游戏世界的唯一标识。 - /// 游戏世界实例。 - internal static World Create(Scene scene, byte id) - { - if (!WorldConfigData.Instance.TryGet(id, out var worldConfigData)) - { - return null; - } - - return string.IsNullOrEmpty(worldConfigData.DbConnection) ? null : new World(scene, id); - } - - /// - /// 释放游戏世界资源。 - /// - public void Dispose() - { - DataBase.Dispose(); - } - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/CircularBuffer.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/CircularBuffer.cs deleted file mode 100644 index d80ec55..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/CircularBuffer.cs +++ /dev/null @@ -1,346 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.DataStructure.Collection -{ - /// 环形缓存(自增式缓存,自动扩充、不会收缩缓存、所以不要用这个操作过大的IO流) - /// 1、环大小8192,溢出的会自动增加环的大小。 - /// 2、每个块都是一个环形缓存,当溢出的时候会自动添加到下一个环中。 - /// 3、当读取完成后用过的环会放在缓存中,不会销毁掉。 - /// - /// 自增式缓存类,继承自 Stream 和 IDisposable 接口。 - /// 环形缓存具有自动扩充的特性,但不会收缩,适用于操作不过大的 IO 流。 - /// - public sealed class CircularBuffer : Stream, IDisposable - { - private byte[] _lastBuffer; - /// - /// 环形缓存块的默认大小 - /// - public const int ChunkSize = 8192; - private readonly Queue _bufferCache = new Queue(); - private readonly Queue _bufferQueue = new Queue(); - /// - /// 获取或设置环形缓存的第一个索引位置 - /// - public int FirstIndex { get; set; } - /// - /// 获取或设置环形缓存的最后一个索引位置 - /// - public int LastIndex { get; set; } - /// - /// 获取环形缓存的总长度 - /// - public override long Length - { - get - { - if (_bufferQueue.Count == 0) - { - return 0; - } - - return (_bufferQueue.Count - 1) * ChunkSize + LastIndex - FirstIndex; - } - } - - /// - /// 获取环形缓存的第一个块 - /// - public byte[] First - { - get - { - if (_bufferQueue.Count == 0) - { - AddLast(); - } - - return _bufferQueue.Peek(); - } - } - - /// - /// 获取环形缓存的最后一个块 - /// - public byte[] Last - { - get - { - if (_bufferQueue.Count == 0) - { - AddLast(); - } - - return _lastBuffer; - } - } - /// - /// 向环形缓存中添加一个新的块 - /// - public void AddLast() - { - var buffer = _bufferCache.Count > 0 ? _bufferCache.Dequeue() : new byte[ChunkSize]; - _bufferQueue.Enqueue(buffer); - _lastBuffer = buffer; - } - /// - /// 从环形缓存中移除第一个块 - /// - public void RemoveFirst() - { - _bufferCache.Enqueue(_bufferQueue.Dequeue()); - } - - /// - /// 从流中读取指定数量的数据到缓存。 - /// - /// 源数据流。 - /// 要读取的字节数。 - public void Read(Stream stream, int count) - { - if (count > Length) - { - throw new Exception($"bufferList length < count, {Length} {count}"); - } - - var copyCount = 0; - while (copyCount < count) - { - var n = count - copyCount; - if (ChunkSize - FirstIndex > n) - { - stream.Write(First, FirstIndex, n); - FirstIndex += n; - copyCount += n; - } - else - { - stream.Write(First, FirstIndex, ChunkSize - FirstIndex); - copyCount += ChunkSize - FirstIndex; - FirstIndex = 0; - RemoveFirst(); - } - } - } - - /// - /// 从缓存中读取指定数量的数据到内存。 - /// - /// 目标内存。 - /// 要读取的字节数。 - public void Read(Memory memory, int count) - { - if (count > Length) - { - throw new Exception($"bufferList length < count, {Length} {count}"); - } - - var copyCount = 0; - while (copyCount < count) - { - var n = count - copyCount; - var asMemory = First.AsMemory(); - - if (ChunkSize - FirstIndex > n) - { - var slice = asMemory.Slice(FirstIndex, n); - slice.CopyTo(memory.Slice(copyCount, n)); - FirstIndex += n; - copyCount += n; - } - else - { - var length = ChunkSize - FirstIndex; - var slice = asMemory.Slice(FirstIndex, length); - slice.CopyTo(memory.Slice(copyCount, length)); - copyCount += ChunkSize - FirstIndex; - FirstIndex = 0; - RemoveFirst(); - } - } - } - - /// - /// 从自定义流中读取数据到指定的缓冲区。 - /// - /// 目标缓冲区,用于存储读取的数据。 - /// 目标缓冲区中的起始偏移量。 - /// 要读取的字节数。 - /// 实际读取的字节数。 - public override int Read(byte[] buffer, int offset, int count) - { - if (buffer.Length < offset + count) - { - throw new Exception($"buffer length < count, buffer length: {buffer.Length} {offset} {count}"); - } - - var length = Length; - if (length < count) - { - count = (int) length; - } - - var copyCount = 0; - - // 循环直到成功读取所需的字节数 - while (copyCount < count) - { - var copyLength = count - copyCount; - - if (ChunkSize - FirstIndex > copyLength) - { - // 将数据从当前块的缓冲区复制到目标缓冲区 - Array.Copy(First, FirstIndex, buffer, copyCount + offset, copyLength); - - FirstIndex += copyLength; - copyCount += copyLength; - continue; - } - - // 复制当前块中剩余的数据,并切换到下一个块 - Array.Copy(First, FirstIndex, buffer, copyCount + offset, ChunkSize - FirstIndex); - copyCount += ChunkSize - FirstIndex; - FirstIndex = 0; - - RemoveFirst(); - } - - return count; - } - - /// - /// 将数据从给定的字节数组写入流中。 - /// - /// 包含要写入的数据的字节数组。 - public void Write(byte[] buffer) - { - Write(buffer, 0, buffer.Length); - } - - /// - /// 将数据从给定的流写入流中。 - /// - /// 包含要写入的数据的流。 - public void Write(Stream stream) - { - var copyCount = 0; - var count = (int) (stream.Length - stream.Position); - - while (copyCount < count) - { - if (LastIndex == ChunkSize) - { - AddLast(); - LastIndex = 0; - } - - var n = count - copyCount; - - if (ChunkSize - LastIndex > n) - { - _ = stream.Read(Last, LastIndex, n); - LastIndex += count - copyCount; - copyCount += n; - } - else - { - _ = stream.Read(Last, LastIndex, ChunkSize - LastIndex); - copyCount += ChunkSize - LastIndex; - LastIndex = ChunkSize; - } - } - } - - /// - /// 将数据从给定的字节数组写入流中。 - /// - /// 包含要写入的数据的字节数组。 - /// 开始写入的缓冲区中的索引。 - /// 要写入的字节数。 - public override void Write(byte[] buffer, int offset, int count) - { - var copyCount = 0; - - while (copyCount < count) - { - if (ChunkSize == LastIndex) - { - AddLast(); - LastIndex = 0; - } - - var byteLength = count - copyCount; - - if (ChunkSize - LastIndex > byteLength) - { - Array.Copy(buffer, copyCount + offset, Last, LastIndex, byteLength); - LastIndex += byteLength; - copyCount += byteLength; - } - else - { - Array.Copy(buffer, copyCount + offset, Last, LastIndex, ChunkSize - LastIndex); - copyCount += ChunkSize - LastIndex; - LastIndex = ChunkSize; - } - } - } - - /// - /// 获取一个值,指示流是否支持读取操作。 - /// - public override bool CanRead { get; } = true; - /// - /// 获取一个值,指示流是否支持寻找操作。 - /// - public override bool CanSeek { get; } = false; - /// - /// 获取一个值,指示流是否支持写入操作。 - /// - public override bool CanWrite { get; } = true; - /// - /// 获取或设置流中的位置。 - /// - public override long Position { get; set; } - - /// - /// 刷新流(在此实现中引发未实现异常)。 - /// - public override void Flush() - { - throw new NotImplementedException(); - } - - /// - /// 在流中寻找特定位置(在此实现中引发未实现异常)。 - /// - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotImplementedException(); - } - - /// - /// 设置流的长度(在此实现中引发未实现异常)。 - /// - public override void SetLength(long value) - { - throw new NotImplementedException(); - } - - /// - /// 释放 CustomStream 使用的所有资源。 - /// - public new void Dispose() - { - _bufferQueue.Clear(); - _lastBuffer = null; - FirstIndex = 0; - LastIndex = 0; - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyListPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyListPool.cs deleted file mode 100644 index e110a0b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyListPool.cs +++ /dev/null @@ -1,197 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 并发的一对多列表池,用于维护具有相同键的多个值的关联关系,实现了 接口。 - /// - /// 关键字的类型,不能为空。 - /// 值的类型。 - public class ConcurrentOneToManyListPool : ConcurrentOneToManyList, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 的实例。 - /// - /// 创建的实例。 - public static ConcurrentOneToManyListPool Create() - { - var a = MultiThreadPool.Rent>(); - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - // 清空实例的数据 - Clear(); - // 将实例返回到池中以便重用 - MultiThreadPool.Return(this); - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 并发的一对多列表,用于维护具有相同键的多个值的关联关系。 - /// - /// 关键字的类型,不能为空。 - /// 值的类型。 - public class ConcurrentOneToManyList : ConcurrentDictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit = 120; - - /// - /// 初始化 类的新实例。 - /// - public ConcurrentOneToManyList() - { - } - - /// - /// 设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public ConcurrentOneToManyList(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断指定键的列表是否包含指定值。 - /// - /// 要搜索的键。 - /// 要搜索的值。 - /// 如果列表包含值,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 向指定键的列表中添加一个值。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - base[key] = list; - return; - } - - list.Add(value); - } - - /// - /// 获取指定键的列表中的第一个值。 - /// - /// 要获取第一个值的键。 - /// 指定键的列表中的第一个值,如果不存在则为默认值。 - public TValue First(TKey key) - { - return !TryGetValue(key, out var list) ? default : list.FirstOrDefault(); - } - - /// - /// 从指定键的列表中移除一个值。 - /// - /// 要移除值的键。 - /// 要移除的值。 - public void RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) return; - - list.Remove(value); - - if (list.Count == 0) RemoveKey(key); - } - - /// - /// 从字典中移除指定键以及其关联的列表。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryRemove(key, out var list)) return; - - Recycle(list); - } - - /// - /// 从队列中获取一个列表,如果队列为空则创建一个新的列表。 - /// - /// 获取的列表。 - private List Fetch() - { - return _queue.Count <= 0 ? new List() : _queue.Dequeue(); - } - - /// - /// 将一个列表回收到队列中。 - /// - /// 要回收的列表。 - private void Recycle(List list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 清空当前类的数据,包括从基类继承的数据以及自定义的数据队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyQueuePool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyQueuePool.cs deleted file mode 100644 index 59c4367..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ConcurrentOneToManyQueuePool.cs +++ /dev/null @@ -1,194 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8603 - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 表示一个并发的一对多队列池,用于维护具有相同键的多个值的关联关系,实现了 接口。 - /// - /// 关键字的类型,不能为空。 - /// 值的类型。 - public class ConcurrentOneToManyQueuePool : ConcurrentOneToManyQueue, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建并返回一个 的实例。 - /// - /// 创建的实例。 - public static ConcurrentOneToManyQueuePool Create() - { - var a = MultiThreadPool.Rent>(); - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); - // 将实例返回到对象池中,以便重用 - MultiThreadPool.Return(this); - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 表示一个并发的一对多队列,用于维护具有相同键的多个值的关联关系。 - /// - /// 关键字的类型,不能为空。 - /// 值的类型。 - public class ConcurrentOneToManyQueue : ConcurrentDictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit; - - /// - /// 设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public ConcurrentOneToManyQueue(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断指定键的队列是否包含指定值。 - /// - /// 要搜索的键。 - /// 要搜索的值。 - /// 如果队列包含值,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 向指定键的队列中添加一个值。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Enqueue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Enqueue(value); - TryAdd(key, list); - return; - } - - list.Enqueue(value); - } - - /// - /// 从指定键的队列中出队并返回一个值。 - /// - /// 要出队的键。 - /// 出队的值,如果队列为空则为默认值。 - public TValue Dequeue(TKey key) - { - if (!TryGetValue(key, out var list) || list.Count == 0) return default; - - var value = list.Dequeue(); - - if (list.Count == 0) RemoveKey(key); - - return value; - } - - /// - /// 尝试从指定键的队列中出队一个值。 - /// - /// 要出队的键。 - /// 出队的值,如果队列为空则为默认值。 - /// 如果成功出队,则为 true;否则为 false。 - public bool TryDequeue(TKey key, out TValue value) - { - value = Dequeue(key); - - return value != null; - } - - /// - /// 从字典中移除指定键以及其关联的队列。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) return; - - TryRemove(key, out _); - Recycle(list); - } - - /// - /// 从队列中获取一个新的队列,如果队列为空则创建一个新的队列。 - /// - /// 获取的队列。 - private Queue Fetch() - { - return _queue.Count <= 0 ? new Queue() : _queue.Dequeue(); - } - - /// - /// 将一个队列回收到队列池中。 - /// - /// 要回收的队列。 - private void Recycle(Queue list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 清空当前类的数据,包括从基类继承的键值对字典中的数据以及自定义的队列池。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/HashSetPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/HashSetPool.cs deleted file mode 100644 index bb64ae8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/HashSetPool.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 可释放的哈希集合对象池。 - /// - /// 哈希集合中元素的类型。 - public sealed class HashSetPool : HashSet, IDisposable, IPool - { - private bool _isPool; - private bool _isDispose; - - /// - /// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 创建一个 哈希集合池的实例。 - /// - /// 创建的实例。 - public static HashSetPool Create() - { -#if FANTASY_WEBGL - var list = Pool>.Rent(); - list._isDispose = false; - list._isPool = true; - return list; -#else - var list = MultiThreadPool.Rent>(); - list._isDispose = false; - list._isPool = true; - return list; -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 基本哈希集合对象池,他自持有实际的哈希集合。 - /// - /// 哈希集合中元素的类型。 - public sealed class HashSetBasePool : IDisposable, IPool - { - private bool _isPool; - - /// - /// 存储实际的哈希集合 - /// - public HashSet Set = new HashSet(); - - /// - /// 创建一个 基本哈希集合对象池的实例。 - /// - /// 创建的实例。 - public static HashSetBasePool Create() - { -#if FANTASY_WEBGL - var hashSetBasePool = Pool>.Rent(); - hashSetBasePool._isPool = true; - return hashSetBasePool; -#else - var hashSetBasePool = MultiThreadPool.Rent>(); - hashSetBasePool._isPool = true; - return hashSetBasePool; -#endif - } - - /// - /// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - Set.Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ListPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ListPool.cs deleted file mode 100644 index de70fe2..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ListPool.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 可释放的列表(List)对象池。 - /// - /// 列表中元素的类型。 - public sealed class ListPool : List, IDisposable, IPool - { - private bool _isPool; - private bool _isDispose; - - /// - /// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 使用指定的元素创建一个 列表(List)对象池的实例。 - /// - /// 要添加到列表的元素。 - /// 创建的实例。 - public static ListPool Create(params T[] args) - { -#if FANTASY_WEBGL - var list = Pool>.Rent(); -#else - var list = MultiThreadPool.Rent>(); -#endif - list._isDispose = false; - list._isPool = true; - - if (args != null) - { - list.AddRange(args); - } - - return list; - } - - /// - /// 使用指定的列表创建一个 列表(List)对象池的实例。 - /// - /// 要添加到列表的元素列表。 - /// 创建的实例。 - public static ListPool Create(List args) - { -#if FANTASY_WEBGL - var list = Pool>.Rent(); -#else - var list = MultiThreadPool.Rent>(); -#endif - list._isDispose = false; - list._isPool = true; - - if (args != null) - { - list.AddRange(args); - } - - return list; - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/OneToManyHashSetPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/OneToManyHashSetPool.cs deleted file mode 100644 index 8a5766c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/OneToManyHashSetPool.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 一对多哈希集合(OneToManyHashSet)对象池。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyHashSetPool : OneToManyHashSet, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 一对多哈希集合(OneToManyHashSet)对象池的实例。 - /// - /// 创建的实例。 - public static OneToManyHashSetPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 一对多哈希集合(OneToManyHashSet),用于创建和管理键对应多个值的集合。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyHashSet : Dictionary> where TKey : notnull - { - /// 用于回收和重用的空闲值集合队列。 - private readonly Queue> _queue = new Queue>(); - /// 设置最大回收限制,用于控制值集合的最大数量。 - private readonly int _recyclingLimit = 120; - /// 一个空的、不包含任何元素的哈希集合,用于在查找失败时返回。 - private static HashSet _empty = new HashSet(); - - /// - /// 初始化 类的新实例。 - /// - public OneToManyHashSet() { } - - /// - /// 设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManyHashSet(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断指定的键值对是否存在于集合中。 - /// - /// 键。 - /// 值。 - /// 如果存在则为 true,否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 添加指定的键值对到集合中。 - /// - /// 键。 - /// 值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - Add(key, list); - - return; - } - - list.Add(value); - } - - /// - /// 从集合中移除指定键对应的值。 - /// - /// 键。 - /// 要移除的值。 - public void RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) return; - - list.Remove(value); - - if (list.Count == 0) RemoveKey(key); - } - - /// - /// 从集合中移除指定键及其对应的值集合。 - /// - /// 键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) return; - - Remove(key); - Recycle(list); - } - - /// - /// 获取指定键对应的值集合,如果不存在则返回一个空的哈希集合。 - /// - /// 键。 - /// 对应的值集合或空的哈希集合。 - public HashSet GetValue(TKey key) - { - if (TryGetValue(key, out HashSet value)) - { - return value; - } - - return _empty; - } - - /// - /// 从队列中获取一个空闲的值集合,或者创建一个新的。 - /// - /// 值集合。 - private HashSet Fetch() - { - return _queue.Count <= 0 ? new HashSet() : _queue.Dequeue(); - } - - /// - /// 回收值集合到队列中,以便重复利用。 - /// - /// 要回收的值集合。 - private void Recycle(HashSet list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 清空集合中的数据并和队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/OneToManyListPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/OneToManyListPool.cs deleted file mode 100644 index 80568ef..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/OneToManyListPool.cs +++ /dev/null @@ -1,232 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 可回收的、一对多关系的列表池。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyListPool : OneToManyList, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 一对多关系的列表池的实例。 - /// - /// 创建的实例。 - public static OneToManyListPool Create() - { -#if FANTASY_WEBGL || FANTASY_EXPORTER - var list = Pool>.Rent(); -#else - var list = MultiThreadPool.Rent>(); -#endif - list._isDispose = false; - list._isPool = true; - return list; - } - - /// - /// 释放当前对象所占用的资源,并将对象回收到对象池中。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL || FANTASY_EXPORTER - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 一对多关系的列表字典。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyList : Dictionary> where TKey : notnull - { - private readonly int _recyclingLimit = 120; - private static readonly List Empty = new List(); - private readonly Queue> _queue = new Queue>(); - - /// - /// 初始化一个新的 实例。 - /// - public OneToManyList() { } - - /// - /// 设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManyList(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断给定的键和值是否存在于列表中。 - /// - /// 要搜索的键。 - /// 要搜索的值。 - /// 如果存在则为 ,否则为 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 向列表中添加指定键和值。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - Add(key, list); - - return; - } - - list.Add(value); - } - - /// - /// 获取指定键对应的列表中的第一个值。 - /// - /// 要获取值的键。 - /// 键对应的列表中的第一个值。 - public TValue First(TKey key) - { - return !TryGetValue(key, out var list) ? default : list.FirstOrDefault(); - } - - /// - /// 从列表中移除指定键和值。 - /// - /// 要移除值的键。 - /// 要移除的值。 - /// 如果成功移除则为 ,否则为 - public bool RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - return true; - } - - var isRemove = list.Remove(value); - - if (list.Count == 0) - { - isRemove = RemoveByKey(key); - } - - return isRemove; - } - - /// - /// 从列表中移除指定键及其关联的所有值。 - /// - /// 要移除的键。 - /// 如果成功移除则为 ,否则为 - public bool RemoveByKey(TKey key) - { - if (!TryGetValue(key, out var list)) - { - return false; - } - - Remove(key); - Recycle(list); - return true; - } - - /// - /// 获取指定键关联的所有值的列表。 - /// - /// 要获取值的键。 - /// 键关联的所有值的列表。 - public List GetValues(TKey key) - { - if (TryGetValue(key, out List list)) - { - return list; - } - - return Empty; - } - - /// - /// 清除字典中的所有键值对,并回收相关的值集合。 - /// - public new void Clear() - { - foreach (var keyValuePair in this) Recycle(keyValuePair.Value); - - base.Clear(); - } - - /// - /// 从空闲值集合队列中获取一个值集合,如果队列为空则创建一个新的值集合。 - /// - /// 从队列中获取的值集合。 - private List Fetch() - { - return _queue.Count <= 0 ? new List() : _queue.Dequeue(); - } - - /// - /// 回收一个不再使用的值集合到空闲值集合队列中。 - /// - /// 要回收的值集合。 - private void Recycle(List list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/OneToManyQueuePool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/OneToManyQueuePool.cs deleted file mode 100644 index 222576e..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/OneToManyQueuePool.cs +++ /dev/null @@ -1,204 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8603 - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 支持一对多关系的队列池,用于存储具有相同键的值的队列集合。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyQueuePool : OneToManyQueue, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 一对多关系的队列池的实例。 - /// - /// 创建的实例。 - public static OneToManyQueuePool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前实例所占用的资源,并将实例回收到对象池中。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 支持一对多关系的队列,用于存储具有相同键的值的队列集合。 - /// - /// 键的类型。 - /// 值的类型。 - public class OneToManyQueue : Dictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit; - - /// - /// 创建一个 一对多关系的队列的实例。设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManyQueue(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断指定键的值队列是否包含指定的值。 - /// - /// 要查找的键。 - /// 要查找的值。 - /// 如果存在,则为 true;否则为 false - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 将指定的值添加到指定键的值队列中。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Enqueue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Enqueue(value); - Add(key, list); - return; - } - - list.Enqueue(value); - } - - /// - /// 从指定键的值队列中出队一个值。 - /// - /// 要出队的键。 - /// 出队的值。 - public TValue Dequeue(TKey key) - { - if (!TryGetValue(key, out var list) || list.Count == 0) - { - return default; - } - - var value = list.Dequeue(); - - if (list.Count == 0) - { - RemoveKey(key); - } - - return value; - } - - /// - /// 尝试从指定键的值队列中出队一个值。 - /// - /// 要出队的键。 - /// 出队的值。 - /// 如果成功出队,则为 true;否则为 false - public bool TryDequeue(TKey key, out TValue value) - { - value = Dequeue(key); - - return value != null; - } - - /// - /// 从字典中移除指定键及其对应的值队列。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) return; - - Remove(key); - Recycle(list); - } - - /// - /// 从队列池中获取一个值队列。如果队列池为空,则创建一个新的值队列。 - /// - /// 获取的值队列。 - private Queue Fetch() - { - return _queue.Count <= 0 ? new Queue() : _queue.Dequeue(); - } - - /// - /// 回收一个不再使用的值队列到队列池中,以便重用。 - /// - /// 要回收的值队列。 - private void Recycle(Queue list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 清空当前实例的数据,同时回收所有值队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ReuseList.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ReuseList.cs deleted file mode 100644 index b4395e8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/ReuseList.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 可重用的列表,继承自 类。该类支持通过对象池重用列表实例,以减少对象分配和释放的开销。 - /// - /// 列表中元素的类型。 - public sealed class ReuseList : List, IDisposable, IPool - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 可重用的列表的实例。 - /// - /// 创建的实例。 - public static ReuseList Create() - { -#if FANTASY_WEBGL - var list = Pool>.Rent(); -#else - var list = MultiThreadPool.Rent>(); -#endif - list._isDispose = false; - list._isPool = true; - return list; - } - - /// - /// 释放该实例所占用的资源,并将实例返回到对象池中,以便重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/SortedConcurrentOneToManyListPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/SortedConcurrentOneToManyListPool.cs deleted file mode 100644 index 464ab58..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/SortedConcurrentOneToManyListPool.cs +++ /dev/null @@ -1,226 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8603 - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 基于排序字典和并发集合实现的一对多映射列表的对象池包装类,继承自 类, - /// 同时实现了 接口,以支持对象的重用和释放。 - /// - /// 键的类型。 - /// 值的类型。 - public class SortedConcurrentOneToManyListPool : SortedConcurrentOneToManyList, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个新的 实例,使用默认的参数设置。 - /// - /// 新创建的 实例。 - public static SortedConcurrentOneToManyListPool Create() - { - var a = MultiThreadPool.Rent>(); - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前对象池实例,将其返回到对象池以供重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); - MultiThreadPool.Return(this); - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 基于排序字典和并发集合实现的一多对映射列表类,继承自 类, - /// 用于在多个值与一个键关联的情况下进行管理和存储。该类支持并发操作,适用于多线程环境。 - /// - /// 键的类型。 - /// 值的类型。 - public class SortedConcurrentOneToManyList : SortedDictionary> where TKey : notnull - { - /// 用于同步操作的锁对象,它确保在多线程环境下对数据的安全访问。 - private readonly object _lockObject = new object(); - /// 用于存储缓存的队列。 - private readonly Queue> _queue = new Queue>(); - /// 控制缓存回收的限制。当缓存的数量超过此限制时,旧的缓存将会被回收。 - private readonly int _recyclingLimit; - - /// - /// 初始化一个新的 类的实例,使用默认的参数设置。 - /// - public SortedConcurrentOneToManyList() - { - } - - /// - /// 初始化一个新的 类的实例,指定最大缓存数量。 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public SortedConcurrentOneToManyList(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 检查指定的键和值是否存在于映射列表中。 - /// - /// 要检查的键。 - /// 要检查的值。 - /// 如果存在,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - lock (_lockObject) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - } - - /// - /// 将指定的值添加到与指定键关联的列表中。 - /// - /// 要关联值的键。 - /// 要添加到列表的值。 - public void Add(TKey key, TValue value) - { - lock (_lockObject) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - base[key] = list; - return; - } - - list.Add(value); - } - } - - /// - /// 获取与指定键关联的列表中的第一个值。 - /// 如果列表不存在或为空,则返回默认值。 - /// - /// 要获取第一个值的键。 - /// 第一个值,或默认值。 - public TValue First(TKey key) - { - lock (_lockObject) - { - return !TryGetValue(key, out var list) ? default : list.FirstOrDefault(); - } - } - - /// - /// 从与指定键关联的列表中移除指定的值。 - /// 如果列表不存在或值不存在于列表中,则不执行任何操作。 - /// - /// 要移除值的键。 - /// 要移除的值。 - public void RemoveValue(TKey key, TValue value) - { - lock (_lockObject) - { - if (!TryGetValue(key, out var list)) return; - - list.Remove(value); - - if (list.Count == 0) RemoveKey(key); - } - } - - /// - /// 从映射列表中移除指定的键及其关联的列表。 - /// 如果键不存在于映射列表中,则不执行任何操作。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - lock (_lockObject) - { - if (!TryGetValue(key, out var list)) return; - - Remove(key); - - Recycle(list); - } - } - - /// - /// 从缓存中获取一个可重用的列表。如果缓存中不存在列表,则创建一个新的列表并返回。 - /// - /// 可重用的列表。 - private List Fetch() - { - lock (_lockObject) - { - return _queue.Count <= 0 ? new List() : _queue.Dequeue(); - } - } - - /// - /// 将不再使用的列表回收到缓存中,以便重复利用。如果缓存数量超过限制,则丢弃列表而不进行回收。 - /// - /// 要回收的列表。 - private void Recycle(List list) - { - lock (_lockObject) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - } - - /// - /// 清空映射列表以及队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/SortedOneToManyHashSetPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/SortedOneToManyHashSetPool.cs deleted file mode 100644 index 8158db5..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/SortedOneToManyHashSetPool.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 基于排序字典实现的一对多关系的映射哈希集合的对象池包装类,将唯一键映射到多个值的哈希集合。 - /// 同时实现了 接口,以支持对象的重用和释放。 - /// - /// 字典中键的类型。 - /// 哈希集合中值的类型。 - public class SortedOneToManyHashSetPool : SortedOneToManyHashSet, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 实例。 - /// - /// 新创建的实例。 - public static SortedOneToManyHashSetPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前对象池实例,将其返回到对象池以供重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 基于排序字典实现的一对多关系的映射哈希集合类,将唯一键映射到多个值的哈希集合。 - /// 用于在多个值与一个键关联的情况下进行管理和存储。 - /// - /// 字典中键的类型。 - /// 集合中值的类型。 - public class SortedOneToManyHashSet : SortedDictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit = 120; - - /// - /// 创建一个新的 实例。 - /// - public SortedOneToManyHashSet() { } - - /// - /// 创建一个新的 实例,设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public SortedOneToManyHashSet(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断哈希集合中是否包含指定的键值对。 - /// - /// 要查找的键。 - /// 要查找的值。 - /// 如果键值对存在,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 将指定值添加到给定键关联的哈希集合中。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - Add(key, list); - - return; - } - - list.Add(value); - } - - /// - /// 从指定键关联的哈希集合中移除特定值。 - /// 如果哈希集合不存在或值不存在于集合中,则不执行任何操作。 - /// - /// 要移除值的键。 - /// 要移除的值。 - public void RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) return; - - list.Remove(value); - - if (list.Count == 0) RemoveKey(key); - } - - /// - /// 从字典中移除指定键以及关联的哈希集合,并将集合进行回收。 - /// 如果键不存在于映射列表中,则不执行任何操作。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) return; - - Remove(key); - - Recycle(list); - } - - /// - /// 获取一个空的或回收的哈希集合。 - /// - /// 获取的哈希集合实例。 - private HashSet Fetch() - { - return _queue.Count <= 0 ? new HashSet() : _queue.Dequeue(); - } - - /// - /// 回收一个哈希集合,将其清空并放入回收队列中。 - /// - /// 要回收的哈希集合。 - private void Recycle(HashSet list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } - - /// - /// 重写 Clear 方法,清空字典并清空回收队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/SortedOneToManyListPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/SortedOneToManyListPool.cs deleted file mode 100644 index f0bae12..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Collection/SortedOneToManyListPool.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8603 - -namespace Fantasy.DataStructure.Collection -{ - /// - /// 基于排序字典实现的一对多映射列表的对象池包装类,继承自 类, - /// 同时实现了 接口,以支持对象的重用和释放。 - /// - /// 字典中键的类型。 - /// 列表中值的类型。 - public class SortedOneToManyListPool : SortedOneToManyList, IDisposable, IPool where TKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 实例。 - /// - /// 新创建的实例。 - public static SortedOneToManyListPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前对象池实例,将其返回到对象池以供重用。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 基于排序字典实现的一对多关系的映射列表类,将唯一键映射到包含多个值的列表。 - /// 用于在多个值与一个键关联的情况下进行管理和存储。 - /// - /// 字典中键的类型。 - /// 列表中值的类型。 - public class SortedOneToManyList : SortedDictionary> where TKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit; - - /// - /// 创建一个新的 实例。 - /// - public SortedOneToManyList() - { - } - - /// - /// 创建一个新的 实例,设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public SortedOneToManyList(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断列表中是否包含指定的键值对。 - /// - /// 要查找的键。 - /// 要查找的值。 - /// 如果键值对存在,则为 true;否则为 false。 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 将指定值添加到给定键关联的列表中。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - base[key] = list; - return; - } - - list.Add(value); - } - - /// - /// 获取指定键关联的列表中的第一个值。 - /// - /// 要查找值的键。 - /// 指定键关联的列表中的第一个值,如果列表为空则返回默认值。 - public TValue First(TKey key) - { - return !TryGetValue(key, out var list) ? default : list.FirstOrDefault(); - } - - /// - /// 从指定键关联的列表中移除特定值。 - /// - /// 要移除值的键。 - /// 要移除的值。 - - public void RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - return; - } - - list.Remove(value); - - if (list.Count == 0) - { - RemoveKey(key); - } - } - - /// - /// 从字典中移除指定键以及关联的列表,并将列表进行回收。 - /// - /// 要移除的键。 - - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) - { - return; - } - - Remove(key); - Recycle(list); - } - - /// - /// 获取一个空的或回收的列表。 - /// - /// 获取的列表实例。 - private List Fetch() - { - return _queue.Count <= 0 ? new List() : _queue.Dequeue(); - } - - /// - /// 回收一个列表,将其清空并放入回收队列中。如果缓存数量超过限制,则丢弃列表而不进行回收 - /// - /// 要回收的列表。 - private void Recycle(List list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) - { - return; - } - - _queue.Enqueue(list); - } - - /// - /// 重写 Clear 方法,清空字典并清空回收队列。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/DictionaryExtensions.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/DictionaryExtensions.cs deleted file mode 100644 index ed0aa57..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/DictionaryExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -#pragma warning disable CS8601 // Possible null reference assignment. - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供对字典的扩展方法。 - /// - public static class DictionaryExtensions - { - /// - /// 尝试从字典中移除指定键,并返回相应的值。 - /// - /// 字典中键的类型。 - /// 字典中值的类型。 - /// 要操作的字典实例。 - /// 要移除的键。 - /// 从字典中移除的值(如果成功移除)。 - /// 如果成功移除键值对,则为 true;否则为 false。 - public static bool TryRemove(this IDictionary self, T key, out TV value) - { - if (!self.TryGetValue(key, out value)) - { - return false; - } - - self.Remove(key); - return true; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/DictionaryPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/DictionaryPool.cs deleted file mode 100644 index 567901c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/DictionaryPool.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个可以使用对象池管理的字典类。 - /// - /// 字典中键的类型。 - /// 字典中值的类型。 - public sealed class DictionaryPool : Dictionary, IDisposable, IPool where TM : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static DictionaryPool Create() - { -#if FANTASY_WEBGL - var dictionary = Pool>.Rent(); -#else - var dictionary = MultiThreadPool.Rent>(); -#endif - dictionary._isDispose = false; - dictionary._isPool = true; - return dictionary; - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/DoubleMapDictionaryPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/DoubleMapDictionaryPool.cs deleted file mode 100644 index e868710..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/DoubleMapDictionaryPool.cs +++ /dev/null @@ -1,289 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个双向映射字典对象池类,用于双向键值对映射。 - /// - /// 字典中键的类型。 - /// 字典中值的类型。 - public class DoubleMapDictionaryPool : DoubleMapDictionary, IDisposable, IPool where TKey : notnull where TValue : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static DoubleMapDictionaryPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 可以实现双向映射的字典类,用于将键和值进行双向映射。 - /// - /// 键的类型,不能为 null。 - /// 值的类型,不能为 null。 - public class DoubleMapDictionary where TK : notnull where TV : notnull - { - private readonly Dictionary _kv = new Dictionary(); - private readonly Dictionary _vk = new Dictionary(); - - /// - /// 创建一个新的空的 实例。 - /// - public DoubleMapDictionary() { } - - /// - /// 创建一个新的具有指定初始容量的 实例。 - /// - /// 初始容量。 - public DoubleMapDictionary(int capacity) - { - _kv = new Dictionary(capacity); - _vk = new Dictionary(capacity); - } - - /// - /// 获取包含字典中所有键的列表。 - /// - public List Keys => new List(_kv.Keys); - - /// - /// 获取包含字典中所有值的列表。 - /// - public List Values => new List(_vk.Keys); - - /// - /// 对字典中的每个键值对执行指定的操作。 - /// - /// 要执行的操作。 - public void ForEach(Action action) - { - if (action == null) - { - return; - } - - var keys = _kv.Keys; - foreach (var key in keys) - { - action(key, _kv[key]); - } - } - - /// - /// 将指定的键值对添加到字典中。 - /// - /// 要添加的键。 - /// 要添加的值。 - public void Add(TK key, TV value) - { - if (key == null || value == null || _kv.ContainsKey(key) || _vk.ContainsKey(value)) - { - return; - } - - _kv.Add(key, value); - _vk.Add(value, key); - } - - /// - /// 根据指定的键获取相应的值。 - /// - /// 要查找值的键。 - /// 与指定键关联的值,如果找不到键,则返回默认值。 - public TV GetValueByKey(TK key) - { - if (key != null && _kv.ContainsKey(key)) - { - return _kv[key]; - } - - return default; - } - - /// - /// 尝试根据指定的键获取相应的值。 - /// - /// 要查找值的键。 - /// 如果找到,则为与指定键关联的值;否则为值的默认值。 - /// 如果找到键,则为 true;否则为 false。 - public bool TryGetValueByKey(TK key, out TV value) - { - var result = key != null && _kv.ContainsKey(key); - - value = result ? _kv[key] : default; - - return result; - } - - /// - /// 根据指定的值获取相应的键。 - /// - /// 要查找键的值。 - /// 与指定值关联的键,如果找不到值,则返回默认键。 - public TK GetKeyByValue(TV value) - { - if (value != null && _vk.ContainsKey(value)) - { - return _vk[value]; - } - - return default; - } - - /// - /// 尝试根据指定的值获取相应的键。 - /// - /// 要查找键的值。 - /// 如果找到,则为与指定值关联的键;否则为键的默认值。 - /// 如果找到值,则为 true;否则为 false。 - public bool TryGetKeyByValue(TV value, out TK key) - { - var result = value != null && _vk.ContainsKey(value); - - key = result ? _vk[value] : default; - - return result; - } - - /// - /// 根据指定的键移除键值对。 - /// - /// 要移除的键。 - public void RemoveByKey(TK key) - { - if (key == null) - { - return; - } - - if (!_kv.TryGetValue(key, out var value)) - { - return; - } - - _kv.Remove(key); - _vk.Remove(value); - } - - /// - /// 根据指定的值移除键值对。 - /// - /// 要移除的值。 - public void RemoveByValue(TV value) - { - if (value == null) - { - return; - } - - if (!_vk.TryGetValue(value, out var key)) - { - return; - } - - _kv.Remove(key); - _vk.Remove(value); - } - - /// - /// 清空字典中的所有键值对。 - /// - public void Clear() - { - _kv.Clear(); - _vk.Clear(); - } - - /// - /// 判断字典是否包含指定的键。 - /// - /// 要检查的键。 - /// 如果字典包含指定的键,则为 true;否则为 false。 - public bool ContainsKey(TK key) - { - return key != null && _kv.ContainsKey(key); - } - - /// - /// 判断字典是否包含指定的值。 - /// - /// 要检查的值。 - /// 如果字典包含指定的值,则为 true;否则为 false。 - public bool ContainsValue(TV value) - { - return value != null && _vk.ContainsKey(value); - } - - /// - /// 判断字典是否包含指定的键值对。 - /// - /// 要检查的键。 - /// 要检查的值。 - /// 如果字典包含指定的键值对,则为 true;否则为 false。 - public bool Contains(TK key, TV value) - { - if (key == null || value == null) - { - return false; - } - - return _kv.ContainsKey(key) && _vk.ContainsKey(value); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/EntityDictionary.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/EntityDictionary.cs deleted file mode 100644 index fc4d44f..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/EntityDictionary.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个带资源释放功能的实体字典类,支持使用对象池管理。 - /// - /// 字典中键的类型。 - /// 字典中值的类型,必须实现 IDisposable 接口。 - public sealed class EntityDictionary : Dictionary, IDisposable, IPool where TN : IDisposable where TM : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static EntityDictionary Create() - { -#if FANTASY_WEBGL - var entityDictionary = Pool>.Rent(); -#else - var entityDictionary = MultiThreadPool.Rent>(); -#endif - entityDictionary._isDispose = false; - entityDictionary._isPool = true; - return entityDictionary; - } - - /// - /// 清空字典中的所有键值对,并释放值的资源。 - /// - public new void Clear() - { - foreach (var keyValuePair in this) - { - keyValuePair.Value.Dispose(); - } - - base.Clear(); - } - - /// - /// 清空字典中的所有键值对,但不释放值的资源。 - /// - public void ClearNotDispose() - { - base.Clear(); - } - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/OneToManyDictionaryPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/OneToManyDictionaryPool.cs deleted file mode 100644 index 0515423..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/OneToManyDictionaryPool.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Pool; - -#pragma warning disable CS8603 -#pragma warning disable CS8601 - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 一对多映射关系的字典对象池。 - /// - /// 外部字典中的键类型。 - /// 内部字典中的键类型。 - /// 内部字典中的值类型。 - public class OneToManyDictionaryPool : OneToManyDictionary, IDisposable, IPool where TKey : notnull where TValueKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 的实例。 - /// - /// 新创建的 OneToManyDictionaryPool 实例。 - public static OneToManyDictionaryPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前实例及其资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 一对多映射关系的字典。每个键都对应一个内部字典,该内部字典将键值映射到相应的值。 - /// - /// 外部字典中的键类型。 - /// 内部字典中的键类型。 - /// 内部字典中的值类型。 - public class OneToManyDictionary : Dictionary> - where TKey : notnull where TValueKey : notnull - { - private readonly Queue> _queue = new Queue>(); - private readonly int _recyclingLimit = 120; - - /// - /// 创建一个新的 实例。 - /// - public OneToManyDictionary() { } - - /// - /// 创建一个新的 实例,并指定最大缓存数量。 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManyDictionary(int recyclingLimit = 0) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 检查是否包含指定的键值对。 - /// - /// 外部字典中的键。 - /// 内部字典中的键。 - /// 如果包含指定的键值对,则为 true;否则为 false。 - public bool Contains(TKey key, TValueKey valueKey) - { - TryGetValue(key, out var dic); - - return dic != null && dic.ContainsKey(valueKey); - } - - /// - /// 尝试获取指定键值对的值。 - /// - /// 外部字典中的键。 - /// 内部字典中的键。 - /// 获取的值,如果操作成功,则为值;否则为默认值。 - /// 如果操作成功,则为 true;否则为 false。 - public bool TryGetValue(TKey key, TValueKey valueKey, out TValue value) - { - value = default; - return TryGetValue(key, out var dic) && dic.TryGetValue(valueKey, out value); - } - - /// - /// 获取指定键的第一个值。 - /// - /// 要获取第一个值的键。 - public TValue First(TKey key) - { - return !TryGetValue(key, out var dic) ? default : dic.First().Value; - } - - /// - /// 向字典中添加指定的键值对。 - /// - /// 要添加键值对的键。 - /// 要添加键值对的内部字典键。 - /// 要添加的值。 - public void Add(TKey key, TValueKey valueKey, TValue value) - { - if (!TryGetValue(key, out var dic)) - { - dic = Fetch(); - dic[valueKey] = value; - // dic.Add(valueKey, value); - Add(key, dic); - - return; - } - - dic[valueKey] = value; - // dic.Add(valueKey, value); - } - - /// - /// 从字典中移除指定的键值对。 - /// - /// 要移除键值对的键。 - /// 要移除键值对的内部字典键。 - /// 如果成功移除键值对,则为 true;否则为 false。 - public bool Remove(TKey key, TValueKey valueKey) - { - if (!TryGetValue(key, out var dic)) return false; - - var result = dic.Remove(valueKey); - - if (dic.Count == 0) RemoveKey(key); - - return result; - } - - /// - /// 从字典中移除指定的键值对。 - /// - /// 要移除键值对的键。 - /// 要移除键值对的内部字典键。 - /// 如果成功移除键值对,则为移除的值;否则为默认值。 - /// 如果成功移除键值对,则为 true;否则为 false。 - public bool Remove(TKey key, TValueKey valueKey, out TValue value) - { - if (!TryGetValue(key, out var dic)) - { - value = default; - return false; - } - - var result = dic.TryGetValue(valueKey, out value); - - if (result) dic.Remove(valueKey); - - if (dic.Count == 0) RemoveKey(key); - - return result; - } - - /// - /// 移除字典中的指定键及其相关的所有键值对。 - /// - /// 要移除的键。 - public void RemoveKey(TKey key) - { - if (!TryGetValue(key, out var dic)) return; - - Remove(key); - Recycle(dic); - } - - /// - /// 从对象池中获取一个内部字典实例,如果池中没有,则创建一个新实例。 - /// - /// 获取的内部字典实例。 - private Dictionary Fetch() - { - return _queue.Count <= 0 ? new Dictionary() : _queue.Dequeue(); - } - - /// - /// 将不再使用的内部字典实例放回对象池中,以便后续重用。 - /// - /// 要放回对象池的内部字典实例。 - private void Recycle(Dictionary dic) - { - dic.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(dic); - } - - /// - /// 清空字典中的所有键值对,并将不再使用的内部字典实例放回对象池中。 - /// - public new void Clear() - { - foreach (var keyValuePair in this) Recycle(keyValuePair.Value); - - base.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/OneToManySortedDictionaryPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/OneToManySortedDictionaryPool.cs deleted file mode 100644 index 127a8ac..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/OneToManySortedDictionaryPool.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8601 - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 一对多映射关系的排序字典对象池。 - /// - /// 外部字典中的键类型。 - /// 内部字典中的排序键类型。 - /// 内部字典中的值类型。 - public class OneToManySortedDictionaryPool : OneToManySortedDictionary, IDisposable, IPool where TKey : notnull where TSortedKey : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 的实例。 - /// - /// 新创建的 OneToManySortedDictionaryPool 实例。 - public static OneToManySortedDictionaryPool Create() - { -#if FANTASY_WEBGL - var a = Pool>.Rent(); -#else - var a = MultiThreadPool.Rent>(); -#endif - a._isDispose = false; - a._isPool = true; - return a; - } - - /// - /// 释放当前实例及其资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - /// - /// 一对多映射关系的排序字典。每个外部键映射到一个内部排序字典,该内部排序字典将排序键映射到相应的值。 - /// - /// 外部字典中的键类型。 - /// 内部字典中的排序键类型。 - /// 内部字典中的值类型。 - public class - OneToManySortedDictionary : Dictionary> - where TSortedKey : notnull where TKey : notnull - { - /// 缓存队列的回收限制 - private readonly int _recyclingLimit = 120; - /// 缓存队列,用于存储已回收的内部排序字典 - private readonly Queue> _queue = new Queue>(); - - /// - /// 创建一个新的 实例。 - /// - protected OneToManySortedDictionary() { } - - /// - /// 创建一个新的 实例。设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManySortedDictionary(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 检查字典是否包含指定的外部键。 - /// - /// 要检查的外部键。 - /// 如果字典包含指定的外部键,则为 true;否则为 false。 - public bool Contains(TKey key) - { - return this.ContainsKey(key); - } - - /// - /// 检查字典是否包含指定的外部键和排序键。 - /// - /// 要检查的外部键。 - /// 要检查的排序键。 - /// 如果字典包含指定的外部键和排序键,则为 true;否则为 false。 - public bool Contains(TKey key, TSortedKey sortedKey) - { - return TryGetValue(key, out var dic) && dic.ContainsKey(sortedKey); - } - - /// - /// 尝试从字典中获取指定外部键对应的内部排序字典。 - /// - /// 要获取内部排序字典的外部键。 - /// 获取到的内部排序字典,如果找不到则为 null。 - /// 如果找到内部排序字典,则为 true;否则为 false。 - public new bool TryGetValue(TKey key, out SortedDictionary dic) - { - return base.TryGetValue(key, out dic); - } - - /// - /// 尝试从字典中获取指定外部键和排序键对应的值。 - /// - /// 要获取值的外部键。 - /// 要获取值的排序键。 - /// 获取到的值,如果找不到则为 default。 - /// 如果找到值,则为 true;否则为 false。 - public bool TryGetValueBySortedKey(TKey key, TSortedKey sortedKey, out TValue value) - { - if (base.TryGetValue(key, out var dic)) - { - return dic.TryGetValue(sortedKey, out value); - } - - value = default; - return false; - } - - /// - /// 向字典中添加一个值,关联到指定的外部键和排序键。 - /// - /// 要关联值的外部键。 - /// 要关联值的排序键。 - /// 要添加的值。 - public void Add(TKey key, TSortedKey sortedKey, TValue value) - { - if (!TryGetValue(key, out var dic)) - { - dic = Fetch(); - dic.Add(sortedKey, value); - Add(key, dic); - - return; - } - - dic.Add(sortedKey, value); - } - - /// - /// 从字典中移除指定外部键和排序键关联的值。 - /// - /// 要移除值的外部键。 - /// 要移除值的排序键。 - /// 如果成功移除值,则为 true;否则为 false。 - public bool RemoveSortedKey(TKey key, TSortedKey sortedKey) - { - if (!TryGetValue(key, out var dic)) - { - return false; - } - - var isRemove = dic.Remove(sortedKey); - - if (dic.Count == 0) - { - isRemove = RemoveKey(key); - } - - return isRemove; - } - - /// - /// 从字典中移除指定外部键及其关联的所有值。 - /// - /// 要移除的外部键。 - /// 如果成功移除外部键及其关联的所有值,则为 true;否则为 false。 - public bool RemoveKey(TKey key) - { - if (!TryGetValue(key, out var list)) - { - return false; - } - - Remove(key); - Recycle(list); - return true; - } - - /// - /// 从缓存队列中获取一个内部排序字典。 - /// - /// 一个内部排序字典。 - private SortedDictionary Fetch() - { - return _queue.Count <= 0 ? new SortedDictionary() : _queue.Dequeue(); - } - - /// - /// 回收一个内部排序字典到缓存队列。 - /// - /// 要回收的内部排序字典。 - private void Recycle(SortedDictionary dic) - { - dic.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) - { - return; - } - - _queue.Enqueue(dic); - } - - /// - /// 清空字典以及内部排序字典缓存队列,释放所有资源。 - /// - protected new void Clear() - { - base.Clear(); - _queue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/ReuseDictionary.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/ReuseDictionary.cs deleted file mode 100644 index ebe12e9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/ReuseDictionary.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个可以重用的字典类,支持使用对象池管理。 - /// - /// 字典中键的类型。 - /// 字典中值的类型。 - public sealed class ReuseDictionary : Dictionary, IDisposable, IPool where TM : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static ReuseDictionary Create() - { -#if FANTASY_WEBGL - var entityDictionary = Pool>.Rent(); -#else - var entityDictionary = MultiThreadPool.Rent>(); -#endif - entityDictionary._isDispose = false; - entityDictionary._isPool = true; - return entityDictionary; - } - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/SortedDictionaryPool.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/SortedDictionaryPool.cs deleted file mode 100644 index 8db66a8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/Dictionary/SortedDictionaryPool.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -namespace Fantasy.DataStructure.Dictionary -{ - /// - /// 提供一个可以使用对象池管理的排序字典类。 - /// - /// - /// - public sealed class SortedDictionaryPool : SortedDictionary, IDisposable, IPool where TM : notnull - { - private bool _isPool; - private bool _isDispose; - - /// - /// 释放实例占用的资源。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); -#if FANTASY_WEBGL - Pool>.Return(this); -#else - MultiThreadPool.Return(this); -#endif - } - - /// - /// 创建一个新的 实例。 - /// - /// 新创建的实例。 - public static SortedDictionaryPool Create() - { -#if FANTASY_WEBGL - var dictionary = Pool>.Rent(); -#else - var dictionary = MultiThreadPool.Rent>(); -#endif - dictionary._isDispose = false; - dictionary._isPool = true; - return dictionary; - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueGenerics.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueGenerics.cs deleted file mode 100644 index 2ef6704..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueGenerics.cs +++ /dev/null @@ -1,121 +0,0 @@ -// ReSharper disable SwapViaDeconstruction -// ReSharper disable UseIndexFromEndExpression -// ReSharper disable ConvertToPrimaryConstructor -using System; -using System.Collections.Generic; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -#pragma warning disable CS8601 // Possible null reference assignment. -namespace Fantasy.DataStructure.PriorityQueue -{ - /// - /// 优先队列 - /// - /// 节点数据 - /// 排序的类型、 - public sealed class PriorityQueue where TPriority : IComparable - { - private readonly List> _heap; - - public PriorityQueue(int initialCapacity = 16) - { - _heap = new List>(initialCapacity); - } - - public int Count => _heap.Count; - - public void Enqueue(TElement element, TPriority priority) - { - _heap.Add(new PriorityQueueItem(element, priority)); - HeapifyUp(_heap.Count - 1); - } - - public TElement Dequeue() - { - if (_heap.Count == 0) - { - throw new InvalidOperationException("The queue is empty."); - } - - var item = _heap[0]; - _heap[0] = _heap[_heap.Count - 1]; - _heap.RemoveAt(_heap.Count - 1); - HeapifyDown(0); - return item.Element; - } - - public bool TryDequeue(out TElement element) - { - if (_heap.Count == 0) - { - element = default(TElement); - return false; - } - - element = Dequeue(); - return true; - } - - public TElement Peek() - { - if (_heap.Count == 0) - { - throw new InvalidOperationException("The queue is empty."); - } - return _heap[0].Element; - } - - // ReSharper disable once IdentifierTypo - private void HeapifyUp(int index) - { - while (index > 0) - { - var parentIndex = (index - 1) / 2; - if (_heap[index].Priority.CompareTo(_heap[parentIndex].Priority) >= 0) - { - break; - } - Swap(index, parentIndex); - index = parentIndex; - } - } - - // ReSharper disable once IdentifierTypo - private void HeapifyDown(int index) - { - var lastIndex = _heap.Count - 1; - while (true) - { - var smallestIndex = index; - var leftChildIndex = 2 * index + 1; - var rightChildIndex = 2 * index + 2; - - if (leftChildIndex <= lastIndex && _heap[leftChildIndex].Priority.CompareTo(_heap[smallestIndex].Priority) < 0) - { - smallestIndex = leftChildIndex; - } - - if (rightChildIndex <= lastIndex && _heap[rightChildIndex].Priority.CompareTo(_heap[smallestIndex].Priority) < 0) - { - smallestIndex = rightChildIndex; - } - - if (smallestIndex == index) - { - break; - } - - Swap(index, smallestIndex); - index = smallestIndex; - } - } - - private void Swap(int index1, int index2) - { - var temp = _heap[index1]; - _heap[index1] = _heap[index2]; - _heap[index2] = temp; - } - } -} - diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueItem.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueItem.cs deleted file mode 100644 index 5b020b2..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueItem.cs +++ /dev/null @@ -1,30 +0,0 @@ -// ReSharper disable ConvertToPrimaryConstructor -// ReSharper disable SwapViaDeconstruction -// ReSharper disable InconsistentNaming -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.DataStructure.PriorityQueue -{ - public struct PriorityQueueItemUint - { - public T Element { get; set; } - public uint Priority { get; set; } - - public PriorityQueueItemUint(T element, uint priority) - { - Element = element; - Priority = priority; - } - } - - public struct PriorityQueueItem - { - public T Element { get; } - public T1 Priority { get; } - - public PriorityQueueItem(T element, T1 priority) - { - Element = element; - Priority = priority; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueSimple.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueSimple.cs deleted file mode 100644 index 63a4418..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/PriorityQueue/PriorityQueueSimple.cs +++ /dev/null @@ -1,116 +0,0 @@ -// ReSharper disable SwapViaDeconstruction -// ReSharper disable UseIndexFromEndExpression -// ReSharper disable ConvertToPrimaryConstructor -using System; -using System.Collections.Generic; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8601 // Possible null reference assignment. -namespace Fantasy.DataStructure.PriorityQueue -{ - public sealed class PriorityQueue where T : IComparable - { - private readonly List _heap; - - public PriorityQueue(int initialCapacity = 16) - { - _heap = new List(initialCapacity); - } - - public int Count => _heap.Count; - - public void Enqueue(T item) - { - _heap.Add(item); - HeapifyUp(_heap.Count - 1); - } - - public T Dequeue() - { - if (_heap.Count == 0) - { - throw new InvalidOperationException("The queue is empty."); - } - - var item = _heap[0]; - var heapCount = _heap.Count - 1; - _heap[0] = _heap[heapCount]; - _heap.RemoveAt(heapCount); - HeapifyDown(0); - return item; - } - - public bool TryDequeue(out T item) - { - if (_heap.Count == 0) - { - item = default(T); - return false; - } - - item = Dequeue(); - return true; - } - - public T Peek() - { - if (_heap.Count == 0) - { - throw new InvalidOperationException("The queue is empty."); - } - return _heap[0]; - } - - // ReSharper disable once IdentifierTypo - private void HeapifyUp(int index) - { - while (index > 0) - { - var parentIndex = (index - 1) / 2; - if (_heap[index].CompareTo(_heap[parentIndex]) >= 0) - { - break; - } - Swap(index, parentIndex); - index = parentIndex; - } - } - - // ReSharper disable once IdentifierTypo - private void HeapifyDown(int index) - { - var lastIndex = _heap.Count - 1; - while (true) - { - var smallestIndex = index; - var leftChildIndex = 2 * index + 1; - var rightChildIndex = 2 * index + 2; - - if (leftChildIndex <= lastIndex && _heap[leftChildIndex].CompareTo(_heap[smallestIndex]) < 0) - { - smallestIndex = leftChildIndex; - } - - if (rightChildIndex <= lastIndex && _heap[rightChildIndex].CompareTo(_heap[smallestIndex]) < 0) - { - smallestIndex = rightChildIndex; - } - - if (smallestIndex == index) - { - break; - } - - Swap(index, smallestIndex); - index = smallestIndex; - } - } - - private void Swap(int index1, int index2) - { - var temp = _heap[index1]; - _heap[index1] = _heap[index2]; - _heap[index2] = temp; - } - } -} - diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTable.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTable.cs deleted file mode 100644 index acbc2c1..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTable.cs +++ /dev/null @@ -1,190 +0,0 @@ - -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -namespace Fantasy.DataStructure.SkipTable -{ - /// - /// 跳表数据结构(升序版) - /// - /// 跳表中存储的值的类型。 - public class SkipTable : SkipTableBase - { - /// - /// 创建一个新的跳表实例。 - /// - /// 跳表的最大层数。 - public SkipTable(int maxLayer = 8) : base(maxLayer) { } - - /// - /// 向跳表中添加一个新节点。 - /// - /// 节点的主排序键。 - /// 节点的副排序键。 - /// 节点的唯一键。 - /// 要添加的值。 - public override void Add(long sortKey, long viceKey, long key, TValue value) - { - var rLevel = 1; - - while (rLevel <= MaxLayer && Random.Next(3) == 0) - { - ++rLevel; - } - - SkipTableNode cur = TopHeader, last = null; - - for (var layer = MaxLayer; layer >= 1; --layer) - { - // 节点有next节点,且 (next主键 < 插入主键) 或 (next主键 == 插入主键 且 next副键 < 插入副键) - while (cur.Right != null && ((cur.Right.SortKey < sortKey) || - (cur.Right.SortKey == sortKey && cur.Right.ViceKey < viceKey))) - { - cur = cur.Right; - } - - if (layer <= rLevel) - { - var currentRight = cur.Right; - - // 在当前层插入新节点 - cur.Right = new SkipTableNode(sortKey, viceKey, key, value, layer == 1 ? cur.Index + 1 : 0, cur, cur.Right, null); - - if (currentRight != null) - { - currentRight.Left = cur.Right; - } - - if (last != null) - { - last.Down = cur.Right; - } - - if (layer == 1) - { - // 更新索引信息 - cur.Right.Index = cur.Index + 1; - Node.Add(key, cur.Right); - - SkipTableNode v = cur.Right.Right; - - while (v != null) - { - v.Index++; - v = v.Right; - } - } - - last = cur.Right; - } - - cur = cur.Down; - } - } - - /// - /// 从跳表中移除一个节点。 - /// - /// 节点的主排序键。 - /// 节点的副排序键。 - /// 节点的唯一键。 - /// 被移除的节点的值。 - /// 如果成功移除节点,则为 true;否则为 false。 - public override bool Remove(long sortKey, long viceKey, long key, out TValue value) - { - value = default; - var seen = false; - var cur = TopHeader; - - for (var layer = MaxLayer; layer >= 1; --layer) - { - // 先按照主键查找 再 按副键查找 - while (cur.Right != null && cur.Right.SortKey < sortKey && cur.Right.Key != key) cur = cur.Right; - while (cur.Right != null && (cur.Right.SortKey == sortKey && cur.Right.ViceKey <= viceKey) && - cur.Right.Key != key) cur = cur.Right; - - var isFind = false; - var currentCur = cur; - SkipTableNode removeCur = null; - // 如果当前不是要删除的节点、但主键和副键都一样、需要特殊处理下。 - if (cur.Right != null && cur.Right.Key == key) - { - isFind = true; - removeCur = cur.Right; - currentCur = cur; - } - else - { - // 先向左查找下 - var currentNode = cur.Left; - while (currentNode != null && currentNode.SortKey == sortKey && currentNode.ViceKey == viceKey) - { - if (currentNode.Key == key) - { - isFind = true; - removeCur = currentNode; - currentCur = currentNode.Left; - break; - } - - currentNode = currentNode.Left; - } - - // 再向右查找下 - if (!isFind) - { - currentNode = cur.Right; - while (currentNode != null && currentNode.SortKey == sortKey && currentNode.ViceKey == viceKey) - { - if (currentNode.Key == key) - { - isFind = true; - removeCur = currentNode; - currentCur = currentNode.Left; - break; - } - - currentNode = currentNode.Right; - } - } - } - - if (isFind && currentCur != null) - { - value = removeCur.Value; - currentCur.Right = removeCur.Right; - - if (removeCur.Right != null) - { - removeCur.Right.Left = currentCur; - removeCur.Right = null; - } - - removeCur.Left = null; - removeCur.Down = null; - removeCur.Value = default; - - if (layer == 1) - { - var tempCur = currentCur.Right; - while (tempCur != null) - { - tempCur.Index--; - tempCur = tempCur.Right; - } - - Node.Remove(removeCur.Key); - } - - seen = true; - } - - cur = cur.Down; - } - - return seen; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTableBase.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTableBase.cs deleted file mode 100644 index 82783e8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTableBase.cs +++ /dev/null @@ -1,282 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using Fantasy.DataStructure.Collection; - -#pragma warning disable CS8601 -#pragma warning disable CS8603 -#pragma warning disable CS8625 -#pragma warning disable CS8604 - -namespace Fantasy.DataStructure.SkipTable -{ - /// - /// 抽象的跳表基类,提供跳表的基本功能和操作。 - /// - /// 跳表中存储的值的类型。 - public abstract class SkipTableBase : IEnumerable> - { - /// - /// 跳表的最大层数 - /// - public readonly int MaxLayer; - /// - /// 跳表的顶部头节点 - /// - public readonly SkipTableNode TopHeader; - /// - /// 跳表的底部头节点 - /// - public SkipTableNode BottomHeader; - /// - /// 跳表中节点的数量,使用了 Node 字典的计数 - /// - public int Count => Node.Count; - /// - /// 用于生成随机数的随机数生成器 - /// - protected readonly Random Random = new Random(); - /// - /// 存储跳表节点的字典 - /// - protected readonly Dictionary> Node = new(); - /// - /// 用于辅助反向查找的栈 - /// - protected readonly Stack> AntiFindStack = new Stack>(); - - /// - /// 初始化一个新的跳表实例。 - /// - /// 跳表的最大层数,默认为 8。 - protected SkipTableBase(int maxLayer = 8) - { - MaxLayer = maxLayer; - var cur = TopHeader = new SkipTableNode(long.MinValue, 0, 0, default, 0, null, null, null); - - for (var layer = MaxLayer - 1; layer >= 1; --layer) - { - cur.Down = new SkipTableNode(long.MinValue, 0, 0, default, 0, null, null, null); - cur = cur.Down; - } - - BottomHeader = cur; - } - - /// - /// 获取指定键的节点的值,若不存在则返回默认值。 - /// - /// 要查找的键。 - public TValue this[long key] => !TryGetValueByKey(key, out TValue value) ? default : value; - - /// - /// 获取指定键的节点在跳表中的排名。 - /// - /// 要查找的键。 - /// 节点的排名。 - public int GetRanking(long key) - { - if (!Node.TryGetValue(key, out var node)) - { - return 0; - } - - return node.Index; - } - - /// - /// 获取指定键的反向排名,即在比该键更大的节点中的排名。 - /// - /// 要查找的键。 - /// 反向排名。 - public int GetAntiRanking(long key) - { - var ranking = GetRanking(key); - - if (ranking == 0) - { - return 0; - } - - return Count + 1 - ranking; - } - - /// - /// 尝试通过键获取节点的值。 - /// - /// 要查找的键。 - /// 获取到的节点的值,如果键不存在则为默认值。 - /// 是否成功获取节点的值。 - public bool TryGetValueByKey(long key, out TValue value) - { - if (!Node.TryGetValue(key, out var node)) - { - value = default; - return false; - } - - value = node.Value; - return true; - } - - /// - /// 尝试通过键获取节点。 - /// - /// 要查找的键。 - /// 获取到的节点,如果键不存在则为 null。 - /// 是否成功获取节点。 - public bool TryGetNodeByKey(long key, out SkipTableNode node) - { - if (Node.TryGetValue(key, out node)) - { - return true; - } - - return false; - } - - /// - /// 在跳表中查找节点,返回从起始位置到结束位置的节点列表。 - /// - /// 起始位置的排名。 - /// 结束位置的排名。 - /// 用于存储节点列表的 实例。 - public void Find(int start, int end, ListPool> list) - { - var cur = BottomHeader; - var count = end - start; - - for (var i = 0; i < start; i++) - { - cur = cur.Right; - } - - for (var i = 0; i <= count; i++) - { - if (cur == null) - { - break; - } - - list.Add(cur); - cur = cur.Right; - } - } - - /// - /// 在跳表中进行反向查找节点,返回从结束位置到起始位置的节点列表。 - /// - /// 结束位置的排名。 - /// 起始位置的排名。 - /// 用于存储节点列表的 实例。 - public void AntiFind(int start, int end, ListPool> list) - { - var cur = BottomHeader; - start = Count + 1 - start; - end = start - end; - - for (var i = 0; i < start; i++) - { - cur = cur.Right; - - if (cur == null) - { - break; - } - - if (i < end) - { - continue; - } - - AntiFindStack.Push(cur); - } - - while (AntiFindStack.TryPop(out var node)) - { - list.Add(node); - } - } - - /// - /// 获取跳表中最后一个节点的值。 - /// - /// 最后一个节点的值。 - public TValue GetLastValue() - { - var cur = TopHeader; - - while (cur.Right != null || cur.Down != null) - { - while (cur.Right != null) - { - cur = cur.Right; - } - - if (cur.Down != null) - { - cur = cur.Down; - } - } - - return cur.Value; - } - - /// - /// 移除跳表中指定键的节点。 - /// - /// 要移除的节点的键。 - /// 移除是否成功。 - public bool Remove(long key) - { - if (!Node.TryGetValue(key, out var node)) - { - return false; - } - - return Remove(node.SortKey, node.ViceKey, key, out _); - } - - /// - /// 向跳表中添加节点。 - /// - /// 节点的排序键。 - /// 节点的副键。 - /// 节点的键。 - /// 节点的值。 - public abstract void Add(long sortKey, long viceKey, long key, TValue value); - - /// - /// 从跳表中移除指定键的节点。 - /// - /// 节点的排序键。 - /// 节点的副键。 - /// 节点的键。 - /// 被移除的节点的值。 - /// 移除是否成功。 - public abstract bool Remove(long sortKey, long viceKey, long key, out TValue value); - - /// - /// 返回一个枚举器,用于遍历跳表中的节点。 - /// - /// 一个可用于遍历跳表节点的枚举器。 - public IEnumerator> GetEnumerator() - { - var cur = BottomHeader.Right; - while (cur != null) - { - yield return cur; - cur = cur.Right; - } - } - - /// - /// 返回一个非泛型枚举器,用于遍历跳表中的节点。 - /// - /// 一个非泛型枚举器,可用于遍历跳表节点。 - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTableDesc.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTableDesc.cs deleted file mode 100644 index 63daa16..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTableDesc.cs +++ /dev/null @@ -1,188 +0,0 @@ - -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8601 // Possible null reference assignment. -namespace Fantasy.DataStructure.SkipTable -{ - /// - /// 跳表降序版,用于存储降序排列的数据。 - /// - /// 存储的值的类型。 - public class SkipTableDesc : SkipTableBase - { - /// - /// 初始化跳表降序版的新实例。 - /// - /// 跳表的最大层数,默认为 8。 - public SkipTableDesc(int maxLayer = 8) : base(maxLayer) { } - - /// - /// 向跳表中添加一个节点,根据降序规则进行插入。 - /// - /// 排序主键。 - /// 副键。 - /// 键。 - /// 值。 - public override void Add(long sortKey, long viceKey, long key, TValue value) - { - var rLevel = 1; - - while (rLevel <= MaxLayer && Random.Next(3) == 0) - { - ++rLevel; - } - - SkipTableNode cur = TopHeader, last = null; - - for (var layer = MaxLayer; layer >= 1; --layer) - { - // 节点有next节点,且 (next主键 > 插入主键) 或 (next主键 == 插入主键 且 next副键 > 插入副键) - while (cur.Right != null && ((cur.Right.SortKey > sortKey) || - (cur.Right.SortKey == sortKey && cur.Right.ViceKey > viceKey))) - { - cur = cur.Right; - } - - if (layer <= rLevel) - { - var currentRight = cur.Right; - cur.Right = new SkipTableNode(sortKey, viceKey, key, value, - layer == 1 ? cur.Index + 1 : 0, cur, cur.Right, null); - - if (currentRight != null) - { - currentRight.Left = cur.Right; - } - - if (last != null) - { - last.Down = cur.Right; - } - - if (layer == 1) - { - cur.Right.Index = cur.Index + 1; - Node.Add(key, cur.Right); - - SkipTableNode v = cur.Right.Right; - - while (v != null) - { - v.Index++; - v = v.Right; - } - } - - last = cur.Right; - } - - cur = cur.Down; - } - } - - /// - /// 从跳表中移除一个节点,根据降序规则进行移除。 - /// - /// 排序主键。 - /// 副键。 - /// 键。 - /// 移除的节点值。 - /// 如果成功移除节点,则返回 true,否则返回 false。 - public override bool Remove(long sortKey, long viceKey, long key, out TValue value) - { - value = default; - var seen = false; - var cur = TopHeader; - - for (var layer = MaxLayer; layer >= 1; --layer) - { - // 先按照主键查找 再 按副键查找 - while (cur.Right != null && cur.Right.SortKey > sortKey && cur.Right.Key != key) cur = cur.Right; - while (cur.Right != null && (cur.Right.SortKey == sortKey && cur.Right.ViceKey >= viceKey) && - cur.Right.Key != key) cur = cur.Right; - - var isFind = false; - var currentCur = cur; - SkipTableNode removeCur = null; - // 如果当前不是要删除的节点、但主键和副键都一样、需要特殊处理下。 - if (cur.Right != null && cur.Right.Key == key) - { - isFind = true; - removeCur = cur.Right; - currentCur = cur; - } - else - { - // 先向左查找下 - var currentNode = cur.Left; - while (currentNode != null && currentNode.SortKey == sortKey && currentNode.ViceKey == viceKey) - { - if (currentNode.Key == key) - { - isFind = true; - removeCur = currentNode; - currentCur = currentNode.Left; - break; - } - - currentNode = currentNode.Left; - } - - // 再向右查找下 - if (!isFind) - { - currentNode = cur.Right; - while (currentNode != null && currentNode.SortKey == sortKey && currentNode.ViceKey == viceKey) - { - if (currentNode.Key == key) - { - isFind = true; - removeCur = currentNode; - currentCur = currentNode.Left; - break; - } - - currentNode = currentNode.Right; - } - } - } - - if (isFind && currentCur != null) - { - value = removeCur.Value; - currentCur.Right = removeCur.Right; - - if (removeCur.Right != null) - { - removeCur.Right.Left = currentCur; - removeCur.Right = null; - } - - removeCur.Left = null; - removeCur.Down = null; - removeCur.Value = default; - - if (layer == 1) - { - var tempCur = currentCur.Right; - while (tempCur != null) - { - tempCur.Index--; - tempCur = tempCur.Right; - } - - Node.Remove(removeCur.Key); - } - - seen = true; - } - - cur = cur.Down; - } - - return seen; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTableNode.cs b/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTableNode.cs deleted file mode 100644 index 8a1a144..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/DataStructure/SkipTable/SkipTableNode.cs +++ /dev/null @@ -1,68 +0,0 @@ -namespace Fantasy.DataStructure.SkipTable -{ - /// - /// 跳跃表节点。 - /// - /// 节点的值的类型。 - public class SkipTableNode - { - /// - /// 节点在跳跃表中的索引。 - /// - public int Index; - /// - /// 节点的主键。 - /// - public long Key; - /// - /// 节点的排序键。 - /// - public long SortKey; - /// - /// 节点的副键。 - /// - public long ViceKey; - /// - /// 节点存储的值。 - /// - public TValue Value; - /// - /// 指向左侧节点的引用。 - /// - public SkipTableNode Left; - /// - /// 指向右侧节点的引用。 - /// - public SkipTableNode Right; - /// - /// 指向下一层节点的引用。 - /// - public SkipTableNode Down; - - /// - /// 初始化跳跃表节点的新实例。 - /// - /// 节点的排序键。 - /// 节点的副键。 - /// 节点的主键。 - /// 节点存储的值。 - /// 节点在跳跃表中的索引。 - /// 指向左侧节点的引用。 - /// 指向右侧节点的引用。 - /// 指向下一层节点的引用。 - public SkipTableNode(long sortKey, long viceKey, long key, TValue value, int index, - SkipTableNode l, - SkipTableNode r, - SkipTableNode d) - { - Left = l; - Right = r; - Down = d; - Value = value; - Key = key; - Index = index; - SortKey = sortKey; - ViceKey = viceKey; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLock.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLock.cs deleted file mode 100644 index a95d8f3..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLock.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -namespace Fantasy.Async -{ - /// - /// 协程锁专用的对象池 - /// - public sealed class CoroutineLockPool : PoolCore - { - /// - /// 协程锁专用的对象池的构造函数 - /// - public CoroutineLockPool() : base(2000) { } - } - - /// - /// 协程锁 - /// - public sealed class CoroutineLock : IPool, IDisposable - { - private Scene _scene; - private CoroutineLockComponent _coroutineLockComponent; - private readonly Dictionary _queue = new Dictionary(); - /// - /// 表示是否是对象池中创建的 - /// - private bool _isPool; - /// - /// 协程锁的类型 - /// - public long CoroutineLockType { get; private set; } - - internal void Initialize(CoroutineLockComponent coroutineLockComponent, ref long coroutineLockType) - { - _scene = coroutineLockComponent.Scene; - CoroutineLockType = coroutineLockType; - _coroutineLockComponent = coroutineLockComponent; - } - /// - /// 销毁协程锁,如果调用了该方法,所有使用当前协程锁等待的逻辑会按照顺序释放锁。 - /// - public void Dispose() - { - foreach (var (_, coroutineLockQueue) in _queue) - { - while (TryCoroutineLockQueueDequeue(coroutineLockQueue)) { } - } - - _queue.Clear(); - _scene = null; - CoroutineLockType = 0; - _coroutineLockComponent = null; - } - /// - /// 等待上一个任务完成 - /// - /// 需要等待的Id - /// 用于查询协程锁的标记,可不传入,只有在超时的时候排查是哪个锁超时时使用 - /// 等待多久会超时,当到达设定的时候会把当前锁给按照超时处理 - /// - public async FTask Wait(long coroutineLockQueueKey, string tag = null, int timeOut = 30000) - { - var waitCoroutineLock = _coroutineLockComponent.WaitCoroutineLockPool.Rent(this, ref coroutineLockQueueKey, tag, timeOut); - - if (!_queue.TryGetValue(coroutineLockQueueKey, out var queue)) - { - queue = _coroutineLockComponent.CoroutineLockQueuePool.Rent(); - _queue.Add(coroutineLockQueueKey, queue); - return waitCoroutineLock; - } - - queue.Enqueue(waitCoroutineLock); - return await waitCoroutineLock.Tcs; - } - /// - /// 按照先入先出的顺序,释放最早的一个协程锁 - /// - /// - public void Release(long coroutineLockQueueKey) - { - if (!_queue.TryGetValue(coroutineLockQueueKey, out var coroutineLockQueue)) - { - return; - } - - if (!TryCoroutineLockQueueDequeue(coroutineLockQueue)) - { - _queue.Remove(coroutineLockQueueKey); - } - } - - private bool TryCoroutineLockQueueDequeue(CoroutineLockQueue coroutineLockQueue) - { - if (!coroutineLockQueue.TryDequeue(out var waitCoroutineLock)) - { - _coroutineLockComponent.CoroutineLockQueuePool.Return(coroutineLockQueue); - return false; - } - - if (waitCoroutineLock.TimerId != 0) - { - _scene.TimerComponent.Net.Remove(waitCoroutineLock.TimerId); - } - - try - { - // 放到下一帧执行,如果不这样会导致逻辑的顺序不正常。 - _scene.ThreadSynchronizationContext.Post(waitCoroutineLock.SetResult); - } - catch (Exception e) - { - Log.Error($"Error in disposing CoroutineLock: {e}"); - } - - return true; - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockComponent.cs deleted file mode 100644 index 4644274..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockComponent.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Collections.Generic; -using Fantasy.Entitas; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Async -{ - /// - /// 协程锁组件 - /// - public class CoroutineLockComponent : Entity - { - private long _lockId; - private CoroutineLockPool _coroutineLockPool; - internal WaitCoroutineLockPool WaitCoroutineLockPool { get; private set; } - internal CoroutineLockQueuePool CoroutineLockQueuePool { get; private set; } - private readonly Dictionary _coroutineLocks = new Dictionary(); - internal CoroutineLockComponent Initialize() - { - _coroutineLockPool = new CoroutineLockPool(); - CoroutineLockQueuePool = new CoroutineLockQueuePool(); - WaitCoroutineLockPool = new WaitCoroutineLockPool(this); - return this; - } - - internal long LockId => ++_lockId; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - public override void Dispose() -#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member - { - if (IsDisposed) - { - return; - } - - _lockId = 0; - base.Dispose(); - } - - /// - /// 创建一个新的协程锁 - /// 使用这个方法创建的协程锁,需要手动释放管理CoroutineLock。 - /// 不会再CoroutineLockComponent理进行管理。 - /// - /// - /// - public CoroutineLock Create(long coroutineLockType) - { - var coroutineLock = _coroutineLockPool.Rent(); - coroutineLock.Initialize(this, ref coroutineLockType); - return coroutineLock; - } - - /// - /// 请求一个协程锁。 - /// 使用这个方法创建的协程锁,会自动释放CoroutineLockQueueType。 - /// - /// 锁类型 - /// 锁队列Id - /// 当某些锁超时,需要一个标记来方便排查问题,正常的情况下这个默认为null就可以。 - /// 设置锁的超时时间,让超过设置的时间会触发超时,保证锁不会因为某一个锁一直不解锁导致卡住的问题。 - /// - /// 返回的WaitCoroutineLock通过Dispose来解除这个锁、建议用using来保住这个锁。 - /// 也可以返回的WaitCoroutineLock通过CoroutineLockComponent.UnLock来解除这个锁。 - /// - public FTask Wait(long coroutineLockType, long coroutineLockQueueKey, string tag = null, int time = 30000) - { - if (!_coroutineLocks.TryGetValue(coroutineLockType, out var coroutineLock)) - { - coroutineLock = _coroutineLockPool.Rent(); - coroutineLock.Initialize(this, ref coroutineLockType); - _coroutineLocks.Add(coroutineLockType, coroutineLock); - } - - return coroutineLock.Wait(coroutineLockQueueKey, tag, time); - } - - /// - /// 解除一个协程锁。 - /// - /// - /// - public void Release(int coroutineLockType, long coroutineLockQueueKey) - { - if (IsDisposed) - { - return; - } - - if (!_coroutineLocks.TryGetValue(coroutineLockType, out var coroutineLock)) - { - return; - } - - coroutineLock.Release(coroutineLockQueueKey); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockQueue.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockQueue.cs deleted file mode 100644 index 2948aca..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/CoroutineLockQueue.cs +++ /dev/null @@ -1,35 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -namespace Fantasy.Async -{ - internal sealed class CoroutineLockQueuePool : PoolCore - { - public CoroutineLockQueuePool() : base(2000) { } - } - - internal sealed class CoroutineLockQueue : Queue, IPool - { - private bool _isPool; - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/WaitCoroutineLock.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/WaitCoroutineLock.cs deleted file mode 100644 index 28d04d4..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/CoroutineLock/WaitCoroutineLock.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System; -using Fantasy.Event; -using Fantasy.Pool; - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Async -{ - internal sealed class WaitCoroutineLockPool : PoolCore - { - private readonly Scene _scene; - private readonly CoroutineLockComponent _coroutineLockComponent; - - public WaitCoroutineLockPool(CoroutineLockComponent coroutineLockComponent) : base(2000) - { - _scene = coroutineLockComponent.Scene; - _coroutineLockComponent = coroutineLockComponent; - } - - public WaitCoroutineLock Rent(CoroutineLock coroutineLock, ref long coroutineLockQueueKey, string tag = null, int timeOut = 30000) - { - var timerId = 0L; - var lockId = _coroutineLockComponent.LockId; - var waitCoroutineLock = _coroutineLockComponent.WaitCoroutineLockPool.Rent(); - - if (timeOut > 0) - { - timerId = _scene.TimerComponent.Net.OnceTimer(timeOut, new CoroutineLockTimeout(ref lockId, waitCoroutineLock)); - } - - waitCoroutineLock.Initialize(coroutineLock, this, ref coroutineLockQueueKey, ref timerId, ref lockId, tag); - return waitCoroutineLock; - } - } - - internal struct CoroutineLockTimeout - { - public readonly long LockId; - public readonly WaitCoroutineLock WaitCoroutineLock; - - public CoroutineLockTimeout(ref long lockId, WaitCoroutineLock waitCoroutineLock) - { - LockId = lockId; - WaitCoroutineLock = waitCoroutineLock; - } - } - - internal sealed class OnCoroutineLockTimeout : EventSystem - { - protected override void Handler(CoroutineLockTimeout self) - { - var selfWaitCoroutineLock = self.WaitCoroutineLock; - - if (self.LockId != selfWaitCoroutineLock.LockId) - { - return; - } - - Log.Error($"coroutine lock timeout CoroutineLockQueueType:{selfWaitCoroutineLock.CoroutineLock.CoroutineLockType} Key:{selfWaitCoroutineLock.CoroutineLockQueueKey} Tag:{selfWaitCoroutineLock.Tag}"); - } - } - - /// - /// 一个协程锁的实例,用户可以用过这个手动释放锁 - /// - public sealed class WaitCoroutineLock : IPool, IDisposable - { - private bool _isPool; - internal string Tag { get; private set; } - internal long LockId { get; private set; } - internal long TimerId { get; private set; } - internal long CoroutineLockQueueKey { get; private set; } - internal CoroutineLock CoroutineLock { get; private set; } - - private bool _isSetResult; - private FTask _tcs; - private WaitCoroutineLockPool _waitCoroutineLockPool; - internal void Initialize(CoroutineLock coroutineLock, WaitCoroutineLockPool waitCoroutineLockPool, ref long coroutineLockQueueKey, ref long timerId, ref long lockId, string tag) - { - Tag = tag; - LockId = lockId; - TimerId = timerId; - CoroutineLock = coroutineLock; - CoroutineLockQueueKey = coroutineLockQueueKey; - _waitCoroutineLockPool = waitCoroutineLockPool; - } - /// - /// 释放协程锁 - /// - public void Dispose() - { - if (LockId == 0) - { - Log.Error("WaitCoroutineLock is already disposed"); - return; - } - - CoroutineLock.Release(CoroutineLockQueueKey); - - _tcs = null; - Tag = null; - LockId = 0; - TimerId = 0; - _isSetResult = false; - CoroutineLockQueueKey = 0; - _waitCoroutineLockPool.Return(this); - CoroutineLock = null; - _waitCoroutineLockPool = null; - } - - internal FTask Tcs - { - get { return _tcs ??= FTask.Create(); } - } - - internal void SetResult() - { - if (_isSetResult) - { - Log.Error("WaitCoroutineLock is already SetResult"); - return; - } - - _isSetResult = true; - Tcs.SetResult(this); - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/EntityComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/EntityComponent.cs deleted file mode 100644 index 5baa63e..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/EntityComponent.cs +++ /dev/null @@ -1,471 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8765 // Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes). - -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Entitas -{ - internal sealed class UpdateQueueInfo - { - public bool IsStop; - public readonly Type Type; - public readonly long RunTimeId; - - public UpdateQueueInfo(Type type, long runTimeId) - { - Type = type; - IsStop = false; - RunTimeId = runTimeId; - } - } - - internal sealed class FrameUpdateQueueInfo - { - public readonly Type Type; - public readonly long RunTimeId; - - public FrameUpdateQueueInfo(Type type, long runTimeId) - { - Type = type; - RunTimeId = runTimeId; - } - } - - internal struct CustomEntitiesSystemKey : IEquatable - { - public int CustomEventType { get; } - public Type EntitiesType { get; } - public CustomEntitiesSystemKey(int customEventType, Type entitiesType) - { - CustomEventType = customEventType; - EntitiesType = entitiesType; - } - public bool Equals(CustomEntitiesSystemKey other) - { - return CustomEventType == other.CustomEventType && EntitiesType == other.EntitiesType; - } - - public override bool Equals(object obj) - { - return obj is CustomEntitiesSystemKey other && Equals(other); - } - - public override int GetHashCode() - { - return HashCode.Combine(CustomEventType, EntitiesType); - } - } - - /// - /// Entity管理组件 - /// - public sealed class EntityComponent : Entity, ISceneUpdate, IAssembly - { - private readonly OneToManyList _assemblyList = new(); - private readonly OneToManyList _assemblyHashCodes = new(); - - private readonly Dictionary _awakeSystems = new(); - private readonly Dictionary _updateSystems = new(); - private readonly Dictionary _destroySystems = new(); - private readonly Dictionary _deserializeSystems = new(); - private readonly Dictionary _frameUpdateSystem = new(); - - private readonly OneToManyList _assemblyCustomSystemList = new(); - private readonly Dictionary _customEntitiesSystems = new Dictionary(); - - private readonly Dictionary _hashCodes = new Dictionary(); - private readonly Queue _updateQueue = new Queue(); - private readonly Queue _frameUpdateQueue = new Queue(); - private readonly Dictionary _updateQueueDic = new Dictionary(); - - internal async FTask Initialize() - { - await AssemblySystem.Register(this); - return this; - } - - #region Assembly - - public FTask Load(long assemblyIdentity) - { - var task = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - LoadInner(assemblyIdentity); - task.SetResult(); - }); - return task; - } - - public FTask ReLoad(long assemblyIdentity) - { - var task = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - LoadInner(assemblyIdentity); - task.SetResult(); - }); - - return task; - } - - public FTask OnUnLoad(long assemblyIdentity) - { - var task = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - task.SetResult(); - }); - return task; - } - - private void LoadInner(long assemblyIdentity) - { - foreach (var entityType in AssemblySystem.ForEach(assemblyIdentity, typeof(IEntity))) - { - _hashCodes.Add(entityType, HashCodeHelper.ComputeHash64(entityType.FullName)); - _assemblyHashCodes.Add(assemblyIdentity, entityType); - } - - foreach (var entitiesSystemType in AssemblySystem.ForEach(assemblyIdentity, typeof(IEntitiesSystem))) - { - Type entitiesType = null; - var entity = Activator.CreateInstance(entitiesSystemType); - - switch (entity) - { - case IAwakeSystem iAwakeSystem: - { - entitiesType = iAwakeSystem.EntitiesType(); - _awakeSystems.Add(entitiesType, iAwakeSystem); - break; - } - case IDestroySystem iDestroySystem: - { - entitiesType = iDestroySystem.EntitiesType(); - _destroySystems.Add(entitiesType, iDestroySystem); - break; - } - case IDeserializeSystem iDeserializeSystem: - { - entitiesType = iDeserializeSystem.EntitiesType(); - _deserializeSystems.Add(entitiesType, iDeserializeSystem); - break; - } - case IUpdateSystem iUpdateSystem: - { - entitiesType = iUpdateSystem.EntitiesType(); - _updateSystems.Add(entitiesType, iUpdateSystem); - break; - } - case IFrameUpdateSystem iFrameUpdateSystem: - { - entitiesType = iFrameUpdateSystem.EntitiesType(); - _frameUpdateSystem.Add(entitiesType, iFrameUpdateSystem); - break; - } - default: - { - Log.Error($"IEntitiesSystem not support type {entitiesSystemType}"); - return; - } - } - - _assemblyList.Add(assemblyIdentity, entitiesType); - } - - foreach (var customEntitiesSystemType in AssemblySystem.ForEach(assemblyIdentity, typeof(ICustomEntitiesSystem))) - { - var entity = (ICustomEntitiesSystem)Activator.CreateInstance(customEntitiesSystemType); - var customEntitiesSystemKey = new CustomEntitiesSystemKey(entity.CustomEventType, entity.EntitiesType()); - _customEntitiesSystems.Add(customEntitiesSystemKey, entity); - _assemblyCustomSystemList.Add(assemblyIdentity, customEntitiesSystemKey); - } - } - - private void OnUnLoadInner(long assemblyIdentity) - { - if (_assemblyHashCodes.TryGetValue(assemblyIdentity, out var entityType)) - { - foreach (var type in entityType) - { - _hashCodes.Remove(type); - } - - _assemblyHashCodes.RemoveByKey(assemblyIdentity); - } - - if (_assemblyList.TryGetValue(assemblyIdentity, out var assembly)) - { - foreach (var type in assembly) - { - _awakeSystems.Remove(type); - _updateSystems.Remove(type); - _destroySystems.Remove(type); - _deserializeSystems.Remove(type); - _frameUpdateSystem.Remove(type); - } - - _assemblyList.RemoveByKey(assemblyIdentity); - } - - if (_assemblyCustomSystemList.TryGetValue(assemblyIdentity, out var customSystemAssembly)) - { - foreach (var customEntitiesSystemKey in customSystemAssembly) - { - _customEntitiesSystems.Remove(customEntitiesSystemKey); - } - - _assemblyCustomSystemList.RemoveByKey(assemblyIdentity); - } - } - - #endregion - - #region Event - - /// - /// 触发实体的唤醒方法 - /// - /// 实体对象 - public void Awake(Entity entity) - { - if (!_awakeSystems.TryGetValue(entity.Type, out var awakeSystem)) - { - return; - } - - try - { - awakeSystem.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{entity.Type.FullName} Error {e}"); - } - } - - /// - /// 触发实体的销毁方法 - /// - /// 实体对象 - public void Destroy(Entity entity) - { - if (!_destroySystems.TryGetValue(entity.Type, out var system)) - { - return; - } - - try - { - system.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{entity.Type.FullName} Destroy Error {e}"); - } - } - - /// - /// 触发实体的反序列化方法 - /// - /// 实体对象 - public void Deserialize(Entity entity) - { - if (!_deserializeSystems.TryGetValue(entity.Type, out var system)) - { - return; - } - - try - { - system.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{entity.Type.FullName} Deserialize Error {e}"); - } - } - - #endregion - - #region CustomEvent - - public void CustomSystem(Entity entity, int customEventType) - { - var customEntitiesSystemKey = new CustomEntitiesSystemKey(customEventType, entity.Type); - - if (!_customEntitiesSystems.TryGetValue(customEntitiesSystemKey, out var system)) - { - return; - } - - try - { - system.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{entity.Type.FullName} CustomSystem Error {e}"); - } - } - - #endregion - - #region Update - - /// - /// 将实体加入更新队列,准备进行更新 - /// - /// 实体对象 - public void StartUpdate(Entity entity) - { - var type = entity.Type; - var entityRuntimeId = entity.RuntimeId; - - if (_updateSystems.ContainsKey(type)) - { - var updateQueueInfo = new UpdateQueueInfo(type, entityRuntimeId); - _updateQueue.Enqueue(updateQueueInfo); - _updateQueueDic.Add(entityRuntimeId, updateQueueInfo); - } - - if (_frameUpdateSystem.ContainsKey(type)) - { - _frameUpdateQueue.Enqueue(new FrameUpdateQueueInfo(type, entityRuntimeId)); - } - } - - /// - /// 停止实体进行更新 - /// - /// 实体对象 - public void StopUpdate(Entity entity) - { - if (!_updateQueueDic.Remove(entity.RuntimeId, out var updateQueueInfo)) - { - return; - } - - updateQueueInfo.IsStop = true; - } - - /// - /// 执行实体系统的更新逻辑 - /// - public void Update() - { - var updateQueueCount = _updateQueue.Count; - - while (updateQueueCount-- > 0) - { - var updateQueueStruct = _updateQueue.Dequeue(); - - if (updateQueueStruct.IsStop) - { - continue; - } - - if (!_updateSystems.TryGetValue(updateQueueStruct.Type, out var updateSystem)) - { - continue; - } - - var entity = Scene.GetEntity(updateQueueStruct.RunTimeId); - - if (entity == null || entity.IsDisposed) - { - _updateQueueDic.Remove(updateQueueStruct.RunTimeId); - continue; - } - - _updateQueue.Enqueue(updateQueueStruct); - - try - { - updateSystem.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{updateQueueStruct.Type.FullName} Update Error {e}"); - } - } - } - - /// - /// 执行实体系统的帧更新逻辑 - /// - public void FrameUpdate() - { - var count = _frameUpdateQueue.Count; - - while (count-- > 0) - { - var frameUpdateQueueStruct = _frameUpdateQueue.Dequeue(); - - if (!_frameUpdateSystem.TryGetValue(frameUpdateQueueStruct.Type, out var frameUpdateSystem)) - { - continue; - } - - var entity = Scene.GetEntity(frameUpdateQueueStruct.RunTimeId); - - if (entity == null || entity.IsDisposed) - { - continue; - } - - _frameUpdateQueue.Enqueue(frameUpdateQueueStruct); - - try - { - frameUpdateSystem.Invoke(entity); - } - catch (Exception e) - { - Log.Error($"{frameUpdateQueueStruct.Type.FullName} FrameUpdate Error {e}"); - } - } - } - - #endregion - - public long GetHashCode(Type type) - { - return _hashCodes[type]; - } - - /// - /// 释放实体系统管理器资源 - /// - public override void Dispose() - { - _updateQueue.Clear(); - _frameUpdateQueue.Clear(); - - _assemblyList.Clear(); - _awakeSystems.Clear(); - _updateSystems.Clear(); - _destroySystems.Clear(); - _deserializeSystems.Clear(); - _frameUpdateSystem.Clear(); - - AssemblySystem.UnRegister(this); - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/EventComponent/EventComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/EventComponent/EventComponent.cs deleted file mode 100644 index 30ca61e..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/EventComponent/EventComponent.cs +++ /dev/null @@ -1,252 +0,0 @@ -using System; -using System.Reflection; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; - -// ReSharper disable PossibleMultipleEnumeration -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -// ReSharper disable MethodOverloadWithOptionalParameter - -namespace Fantasy.Event -{ - internal sealed class EventCache - { - public readonly Type EnventType; - public readonly object Obj; - public EventCache(Type enventType, object obj) - { - EnventType = enventType; - Obj = obj; - } - } - - public sealed class EventComponent : Entity, IAssembly - { - private readonly OneToManyList _events = new(); - private readonly OneToManyList _asyncEvents = new(); - private readonly OneToManyList _assemblyEvents = new(); - private readonly OneToManyList _assemblyAsyncEvents = new(); - - internal async FTask Initialize() - { - await AssemblySystem.Register(this); - return this; - } - - #region Assembly - - public async FTask Load(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask ReLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask OnUnLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - private void LoadInner(long assemblyIdentity) - { - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IEvent))) - { - var @event = (IEvent)Activator.CreateInstance(type); - - if (@event == null) - { - continue; - } - - var eventType = @event.EventType(); - _events.Add(eventType, @event); - _assemblyEvents.Add(assemblyIdentity, new EventCache(eventType, @event)); - } - - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IAsyncEvent))) - { - var @event = (IAsyncEvent)Activator.CreateInstance(type); - - if (@event == null) - { - continue; - } - - var eventType = @event.EventType(); - _asyncEvents.Add(eventType, @event); - _assemblyAsyncEvents.Add(assemblyIdentity, new EventCache(eventType, @event)); - } - } - - private void OnUnLoadInner(long assemblyIdentity) - { - if (_assemblyEvents.TryGetValue(assemblyIdentity, out var events)) - { - foreach (var @event in events) - { - _events.RemoveValue(@event.EnventType, (IEvent)@event.Obj); - } - - _assemblyEvents.RemoveByKey(assemblyIdentity); - } - - if (_assemblyAsyncEvents.TryGetValue(assemblyIdentity, out var asyncEvents)) - { - foreach (var @event in asyncEvents) - { - _asyncEvents.RemoveValue(@event.EnventType, (IAsyncEvent)@event.Obj); - } - - _assemblyAsyncEvents.RemoveByKey(assemblyIdentity); - } - } - - #endregion - - #region Publish - - /// - /// 发布一个值类型的事件数据。 - /// - /// 事件数据类型(值类型)。 - /// 事件数据实例。 - public void Publish(TEventData eventData) where TEventData : struct - { - if (!_events.TryGetValue(typeof(TEventData), out var list)) - { - return; - } - - foreach (var @event in list) - { - try - { - @event.Invoke(eventData); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - /// - /// 发布一个继承自 Entity 的事件数据。 - /// - /// 事件数据类型(继承自 Entity)。 - /// 事件数据实例。 - /// 是否释放事件数据。 - public void Publish(TEventData eventData, bool isDisposed = true) where TEventData : Entity - { - if (!_events.TryGetValue(typeof(TEventData), out var list)) - { - return; - } - - foreach (var @event in list) - { - try - { - @event.Invoke(eventData); - } - catch (Exception e) - { - Log.Error(e); - } - } - - if (isDisposed) - { - eventData.Dispose(); - } - } - - /// - /// 异步发布一个值类型的事件数据。 - /// - /// 事件数据类型(值类型)。 - /// 事件数据实例。 - /// 表示异步操作的任务。 - public async FTask PublishAsync(TEventData eventData) where TEventData : struct - { - if (!_asyncEvents.TryGetValue(typeof(TEventData), out var list)) - { - return; - } - - using var tasks = ListPool.Create(); - - foreach (var @event in list) - { - tasks.Add(@event.InvokeAsync(eventData)); - } - - await FTask.WaitAll(tasks); - } - - /// - /// 异步发布一个继承自 Entity 的事件数据。 - /// - /// 事件数据类型(继承自 Entity)。 - /// 事件数据实例。 - /// 是否释放事件数据。 - /// 表示异步操作的任务。 - public async FTask PublishAsync(TEventData eventData, bool isDisposed = true) where TEventData : Entity - { - if (!_asyncEvents.TryGetValue(eventData.GetType(), out var list)) - { - return; - } - - using var tasks = ListPool.Create(); - - foreach (var @event in list) - { - tasks.Add(@event.InvokeAsync(eventData)); - } - - await FTask.WaitAll(tasks); - - if (isDisposed) - { - eventData.Dispose(); - } - } - - #endregion - - public override void Dispose() - { - _events.Clear(); - _asyncEvents.Clear(); - _assemblyEvents.Clear(); - _assemblyAsyncEvents.Clear(); - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/EventComponent/Interface/IEvent.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/EventComponent/Interface/IEvent.cs deleted file mode 100644 index 5314995..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/EventComponent/Interface/IEvent.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Event -{ - /// - /// 事件的接口 - /// - public interface IEvent - { - /// - /// 用于指定事件的Type - /// - /// - Type EventType(); - /// - /// 时间内部使用的入口 - /// - /// - void Invoke(object self); - } - - /// - /// 异步事件的接口 - /// - public interface IAsyncEvent - { - /// - /// - /// - /// - Type EventType(); - /// - /// - /// - /// - FTask InvokeAsync(object self); - } - - /// - /// 事件的抽象类,要使用事件必须要继承这个抽象接口。 - /// - /// 要监听的事件泛型类型 - public abstract class EventSystem : IEvent - { - private readonly Type _selfType = typeof(T); - /// - /// - /// - /// - public Type EventType() - { - return _selfType; - } - /// - /// 事件调用的方法,要在这个方法里编写事件发生的逻辑 - /// - /// - protected abstract void Handler(T self); - /// - /// - /// - /// - public void Invoke(object self) - { - try - { - Handler((T) self); - } - catch (Exception e) - { - Log.Error($"{_selfType.Name} Error {e}"); - } - } - } - /// - /// 异步事件的抽象类,要使用事件必须要继承这个抽象接口。 - /// - /// 要监听的事件泛型类型 - public abstract class AsyncEventSystem : IAsyncEvent - { - private readonly Type _selfType = typeof(T); - /// - /// - /// - /// - public Type EventType() - { - return _selfType; - } - /// - /// 事件调用的方法,要在这个方法里编写事件发生的逻辑 - /// - /// - protected abstract FTask Handler(T self); - /// - /// - /// - /// - public async FTask InvokeAsync(object self) - { - try - { - await Handler((T) self); - } - catch (Exception e) - { - Log.Error($"{_selfType.Name} Error {e}"); - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/MessagePoolComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/MessagePoolComponent.cs deleted file mode 100644 index f1ddb23..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/MessagePoolComponent.cs +++ /dev/null @@ -1,139 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; -using Fantasy.Pool; -using Fantasy.Serialize; - -namespace Fantasy.Entitas -{ - /// - /// 消息的对象池组件 - /// - public sealed class MessagePoolComponent : Entity - { - private int _poolCount; - private const int MaxCapacity = ushort.MaxValue; - private readonly OneToManyQueue _poolQueue = new OneToManyQueue(); - private readonly Dictionary> _typeCheckCache = new Dictionary>(); - /// - /// 销毁组件 - /// - public override void Dispose() - { - _poolCount = 0; - _poolQueue.Clear(); - _typeCheckCache.Clear(); - base.Dispose(); - } - /// - /// 从对象池里获取一个消息,如果没有就创建一个新的 - /// - /// 消息的泛型类型 - /// - public T Rent() where T : AMessage, new() - { - if (!_poolQueue.TryDequeue(typeof(T), out var queue)) - { - var instance = new T(); - instance.SetScene(Scene); - instance.SetIsPool(true); - return instance; - } - - queue.SetIsPool(true); - _poolCount--; - return (T)queue; - } - - /// - /// - /// - /// 消息的类型 - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public AMessage Rent(Type type) - { - if (!_poolQueue.TryDequeue(type, out var queue)) - { - if (!_typeCheckCache.TryGetValue(type, out var createInstance)) - { - if (!typeof(AMessage).IsAssignableFrom(type)) - { - throw new NotSupportedException($"{this.GetType().FullName} Type:{type.FullName} must inherit from IPool"); - } - else - { - createInstance = CreateInstance.CreateMessage(type); - _typeCheckCache[type] = createInstance; - } - } - - var instance = createInstance(); - instance.SetScene(Scene); - instance.SetIsPool(true); - return instance; - } - - queue.SetIsPool(true); - _poolCount--; - return queue; - } - /// - /// 返还一个消息到对象池中 - /// - /// - public void Return(AMessage obj) - { - if (obj == null) - { - return; - } - - if (!obj.IsPool()) - { - return; - } - - if (_poolCount >= MaxCapacity) - { - return; - } - - _poolCount++; - obj.SetIsPool(false); - _poolQueue.Enqueue(obj.GetType(), obj); - } - - /// - /// - /// - /// 返还的消息 - /// 返还的消息泛型类型 - public void Return(T obj) where T : AMessage - { - if (obj == null) - { - return; - } - - if (!obj.IsPool()) - { - return; - } - - if (_poolCount >= MaxCapacity) - { - return; - } - - _poolCount++; - obj.SetIsPool(false); - _poolQueue.Enqueue(typeof(T), obj); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/SingleCollectionComponent/SingleCollectionComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/SingleCollectionComponent/SingleCollectionComponent.cs deleted file mode 100644 index 5c0969d..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/SingleCollectionComponent/SingleCollectionComponent.cs +++ /dev/null @@ -1,167 +0,0 @@ -// ReSharper disable SuspiciousTypeConversion.Global - -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#if FANTASY_NET -namespace Fantasy.SingleCollection -{ - /// - /// 用于处理Entity下的实体进行数据库分表存储的组件 - /// - public sealed class SingleCollectionComponent : Entity, IAssembly - { - private CoroutineLock _coroutineLock; - private readonly OneToManyHashSet _collection = new OneToManyHashSet(); - - private readonly OneToManyList _assemblyCollections = - new OneToManyList(); - - private sealed class SingleCollectionInfo(Type rootType, string collectionName) - { - public readonly Type RootType = rootType; - public readonly string CollectionName = collectionName; - } - - internal async FTask Initialize() - { - var coroutineLockType = HashCodeHelper.ComputeHash64(GetType().FullName); - _coroutineLock = Scene.CoroutineLockComponent.Create(coroutineLockType); - await AssemblySystem.Register(this); - return this; - } - - #region Assembly - - public async FTask Load(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask ReLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask OnUnLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - private void LoadInner(long assemblyIdentity) - { - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(ISupportedSingleCollection))) - { - var customAttributes = type.GetCustomAttributes(typeof(SingleCollectionAttribute), false); - if (customAttributes.Length == 0) - { - Log.Error( - $"type {type.FullName} Implemented the interface of ISingleCollection, requiring the implementation of SingleCollectionAttribute"); - continue; - } - - var singleCollectionAttribute = (SingleCollectionAttribute)customAttributes[0]; - var rootType = singleCollectionAttribute.RootType; - var collectionName = singleCollectionAttribute.CollectionName; - _collection.Add(rootType, collectionName); - _assemblyCollections.Add(assemblyIdentity, new SingleCollectionInfo(rootType, collectionName)); - } - } - - private void OnUnLoadInner(long assemblyIdentity) - { - if (!_assemblyCollections.TryGetValue(assemblyIdentity, out var types)) - { - return; - } - - foreach (var singleCollectionInfo in types) - { - _collection.RemoveValue(singleCollectionInfo.RootType, singleCollectionInfo.CollectionName); - } - - _assemblyCollections.RemoveByKey(assemblyIdentity); - } - - #endregion - - #region Collections - - /// - /// 通过数据库获取某一个实体类型下所有的分表数据到当前实体下,并且会自动建立父子关系。 - /// - /// 实体实例 - /// 实体泛型类型 - public async FTask GetCollections(T entity) where T : Entity, ISingleCollectionRoot - { - if (!_collection.TryGetValue(typeof(T), out var collections)) - { - return; - } - - var worldDateBase = Scene.World.DataBase; - - using (await _coroutineLock.Wait(entity.Id)) - { - foreach (var collectionName in collections) - { - var singleCollection = await worldDateBase.QueryNotLock(entity.Id, true, collectionName); - entity.AddComponent(singleCollection); - } - } - } - - /// - /// 存储当前实体下支持分表的组件到数据中,包括存储实体本身。 - /// - /// 实体实例 - /// 实体泛型类型 - public async FTask SaveCollections(T entity) where T : Entity, ISingleCollectionRoot - { - using var collections = ListPool.Create(); - - foreach (var treeEntity in entity.ForEachSingleCollection) - { - if (treeEntity is not ISupportedSingleCollection) - { - continue; - } - - collections.Add(treeEntity); - } - - collections.Add(entity); - await entity.Scene.World.DataBase.Save(entity.Id, collections); - } - - #endregion - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/Interface/TimerHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/Interface/TimerHandler.cs deleted file mode 100644 index 9e1f4c9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/Interface/TimerHandler.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Fantasy.Event; - -namespace Fantasy.Timer -{ - /// - /// 计时器抽象类,提供了一个基础框架,用于创建处理计时器事件的具体类。 - /// - /// 事件的类型参数 - public abstract class TimerHandler : EventSystem { } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/ScheduledTask.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/ScheduledTask.cs deleted file mode 100644 index d644386..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/ScheduledTask.cs +++ /dev/null @@ -1,49 +0,0 @@ -// #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// namespace Fantasy -// { -// public sealed class ScheduledTaskPool : PoolCore -// { -// public ScheduledTaskPool() : base(2000) { } -// -// public ScheduledTask Rent(Action action, ref int rounds, ref int finalSlot) -// { -// var scheduledTask = Rent(); -// scheduledTask.Rounds = rounds; -// scheduledTask.Action = action; -// scheduledTask.FinalSlot = finalSlot; -// return scheduledTask; -// } -// -// public override void Return(ScheduledTask item) -// { -// base.Return(item); -// item.Dispose(); -// } -// } -// -// public sealed class ScheduledTask : IPool, IDisposable -// { -// public int Rounds; -// public int FinalSlot; -// public Action Action; -// public LinkedListNode Node; -// -// public bool IsPool { get; set; } -// public ScheduledTask() { } -// public ScheduledTask(Action action, ref int rounds, ref int finalSlot) -// { -// Action = action; -// Rounds = rounds; -// FinalSlot = finalSlot; -// } -// -// public void Dispose() -// { -// Rounds = 0; -// FinalSlot = 0; -// Action = null; -// Node = null; -// } -// } -// } \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/TimeWheel.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/TimeWheel.cs deleted file mode 100644 index 58916b1..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimeWheel/TimeWheel.cs +++ /dev/null @@ -1,134 +0,0 @@ -// using System.Runtime.CompilerServices; -// // ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// -// namespace Fantasy -// { -// public sealed class TimeWheel -// { -// private int _currentIndex; -// private ScheduledTaskPool _scheduledTaskPool; -// -// private readonly Scene _scene; -// private readonly int _wheelSize; -// private readonly int _tickDuration; -// private readonly TimeWheel _upperLevelWheel; -// private readonly LinkedList[] _wheel; -// private readonly Queue _tasksToReschedule = new Queue(); -// private readonly Dictionary _taskDictionary = new Dictionary(); -// -// public TimeWheel(TimerComponent timerComponent, int wheelSize, int tickDuration, TimeWheel upperLevelWheel = null) -// { -// _scene = timerComponent.Scene; -// _wheelSize = wheelSize; -// _tickDuration = tickDuration; -// _upperLevelWheel = upperLevelWheel; -// _scheduledTaskPool = timerComponent.ScheduledTaskPool; -// _wheel = new LinkedList[_wheelSize]; -// for (var i = 0; i < wheelSize; i++) -// { -// _wheel[i] = new LinkedList(); -// } -// } -// -// public long Schedule(Action action, int delay) -// { -// var ticks = delay / _tickDuration; -// var futureIndex = ticks + _currentIndex; -// var rounds = futureIndex / _wheelSize; -// var slot = futureIndex % _wheelSize; -// -// if (slot == 0) -// { -// slot = _wheelSize - 1; -// rounds--; -// } -// else -// { -// slot--; -// } -// -// var taskId = _scene.RuntimeIdFactory.Create; -// var task = _scheduledTaskPool.Rent(action, ref rounds, ref slot); -// task.Node = _wheel[slot].AddLast(task); -// _taskDictionary.Add(taskId, task); -// Console.WriteLine($"Schedule rounds:{rounds} slot:{slot} _currentIndex:{_currentIndex}"); -// return taskId; -// } -// -// public bool Remove(int taskId) -// { -// if (!_taskDictionary.TryGetValue(taskId, out var task)) -// { -// return false; -// } -// -// _taskDictionary.Remove(taskId); -// _wheel[task.FinalSlot].Remove(task.Node); -// _scheduledTaskPool.Return(task); -// Console.WriteLine("找到已经删除了任务"); -// return true; -// } -// -// public void Tick(object? state) -// { -// var currentWheel = _wheel[_currentIndex]; -// -// if (currentWheel.Count == 0) -// { -// AdvanceIndex(); -// return; -// } -// -// var currentNode = currentWheel.First; -// -// while (currentNode != null) -// { -// var nextNode = currentNode.Next; -// var task = currentNode.Value; -// -// if (task.Rounds <= 0 && task.FinalSlot == _currentIndex) -// { -// try -// { -// task.Action.Invoke(); -// } -// catch (Exception ex) -// { -// Log.Error($"Exception during task execution: {ex.Message}"); -// } -// } -// else -// { -// task.Rounds--; -// _tasksToReschedule.Enqueue(task); -// } -// -// currentWheel.Remove(currentNode); -// currentNode = nextNode; -// } -// -// RescheduleTasks(); -// AdvanceIndex(); -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private void AdvanceIndex() -// { -// _currentIndex = (_currentIndex + 1) % _wheelSize; -// if (_currentIndex == 0 && _upperLevelWheel != null) -// { -// _upperLevelWheel.Tick(null); -// } -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private void RescheduleTasks() -// { -// while (_tasksToReschedule.TryDequeue(out var task)) -// { -// _wheel[task.FinalSlot].AddLast(task); -// } -// } -// } -// } \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerAction.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerAction.cs deleted file mode 100644 index 2a836ab..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerAction.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8625 -#pragma warning disable CS8618 - -namespace Fantasy.Timer -{ - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct TimerAction - { - public long TimerId; - public long StartTime; - public long TriggerTime; - public readonly object Callback; - public readonly TimerType TimerType; - public TimerAction(long timerId, TimerType timerType, long startTime, long triggerTime, object callback) - { - TimerId = timerId; - Callback = callback; - TimerType = timerType; - StartTime = startTime; - TriggerTime = triggerTime; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerComponent.cs deleted file mode 100644 index ffa7864..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerComponent.cs +++ /dev/null @@ -1,52 +0,0 @@ -// ReSharper disable ForCanBeConvertedToForeach - -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#if FANTASY_UNITY -using UnityEngine; -#endif -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Timer -{ - public sealed class TimerComponentUpdateSystem : UpdateSystem - { - protected override void Update(TimerComponent self) - { - self.Update(); - } - } - - /// - /// 时间调度组件 - /// - public sealed class TimerComponent : Entity - { - /// - /// 使用系统时间创建的计时器核心。 - /// - public TimerSchedulerNet Net { get; private set; } -#if FANTASY_UNITY - /// - /// 使用 Unity 时间创建的计时器核心。 - /// - public TimerSchedulerNetUnity Unity { get; private set; } -#endif - internal TimerComponent Initialize() - { - Net = new TimerSchedulerNet(Scene); -#if FANTASY_UNITY - Unity = new TimerSchedulerNetUnity(Scene); -#endif - return this; - } - public void Update() - { - Net.Update(); -#if FANTASY_UNITY - Unity.Update(); -#endif - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNet.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNet.cs deleted file mode 100644 index 26581f8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNet.cs +++ /dev/null @@ -1,390 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Helper; -// ReSharper disable UnusedParameter.Global - -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Timer -{ - /// - /// 基于系统事件的任务调度系统 - /// - public sealed class TimerSchedulerNet - { - private readonly Scene _scene; - private long _idGenerator; - private long _minTime; // 最小时间 - private readonly Queue _timeOutTime = new Queue(); - private readonly Queue _timeOutTimerIds = new Queue(); - private readonly Dictionary _timerActions = new Dictionary(); - private readonly SortedOneToManyList _timeId = new(); // 时间与计时器ID的有序一对多列表 - private long GetId => ++_idGenerator; - /// - /// 构造函数 - /// - /// 当前的Scene - public TimerSchedulerNet(Scene scene) - { - _scene = scene; - } - - private long Now() - { - return TimeHelper.Now; - } - - /// - /// 驱动方法,只有调用这个方法任务系统才会正常运转。 - /// - public void Update() - { - if (_timeId.Count == 0) - { - return; - } - - var currentTime = Now(); - - if (currentTime < _minTime) - { - return; - } - - // 遍历时间ID列表,查找超时的计时器任务 - foreach (var (key, _) in _timeId) - { - if (key > currentTime) - { - _minTime = key; - break; - } - - _timeOutTime.Enqueue(key); - } - - // 处理超时的计时器任务 - while (_timeOutTime.TryDequeue(out var time)) - { - var timerIds = _timeId[time]; - for (var i = 0; i < timerIds.Count; ++i) - { - _timeOutTimerIds.Enqueue(timerIds[i]); - } - - _timeId.Remove(time); - // _timeId.RemoveKey(time); - } - - if (_timeId.Count == 0) - { - _minTime = long.MaxValue; - } - - // 执行超时的计时器任务的回调操作 - while (_timeOutTimerIds.TryDequeue(out var timerId)) - { - if (!_timerActions.Remove(timerId, out var timerAction)) - { - continue; - } - - // 根据计时器类型执行不同的操作 - switch (timerAction.TimerType) - { - case TimerType.OnceWaitTimer: - { - var tcs = (FTask)timerAction.Callback; - tcs.SetResult(true); - break; - } - case TimerType.OnceTimer: - { - if (timerAction.Callback is not Action action) - { - Log.Error($"timerAction {timerAction.ToJson()}"); - break; - } - - action(); - break; - } - case TimerType.RepeatedTimer: - { - if (timerAction.Callback is not Action action) - { - Log.Error($"timerAction {timerAction.ToJson()}"); - break; - } - - timerAction.StartTime = Now(); - AddTimer(ref timerAction); - action(); - break; - } - } - } - } - - private void AddTimer(ref TimerAction timer) - { - var tillTime = timer.StartTime + timer.TriggerTime; - _timeId.Add(tillTime, timer.TimerId); - _timerActions.Add(timer.TimerId, timer); - - if (tillTime < _minTime) - { - _minTime = tillTime; - } - } - - /// - /// 异步等待指定时间。 - /// - /// 等待的时间长度。 - /// 取消令牌。 - /// 等待是否成功。 - public async FTask WaitAsync(long time, FCancellationToken cancellationToken = null) - { - if (time <= 0) - { - return true; - } - - var now = Now(); - var timerId = GetId; - var tcs = FTask.Create(); - var timerAction = new TimerAction(timerId, TimerType.OnceWaitTimer, now, time, tcs); - - void CancelActionVoid() - { - if (Remove(timerId)) - { - tcs.SetResult(false); - } - } - - bool result; - - try - { - cancellationToken?.Add(CancelActionVoid); - AddTimer(ref timerAction); - result = await tcs; - } - finally - { - cancellationToken?.Remove(CancelActionVoid); - } - - return result; - } - - /// - /// 异步等待直到指定时间。 - /// - /// 等待的目标时间。 - /// 取消令牌。 - /// 等待是否成功。 - public async FTask WaitTillAsync(long tillTime, FCancellationToken cancellationToken = null) - { - var now = Now(); - - if (now >= tillTime) - { - return true; - } - - var timerId = GetId; - var tcs = FTask.Create(); - var timerAction = new TimerAction(timerId, TimerType.OnceWaitTimer, now, tillTime - now, tcs); - - void CancelActionVoid() - { - if (Remove(timerId)) - { - tcs.SetResult(false); - } - } - - bool result; - - try - { - cancellationToken?.Add(CancelActionVoid); - AddTimer(ref timerAction); - result = await tcs; - } - finally - { - cancellationToken?.Remove(CancelActionVoid); - } - - return result; - } - - /// - /// 异步等待一帧时间。 - /// - /// 等待是否成功。 - public async FTask WaitFrameAsync() - { -#if FANTASY_NET - await WaitAsync(100); -#else - await WaitAsync(1); -#endif - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间 - /// - /// 计时器执行的目标时间。 - /// 计时器回调方法。 - /// - public long OnceTimer(long time, Action action) - { - var now = Now(); - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.OnceTimer, now, time, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。 - /// - /// 计时器执行的目标时间。 - /// 计时器回调方法。 - /// 计时器的 ID。 - public long OnceTillTimer(long tillTime, Action action) - { - var now = Now(); - - if (tillTime < now) - { - Log.Error($"new once time too small tillTime:{tillTime} Now:{now}"); - } - - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.OnceTimer, now, tillTime - now, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 创建一个只执行一次的计时器,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器执行的延迟时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long OnceTimer(long time, T timerHandlerType) where T : struct - { - void OnceTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return OnceTimer(time, OnceTimerVoid); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器执行的目标时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long OnceTillTimer(long tillTime, T timerHandlerType) where T : struct - { - void OnceTillTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return OnceTillTimer(tillTime, OnceTillTimerVoid); - } - - /// - /// 创建一个帧任务 - /// - /// - /// - public long FrameTimer(Action action) - { -#if FANTASY_NET - return RepeatedTimerInner(100, action); -#else - return RepeatedTimerInner(0, action); -#endif - } - - /// - /// 创建一个重复执行的计时器。 - /// - /// 计时器重复间隔的时间。 - /// 计时器回调方法。 - /// 计时器的 ID。 - public long RepeatedTimer(long time, Action action) - { - if (time < 0) - { - Log.Error($"time too small: {time}"); - return 0; - } - - return RepeatedTimerInner(time, action); - } - - /// - /// 创建一个重复执行的计时器,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器重复间隔的时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long RepeatedTimer(long time, T timerHandlerType) where T : struct - { - void RepeatedTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return RepeatedTimer(time, RepeatedTimerVoid); - } - - private long RepeatedTimerInner(long time, Action action) - { - var now = Now(); - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.RepeatedTimer, now, time, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// - /// - public bool Remove(ref long timerId) - { - var id = timerId; - timerId = 0; - return Remove(id); - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// 计时器的 ID。 - public bool Remove(long timerId) - { - return timerId != 0 && _timerActions.Remove(timerId, out _); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNetUnity.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNetUnity.cs deleted file mode 100644 index f00bfe4..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerScheduler/TimerSchedulerNetUnity.cs +++ /dev/null @@ -1,372 +0,0 @@ -#if FANTASY_UNITY -using System; -using System.Collections.Generic; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Helper; -using UnityEngine; -namespace Fantasy.Timer -{ - public sealed class TimerSchedulerNetUnity - { - private readonly Scene _scene; - private long _idGenerator; - private long _minTime; // 最小时间 - private readonly Queue _timeOutTime = new Queue(); - private readonly Queue _timeOutTimerIds = new Queue(); - private readonly Dictionary _timerActions = new Dictionary(); - private readonly SortedOneToManyList _timeId = new(); // 时间与计时器ID的有序一对多列表 - private long GetId => ++_idGenerator; - public TimerSchedulerNetUnity(Scene scene) - { - _scene = scene; - } - - private long Now() - { - return (long)(Time.time * 1000); - } - - public void Update() - { - if (_timeId.Count == 0) - { - return; - } - - var currentTime = Now(); - - if (currentTime < _minTime) - { - return; - } - - // 遍历时间ID列表,查找超时的计时器任务 - foreach (var (key, _) in _timeId) - { - if (key > currentTime) - { - _minTime = key; - break; - } - - _timeOutTime.Enqueue(key); - } - - // 处理超时的计时器任务 - while (_timeOutTime.TryDequeue(out var time)) - { - var timerIds = _timeId[time]; - for (var i = 0; i < timerIds.Count; ++i) - { - _timeOutTimerIds.Enqueue(timerIds[i]); - } - - _timeId.Remove(time); - // _timeId.RemoveKey(time); - } - - if (_timeId.Count == 0) - { - _minTime = long.MaxValue; - } - - // 执行超时的计时器任务的回调操作 - while (_timeOutTimerIds.TryDequeue(out var timerId)) - { - if (!_timerActions.Remove(timerId, out var timerAction)) - { - continue; - } - - // 根据计时器类型执行不同的操作 - switch (timerAction.TimerType) - { - case TimerType.OnceWaitTimer: - { - var tcs = (FTask)timerAction.Callback; - tcs.SetResult(true); - break; - } - case TimerType.OnceTimer: - { - if (timerAction.Callback is not Action action) - { - Log.Error($"timerAction {timerAction.ToJson()}"); - break; - } - - action(); - break; - } - case TimerType.RepeatedTimer: - { - if (timerAction.Callback is not Action action) - { - Log.Error($"timerAction {timerAction.ToJson()}"); - break; - } - - timerAction.StartTime = Now(); - AddTimer(ref timerAction); - action(); - break; - } - } - } - } - - private void AddTimer(ref TimerAction timer) - { - var tillTime = timer.StartTime + timer.TriggerTime; - _timeId.Add(tillTime, timer.TimerId); - _timerActions.Add(timer.TimerId, timer); - - if (tillTime < _minTime) - { - _minTime = tillTime; - } - } - - /// - /// 异步等待指定时间。 - /// - /// 等待的时间长度。 - /// 可选的取消令牌。 - /// 等待是否成功。 - public async FTask WaitAsync(long time, FCancellationToken cancellationToken = null) - { - if (time <= 0) - { - return true; - } - - var now = Now(); - var timerId = GetId; - var tcs = FTask.Create(); - var timerAction = new TimerAction(timerId, TimerType.OnceWaitTimer, now, time, tcs); - - - void CancelActionVoid() - { - if (Remove(timerId)) - { - tcs.SetResult(false); - } - } - - bool result; - - try - { - cancellationToken?.Add(CancelActionVoid); - AddTimer(ref timerAction); - result =await tcs; - } - finally - { - cancellationToken?.Remove(CancelActionVoid); - } - - return result; - } - - /// - /// 异步等待直到指定时间。 - /// - /// 等待的目标时间。 - /// 可选的取消令牌。 - /// 等待是否成功。 - public async FTask WaitTillAsync(long tillTime, FCancellationToken cancellationToken = null) - { - var now = Now(); - - if (now >= tillTime) - { - return true; - } - - var timerId = GetId; - var tcs = FTask.Create(); - var timerAction = new TimerAction(timerId, TimerType.OnceWaitTimer, now, tillTime - now, tcs); - - void CancelActionVoid() - { - if (Remove(timerId)) - { - tcs.SetResult(false); - } - } - - bool result; - - try - { - cancellationToken?.Add(CancelActionVoid); - AddTimer(ref timerAction); - result = await tcs; - } - finally - { - cancellationToken?.Remove(CancelActionVoid); - } - - return result; - } - - /// - /// 异步等待一帧时间。 - /// - /// 等待是否成功。 - public async FTask WaitFrameAsync(FCancellationToken cancellationToken = null) - { - await WaitAsync(1, cancellationToken); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间 - /// - /// 计时器执行的目标时间。 - /// 计时器回调方法。 - /// - public long OnceTimer(long time, Action action) - { - var now = Now(); - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.OnceTimer, now, time, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。 - /// - /// 计时器执行的目标时间。 - /// 计时器回调方法。 - /// 计时器的 ID。 - public long OnceTillTimer(long tillTime, Action action) - { - var now = Now(); - - if (tillTime < now) - { - Log.Error($"new once time too small tillTime:{tillTime} Now:{now}"); - } - - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.OnceTimer, now, tillTime - now, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 创建一个只执行一次的计时器,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器执行的延迟时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long OnceTimer(long time, T timerHandlerType) where T : struct - { - void OnceTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return OnceTimer(time, OnceTimerVoid); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器执行的目标时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long OnceTillTimer(long tillTime, T timerHandlerType) where T : struct - { - void OnceTillTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return OnceTillTimer(tillTime, OnceTillTimerVoid); - } - - /// - /// 创建一个帧任务 - /// - /// - /// - public long FrameTimer(Action action) - { - return RepeatedTimerInner(1, action); - } - - /// - /// 创建一个重复执行的计时器。 - /// - /// 计时器重复间隔的时间。 - /// 计时器回调方法。 - /// 计时器的 ID。 - public long RepeatedTimer(long time, Action action) - { - if (time < 0) - { - Log.Error($"time too small: {time}"); - return 0; - } - - return RepeatedTimerInner(time, action); - } - - /// - /// 创建一个重复执行的计时器,用于发布指定类型的事件。 - /// - /// 事件类型。 - /// 计时器重复间隔的时间。 - /// 事件处理器类型。 - /// 计时器的 ID。 - public long RepeatedTimer(long time, T timerHandlerType) where T : struct - { - void RepeatedTimerVoid() - { - _scene.EventComponent.Publish(timerHandlerType); - } - - return RepeatedTimer(time, RepeatedTimerVoid); - } - - private long RepeatedTimerInner(long time, Action action) - { - var now = Now(); - var timerId = GetId; - var timerAction = new TimerAction(timerId, TimerType.RepeatedTimer, now, time, action); - AddTimer(ref timerAction); - return timerId; - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// - /// - public bool Remove(ref long timerId) - { - var id = timerId; - timerId = 0; - return Remove(id); - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// 计时器的 ID。 - public bool Remove(long timerId) - { - return timerId != 0 && _timerActions.Remove(timerId, out _); - } - } -} -#endif - diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerType.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerType.cs deleted file mode 100644 index 6f16f80..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Component/TimerComponent/TimerType.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Fantasy.Timer -{ - /// - /// 枚举对象TimerType - /// - public enum TimerType - { - /// - /// None - /// - None, - /// - /// 一次等待定时器 - /// - OnceWaitTimer, - /// - /// 一次性定时器 - /// - OnceTimer, - /// - /// 重复定时器 - /// - RepeatedTimer - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Entity.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Entity.cs deleted file mode 100644 index 0458cca..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Entity.cs +++ /dev/null @@ -1,1051 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using Fantasy.Entitas.Interface; -using Fantasy.Pool; -using MongoDB.Bson.Serialization.Attributes; -using Newtonsoft.Json; -using ProtoBuf; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable MergeIntoPattern -// ReSharper disable SuspiciousTypeConversion.Global -// ReSharper disable NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract -// ReSharper disable CheckNamespace -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Entitas -{ - /// - /// 用来表示一个Entity - /// - public interface IEntity : IDisposable, IPool { } - - /// - /// Entity的抽象类,任何Entity必须继承这个接口才可以使用 - /// - public abstract partial class Entity : IEntity - { - #region Members - - /// - /// 获取一个值,表示实体是否支持对象池。 - /// - [BsonIgnore] - [JsonIgnore] - [ProtoIgnore] - [IgnoreDataMember] - private bool _isPool; - /// - /// 实体的Id - /// - [BsonId] - [BsonElement] - [BsonIgnoreIfDefault] - [BsonDefaultValue(0L)] - public long Id { get; protected set; } - /// - /// 实体的RunTimeId,其他系统可以通过这个Id发送Route消息,这个Id也可以理解为RouteId - /// - [BsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public long RuntimeId { get; protected set; } - /// - /// 当前实体是否已经被销毁 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public bool IsDisposed => RuntimeId == 0; - /// - /// 当前实体所归属的Scene - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public Scene Scene { get; protected set; } - /// - /// 实体的父实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public Entity Parent { get; protected set; } - /// - /// 实体的真实Type - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public Type Type { get; protected set; } -#if FANTASY_NET - [BsonElement("t")] [BsonIgnoreIfNull] private EntityList _treeDb; - [BsonElement("m")] [BsonIgnoreIfNull] private EntityList _multiDb; -#endif - [BsonIgnore] [IgnoreDataMember] [ProtoIgnore] private EntitySortedDictionary _tree; - [BsonIgnore] [IgnoreDataMember] [ProtoIgnore] private EntitySortedDictionary _multi; - - /// - /// 获得父Entity - /// - /// 父实体的泛型类型 - /// - public T GetParent() where T : Entity, new() - { - return Parent as T; - } - - /// - /// 获取当前实体的RouteId。 - /// - public long RouteId => RuntimeId; - - #endregion - - #region Create - - /// - /// 创建一个实体 - /// - /// 所属的Scene - /// 实体的Type - /// 是否从对象池创建,如果选择的是,销毁的时候同样会进入对象池 - /// 是否执行实体事件 - /// - public static Entity Create(Scene scene, Type type, bool isPool, bool isRunEvent) - { - return Create(scene, type, scene.EntityIdFactory.Create, isPool, isRunEvent); - } - - /// - /// 创建一个实体 - /// - /// 所属的Scene - /// 实体的Type - /// 指定实体的Id - /// 是否从对象池创建,如果选择的是,销毁的时候同样会进入对象池 - /// 是否执行实体事件 - /// - public static Entity Create(Scene scene, Type type, long id, bool isPool, bool isRunEvent) - { - if (!typeof(Entity).IsAssignableFrom(type)) - { - throw new NotSupportedException($"{type.FullName} Type:{type.FullName} must inherit from Entity"); - } - - Entity entity = null; - - if (isPool) - { - entity = (Entity)scene.EntityPool.Rent(type); - } - else - { - if (!scene.TypeInstance.TryGetValue(type, out var createInstance)) - { - createInstance = CreateInstance.CreateIPool(type); - scene.TypeInstance[type] = createInstance; - } - - entity = (Entity)createInstance(); - } - - entity.Scene = scene; - entity.Type = type; - entity.SetIsPool(isPool); - entity.Id = id; - entity.RuntimeId = scene.RuntimeIdFactory.Create; - scene.AddEntity(entity); - - if (isRunEvent) - { - scene.EntityComponent.Awake(entity); - scene.EntityComponent.StartUpdate(entity); - } - - return entity; - } - - /// - /// 创建一个实体 - /// - /// 所属的Scene - /// 是否从对象池创建,如果选择的是,销毁的时候同样会进入对象池 - /// 是否执行实体事件 - /// 要创建的实体泛型类型 - /// - public static T Create(Scene scene, bool isPool, bool isRunEvent) where T : Entity, new() - { - return Create(scene, scene.EntityIdFactory.Create, isPool, isRunEvent); - } - - /// - /// 创建一个实体 - /// - /// 所属的Scene - /// 指定实体的Id - /// 是否从对象池创建,如果选择的是,销毁的时候同样会进入对象池 - /// 是否执行实体事件 - /// 要创建的实体泛型类型 - /// - public static T Create(Scene scene, long id, bool isPool, bool isRunEvent) where T : Entity, new() - { - var entity = isPool ? scene.EntityPool.Rent() : new T(); - entity.Scene = scene; - entity.Type = typeof(T); - entity.SetIsPool(isPool); - entity.Id = id; - entity.RuntimeId = scene.RuntimeIdFactory.Create; - scene.AddEntity(entity); - - if (isRunEvent) - { - scene.EntityComponent.Awake(entity); - scene.EntityComponent.StartUpdate(entity); - } - - return entity; - } - - #endregion - - #region AddComponent - - /// - /// 添加一个组件到当前实体上 - /// - /// 是否从对象池里创建 - /// 要添加组件的泛型类型 - /// 返回添加到实体上组件的实例 - public T AddComponent(bool isPool = true) where T : Entity, new() - { - var id = SupportedMultiEntityChecker.IsSupported ? Scene.EntityIdFactory.Create : Id; - var entity = Create(Scene, id, isPool, false); - AddComponent(entity); - Scene.EntityComponent.Awake(entity); - Scene.EntityComponent.StartUpdate(entity); - return entity; - } - - /// - /// 添加一个组件到当前实体上 - /// - /// 要添加组件的Id - /// 是否从对象池里创建 - /// 要添加组件的泛型类型 - /// 返回添加到实体上组件的实例 - public T AddComponent(long id, bool isPool = true) where T : Entity, new() - { - var entity = Create(Scene, id, isPool, false); - AddComponent(entity); - Scene.EntityComponent.Awake(entity); - Scene.EntityComponent.StartUpdate(entity); - return entity; - } - - /// - /// 添加一个组件到当前实体上 - /// - /// 要添加的实体实例 - public void AddComponent(Entity component) - { - if (this == component) - { - Log.Error("Cannot add oneself to one's own components"); - return; - } - - if (component.IsDisposed) - { - Log.Error($"component is Disposed {component.Type.FullName}"); - return; - } - - var type = component.Type; - component.Parent?.RemoveComponent(component, false); - - if (component is ISupportedMultiEntity) - { - _multi ??= Scene.EntitySortedDictionaryPool.Rent(); - _multi.Add(component.Id, component); -#if FANTASY_NET - if (component is ISupportedDataBase) - { - _multiDb ??= Scene.EntityListPool.Rent(); - _multiDb.Add(component); - } -#endif - } - else - { -#if FANTASY_NET - if (component is ISupportedSingleCollection && component.Id != Id) - { - Log.Error($"component type :{type.FullName} for implementing ISupportedSingleCollection, it is required that the Id must be the same as the parent"); - } -#endif - var typeHashCode = Scene.EntityComponent.GetHashCode(type);; - - if (_tree == null) - { - _tree = Scene.EntitySortedDictionaryPool.Rent(); - } - else if (_tree.ContainsKey(typeHashCode)) - { - Log.Error($"type:{type.FullName} If you want to add multiple components of the same type, please implement IMultiEntity"); - return; - } - - _tree.Add(typeHashCode, component); -#if FANTASY_NET - if (component is ISupportedDataBase) - { - _treeDb ??= Scene.EntityListPool.Rent(); - _treeDb.Add(component); - } -#endif - } - - component.Parent = this; - component.Scene = Scene; - } - - /// - /// 添加一个组件到当前实体上 - /// - /// 要添加的实体实例 - /// 要添加组件的泛型类型 - public void AddComponent(T component) where T : Entity - { - var type = typeof(T); - - if (type == typeof(Entity)) - { - Log.Error("Cannot add a generic Entity type as a component. Specify a more specific type."); - return; - } - - if (this == component) - { - Log.Error("Cannot add oneself to one's own components"); - return; - } - - if (component.IsDisposed) - { - Log.Error($"component is Disposed {type.FullName}"); - return; - } - - component.Parent?.RemoveComponent(component, false); - - if (SupportedMultiEntityChecker.IsSupported) - { - _multi ??= Scene.EntitySortedDictionaryPool.Rent(); - _multi.Add(component.Id, component); -#if FANTASY_NET - if (SupportedDataBaseChecker.IsSupported) - { - _multiDb ??= Scene.EntityListPool.Rent(); - _multiDb.Add(component); - } -#endif - } - else - { -#if FANTASY_NET - if (SupportedSingleCollectionChecker.IsSupported && component.Id != Id) - { - Log.Error($"component type :{type.FullName} for implementing ISupportedSingleCollection, it is required that the Id must be the same as the parent"); - } -#endif - var typeHashCode = Scene.EntityComponent.GetHashCode(type); - - if (_tree == null) - { - _tree = Scene.EntitySortedDictionaryPool.Rent(); - } - else if (_tree.ContainsKey(typeHashCode)) - { - Log.Error($"type:{type.FullName} If you want to add multiple components of the same type, please implement IMultiEntity"); - return; - } - - _tree.Add(typeHashCode, component); -#if FANTASY_NET - if (SupportedDataBaseChecker.IsSupported) - { - _treeDb ??= Scene.EntityListPool.Rent(); - _treeDb.Add(component); - } -#endif - } - - component.Parent = this; - component.Scene = Scene; - } - - /// - /// 添加一个组件到当前实体上 - /// - /// 组件的类型 - /// 是否在对象池创建 - /// - public Entity AddComponent(Type type, bool isPool = true) - { - var id = typeof(ISupportedMultiEntity).IsAssignableFrom(type) ? Scene.EntityIdFactory.Create : Id; - var entity = Entity.Create(Scene, type, id, isPool, false); - AddComponent(entity); - Scene.EntityComponent.Awake(entity); - Scene.EntityComponent.StartUpdate(entity); - return entity; - } - - #endregion - - #region HasComponent - - /// - /// 当前实体上是否有指定类型的组件 - /// - /// - /// - public bool HasComponent() where T : Entity, new() - { - return HasComponent(typeof(T)); - } - - /// - /// 当前实体上是否有指定类型的组件 - /// - /// - /// - public bool HasComponent(Type type) - { - if (_tree == null) - { - return false; - } - - return _tree.ContainsKey(Scene.EntityComponent.GetHashCode(type)); - } - - /// - /// 当前实体上是否有指定类型的组件 - /// - /// - /// - /// - public bool HasComponent(long id) where T : Entity, ISupportedMultiEntity, new() - { - if (_multi == null) - { - return false; - } - - return _multi.ContainsKey(id); - } - - #endregion - - #region GetComponent - - /// - /// 当前实体上查找一个字实体 - /// - /// 要查找实体泛型类型 - /// 查找的实体实例 - public T GetComponent() where T : Entity, new() - { - if (_tree == null) - { - return null; - } - - var typeHashCode = Scene.EntityComponent.GetHashCode(typeof(T)); - return _tree.TryGetValue(typeHashCode, out var component) ? (T)component : null; - } - - /// - /// 当前实体上查找一个字实体 - /// - /// 要查找实体类型 - /// 查找的实体实例 - public Entity GetComponent(Type type) - { - if (_tree == null) - { - return null; - } - - var typeHashCode = Scene.EntityComponent.GetHashCode(type); - return _tree.TryGetValue(typeHashCode, out var component) ? component : null; - } - - /// - /// 当前实体上查找一个字实体 - /// - /// 要查找实体的Id - /// 要查找实体泛型类型 - /// 查找的实体实例 - public T GetComponent(long id) where T : Entity, ISupportedMultiEntity, new() - { - if (_multi == null) - { - return default; - } - - return _multi.TryGetValue(id, out var entity) ? (T)entity : default; - } - - /// - /// 当前实体上查找一个字实体,如果没有就创建一个新的并添加到当前实体上 - /// - /// 是否从对象池创建 - /// 要查找或添加实体泛型类型 - /// 查找的实体实例 - public T GetOrAddComponent(bool isPool = true) where T : Entity, new() - { - return GetComponent() ?? AddComponent(isPool); - } - - #endregion - - #region RemoveComponent - - /// - /// 当前实体下删除一个实体 - /// - /// 是否执行删除实体的Dispose方法 - /// 实体的泛型类型 - /// - public void RemoveComponent(bool isDispose = true) where T : Entity, new() - { - if (SupportedMultiEntityChecker.IsSupported) - { - throw new NotSupportedException($"{typeof(T).FullName} message:Cannot delete components that implement the ISupportedMultiEntity interface"); - } - - if (_tree == null) - { - return; - } - - var type = typeof(T); - var typeHashCode = Scene.EntityComponent.GetHashCode(type); - if (!_tree.TryGetValue(typeHashCode, out var component)) - { - return; - } -#if FANTASY_NET - if (_treeDb != null && SupportedDataBaseChecker.IsSupported) - { - _treeDb.Remove(component); - - if (_treeDb.Count == 0) - { - Scene.EntityListPool.Return(_treeDb); - _treeDb = null; - } - } -#endif - _tree.Remove(typeHashCode); - - if (_tree.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_tree); - _tree = null; - } - - if (isDispose) - { - component.Dispose(); - } - } - - /// - /// 当前实体下删除一个实体 - /// - /// 要删除的实体Id - /// 是否执行删除实体的Dispose方法 - /// 实体的泛型类型 - public void RemoveComponent(long id, bool isDispose = true) where T : Entity, ISupportedMultiEntity, new() - { - if (_multi == null) - { - return; - } - - if (!_multi.TryGetValue(id, out var component)) - { - return; - } -#if FANTASY_NET - if (SupportedDataBaseChecker.IsSupported) - { - _multiDb.Remove(component); - if (_multiDb.Count == 0) - { - Scene.EntityListPool.Return(_multiDb); - _multiDb = null; - } - } -#endif - _multi.Remove(component.Id); - if (_multi.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_multi); - _multi = null; - } - - if (isDispose) - { - component.Dispose(); - } - } - - /// - /// 当前实体下删除一个实体 - /// - /// 要删除的实体实例 - /// 是否执行删除实体的Dispose方法 - public void RemoveComponent(Entity component, bool isDispose = true) - { - if (this == component) - { - return; - } - - if (component is ISupportedMultiEntity) - { - if (_multi != null) - { - if (!_multi.ContainsKey(component.Id)) - { - return; - } -#if FANTASY_NET - if (component is ISupportedDataBase) - { - _multiDb.Remove(component); - if (_multiDb.Count == 0) - { - Scene.EntityListPool.Return(_multiDb); - _multiDb = null; - } - } -#endif - _multi.Remove(component.Id); - if (_multi.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_multi); - _multi = null; - } - } - } - else if (_tree != null) - { - var typeHashCode = Scene.EntityComponent.GetHashCode(component.Type); - if (!_tree.ContainsKey(typeHashCode)) - { - return; - } -#if FANTASY_NET - if (_treeDb != null && component is ISupportedDataBase) - { - _treeDb.Remove(component); - - if (_treeDb.Count == 0) - { - Scene.EntityListPool.Return(_treeDb); - _treeDb = null; - } - } -#endif - _tree.Remove(typeHashCode); - - if (_tree.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_tree); - _tree = null; - } - } - - if (isDispose) - { - component.Dispose(); - } - } - - /// - /// 当前实体下删除一个实体 - /// - /// 要删除的实体实例 - /// 是否执行删除实体的Dispose方法 - /// 实体的泛型类型 - public void RemoveComponent(T component, bool isDispose = true) where T : Entity - { - if (this == component) - { - return; - } - - if (typeof(T) == typeof(Entity)) - { - Log.Error("Cannot remove a generic Entity type as a component. Specify a more specific type."); - return; - } - - if (SupportedMultiEntityChecker.IsSupported) - { - if (_multi != null) - { - if (!_multi.ContainsKey(component.Id)) - { - return; - } -#if FANTASY_NET - if (SupportedDataBaseChecker.IsSupported) - { - _multiDb.Remove(component); - if (_multiDb.Count == 0) - { - Scene.EntityListPool.Return(_multiDb); - _multiDb = null; - } - } -#endif - _multi.Remove(component.Id); - if (_multi.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_multi); - _multi = null; - } - } - } - else if (_tree != null) - { - var typeHashCode = Scene.EntityComponent.GetHashCode(typeof(T)); - if (!_tree.ContainsKey(typeHashCode)) - { - return; - } -#if FANTASY_NET - if (_treeDb != null && SupportedDataBaseChecker.IsSupported) - { - _treeDb.Remove(component); - - if (_treeDb.Count == 0) - { - Scene.EntityListPool.Return(_treeDb); - _treeDb = null; - } - } -#endif - _tree.Remove(typeHashCode); - - if (_tree.Count == 0) - { - Scene.EntitySortedDictionaryPool.Return(_tree); - _tree = null; - } - } - - if (isDispose) - { - component.Dispose(); - } - } - - #endregion - - #region Deserialize - - /// - /// 反序列化当前实体,因为在数据库加载过来的或通过协议传送过来的实体并没有跟当前Scene做关联。 - /// 所以必须要执行一下这个反序列化的方法才可以使用。 - /// - /// Scene - /// 是否是重新生成实体的Id,如果是数据库加载过来的一般是不需要的 - public void Deserialize(Scene scene, bool resetId = false) - { - if (RuntimeId != 0) - { - return; - } - - try - { - Scene = scene; - Type ??= GetType(); - RuntimeId = Scene.RuntimeIdFactory.Create; - if (resetId) - { - Id = RuntimeId; - } -#if FANTASY_NET - if (_treeDb != null && _treeDb.Count > 0) - { - _tree = Scene.EntitySortedDictionaryPool.Rent(); - foreach (var entity in _treeDb) - { - entity.Parent = this; - entity.Type = entity.GetType(); - var typeHashCode = Scene.EntityComponent.GetHashCode(entity.Type); - _tree.Add(typeHashCode, entity); - entity.Deserialize(scene, resetId); - } - } - - if (_multiDb != null && _multiDb.Count > 0) - { - _multi = Scene.EntitySortedDictionaryPool.Rent(); - foreach (var entity in _multiDb) - { - entity.Parent = this; - entity.Deserialize(scene, resetId); - _multi.Add(entity.Id, entity); - } - } -#endif - scene.AddEntity(this); - scene.EntityComponent.Deserialize(this); - } - catch (Exception e) - { - if (RuntimeId != 0) - { - scene.RemoveEntity(RuntimeId); - } - - Log.Error(e); - } - } - - #endregion - - #region ForEach -#if FANTASY_NET - /// - /// 查询当前实体下支持数据库分表存储实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public IEnumerable ForEachSingleCollection - { - get - { - foreach (var (_, treeEntity) in _tree) - { - if (treeEntity is not ISupportedSingleCollection) - { - continue; - } - - yield return treeEntity; - } - } - } - /// - /// 查询当前实体下支持传送实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public IEnumerable ForEachTransfer - { - get - { - if (_tree != null) - { - foreach (var (_, treeEntity) in _tree) - { - if (treeEntity is ISupportedTransfer) - { - yield return treeEntity; - } - } - } - - if (_multiDb != null) - { - foreach (var treeEntity in _multiDb) - { - if (treeEntity is not ISupportedTransfer) - { - continue; - } - - yield return treeEntity; - } - } - } - } -#endif - /// - /// 查询当前实体下的实现了ISupportedMultiEntity接口的实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public IEnumerable ForEachMultiEntity - { - get - { - if (_multi == null) - { - yield break; - } - - foreach (var (_, supportedMultiEntity) in _multi) - { - yield return supportedMultiEntity; - } - } - } - /// - /// 查找当前实体下的所有实体,不包括实现ISupportedMultiEntity接口的实体 - /// - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - public IEnumerable ForEachEntity - { - get - { - if (_tree == null) - { - yield break; - } - - foreach (var (_, entity) in _tree) - { - yield return entity; - } - } - } - #endregion - - #region Dispose - - /// - /// 销毁当前实体,销毁后会自动销毁当前实体下的所有实体。 - /// - public virtual void Dispose() - { - if (IsDisposed) - { - return; - } - - var scene = Scene; - var runTimeId = RuntimeId; - RuntimeId = 0; - - if (_tree != null) - { - foreach (var (_, entity) in _tree) - { - entity.Dispose(); - } - - _tree.Clear(); - scene.EntitySortedDictionaryPool.Return(_tree); - _tree = null; - } - - if (_multi != null) - { - foreach (var (_, entity) in _multi) - { - entity.Dispose(); - } - - _multi.Clear(); - scene.EntitySortedDictionaryPool.Return(_multi); - _multi = null; - } -#if FANTASY_NET - if (_treeDb != null) - { - foreach (var entity in _treeDb) - { - entity.Dispose(); - } - - _treeDb.Clear(); - scene.EntityListPool.Return(_treeDb); - _treeDb = null; - } - - if (_multiDb != null) - { - foreach (var entity in _multiDb) - { - entity.Dispose(); - } - - _multiDb.Clear(); - scene.EntityListPool.Return(_multiDb); - _multiDb = null; - } -#endif - scene.EntityComponent.Destroy(this); - - if (Parent != null && Parent != this && !Parent.IsDisposed) - { - Parent.RemoveComponent(this, false); - Parent = null; - } - - Id = 0; - Scene = null; - Parent = null; - scene.RemoveEntity(runTimeId); - - if (IsPool()) - { - scene.EntityPool.Return(Type, this); - } - - Type = null; - } - - #endregion - - #region Pool - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - - #endregion - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/EntityPool.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/EntityPool.cs deleted file mode 100644 index 9a6441c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/EntityPool.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Collections.Generic; -using Fantasy.Pool; - -#pragma warning disable CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. - -namespace Fantasy.Entitas -{ - internal sealed class EntityPool : PoolCore - { - public EntityPool() : base(4096) { } - } - - internal sealed class EntityList : List, IPool where T : Entity - { - private bool _isPool; - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - internal sealed class EntityListPool : PoolCore> where T : Entity - { - public EntityListPool() : base(4096) { } - } - - internal sealed class EntitySortedDictionary : SortedDictionary, IPool where TN : Entity - { - private bool _isPool; - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } - - internal sealed class EntitySortedDictionaryPool : PoolCore> where TN : Entity - { - public EntitySortedDictionaryPool() : base(4096) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/EntityReference.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/EntityReference.cs deleted file mode 100644 index dd1a3fd..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/EntityReference.cs +++ /dev/null @@ -1,59 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -namespace Fantasy.Entitas -{ - /// - /// 实体引用检查组件 - /// - /// - public struct EntityReference where T : Entity - { - private T _entity; - private readonly long _runTimeId; - - private EntityReference(T t) - { - if (t == null) - { - _entity = null; - _runTimeId = 0; - return; - } - - _entity = t; - _runTimeId = t.RuntimeId; - } - - /// - /// 将一个实体转换为EntityReference - /// - /// 实体泛型类型 - /// 返回一个EntityReference - public static implicit operator EntityReference(T t) - { - return new EntityReference(t); - } - - /// - /// 将一个EntityReference转换为实体 - /// - /// 实体泛型类型 - /// 当实体已经被销毁过会返回null - public static implicit operator T(EntityReference v) - { - if (v._entity == null) - { - return null; - } - - if (v._entity.RuntimeId != v._runTimeId) - { - v._entity = null; - } - - return v._entity; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISingleCollectionRoot.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISingleCollectionRoot.cs deleted file mode 100644 index 84de7a4..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISingleCollectionRoot.cs +++ /dev/null @@ -1,17 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Entitas.Interface -{ - /// - /// Entity保存到数据库的时候会根据子组件设置分离存储特性分表存储在不同的集合表中 - /// - public interface ISingleCollectionRoot { } - public static class SingleCollectionRootChecker where T : Entity - { - public static bool IsSupported { get; } - - static SingleCollectionRootChecker() - { - IsSupported = typeof(ISingleCollectionRoot).IsAssignableFrom(typeof(T)); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedDataBase.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedDataBase.cs deleted file mode 100644 index f505241..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedDataBase.cs +++ /dev/null @@ -1,19 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Entitas.Interface -{ - /// - /// Entity支持数据库 - /// - // ReSharper disable once InconsistentNaming - public interface ISupportedDataBase { } - - public static class SupportedDataBaseChecker where T : Entity - { - public static bool IsSupported { get; } - - static SupportedDataBaseChecker() - { - IsSupported = typeof(ISupportedDataBase).IsAssignableFrom(typeof(T)); - } - } -} diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedMultiEntity.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedMultiEntity.cs deleted file mode 100644 index ee6aeb7..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedMultiEntity.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Entitas.Interface -{ - /// - /// 支持再一个组件里添加多个同类型组件 - /// - public interface ISupportedMultiEntity : IDisposable { } - - public static class SupportedMultiEntityChecker where T : Entity - { - public static bool IsSupported { get; } - - static SupportedMultiEntityChecker() - { - IsSupported = typeof(ISupportedMultiEntity).IsAssignableFrom(typeof(T)); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedSingleCollection.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedSingleCollection.cs deleted file mode 100644 index 302e697..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedSingleCollection.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Entitas.Interface -{ - // Entity是单一集合、保存到数据库的时候不会跟随父组件保存在一个集合里、会单独保存在一个集合里 - // 需要配合SingleCollectionAttribute一起使用、如在Entity类头部定义SingleCollectionAttribute(typeOf(Unit)) - // SingleCollectionAttribute用来定义这个Entity是属于哪个Entity的子集 - /// - /// 定义实体支持单一集合存储的接口。当实体需要单独存储在一个集合中,并且在保存到数据库时不会与父组件一起保存在同一个集合中时,应实现此接口。 - /// - public interface ISupportedSingleCollection { } - public static class SupportedSingleCollectionChecker where T : Entity - { - public static bool IsSupported { get; } - - static SupportedSingleCollectionChecker() - { - IsSupported = typeof(ISupportedSingleCollection).IsAssignableFrom(typeof(T)); - } - } - /// - /// 表示用于指定实体的单一集合存储属性。此属性用于配合 接口使用, - /// 用于定义实体属于哪个父实体的子集合,以及在数据库中使用的集合名称。 - /// - [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] - public class SingleCollectionAttribute : Attribute - { - /// - /// 获取父实体的类型,指示此实体是属于哪个父实体的子集合。 - /// - public readonly Type RootType; - /// - /// 获取在数据库中使用的集合名称。 - /// - public readonly string CollectionName; - /// - /// 初始化 类的新实例,指定父实体类型和集合名称。 - /// - /// 父实体的类型。 - /// 在数据库中使用的集合名称。 - public SingleCollectionAttribute(Type rootType, string collectionName) - { - RootType = rootType; - CollectionName = collectionName; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedTransfer.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedTransfer.cs deleted file mode 100644 index a3ae4a9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/Supported/ISupportedTransfer.cs +++ /dev/null @@ -1,19 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#if FANTASY_NET -namespace Fantasy.Entitas.Interface -{ - /// - /// Entity支持传送 - /// - public interface ISupportedTransfer { } - public static class SupportedTransferChecker where T : Entity - { - public static bool IsSupported { get; } - - static SupportedTransferChecker() - { - IsSupported = typeof(ISupportedTransfer).IsAssignableFrom(typeof(T)); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IAwakeSystem.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IAwakeSystem.cs deleted file mode 100644 index f651701..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IAwakeSystem.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Entitas.Interface -{ - internal interface IAwakeSystem : IEntitiesSystem { } - /// - /// 实体的Awake事件的抽象接口 - /// - /// 实体的泛型类型 - public abstract class AwakeSystem : IAwakeSystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Awake(T self); - /// - /// 框架内部调用的触发Awake的方法。 - /// - /// 触发事件的实体实例 - public void Invoke(Entity self) - { - Awake((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/ICustomEntitiesSystem.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/ICustomEntitiesSystem.cs deleted file mode 100644 index da42e58..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/ICustomEntitiesSystem.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; - -namespace Fantasy.Entitas.Interface -{ - /// - /// 自定义组件事件系统接口 - /// 如果需要自定义组件事件系统,请继承此接口。 - /// 这个接口内部使用。不对外开放。 - /// - internal interface ICustomEntitiesSystem - { - /// - /// 事件类型 - /// 用于触发这个组件事件关键因素。 - /// - int CustomEventType { get; } - /// - /// 实体的类型 - /// - /// - Type EntitiesType(); - /// - /// 框架内部调用的触发事件方法 - /// - /// - void Invoke(Entity entity); - } - - /// - /// 自定义组件事件系统抽象类 - /// 如果需要自定义组件事件系统,请继承此抽象类。 - /// - /// - public abstract class CustomSystem : ICustomEntitiesSystem where T : Entity - { - /// - /// 这个1表示是一个自定义事件类型,执行这个事件是时候需要用到这个1. - /// - public abstract int CustomEventType { get; } - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Custom(T self); - /// - /// 实体的类型 - /// - /// - public abstract Type EntitiesType(); - /// - /// 框架内部调用的触发Awake的方法。 - /// - /// 触发事件的实体实例 - public void Invoke(Entity self) - { - Custom((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IDeserializeSystem.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IDeserializeSystem.cs deleted file mode 100644 index 9c38ab6..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IDeserializeSystem.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Entitas.Interface -{ - internal interface IDeserializeSystem : IEntitiesSystem { } - /// - /// 实体的反序列化事件的抽象接口 - /// - /// 实体的泛型数据 - public abstract class DeserializeSystem : IDeserializeSystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Deserialize(T self); - /// - /// 框架内部调用的触发Deserialize的方法 - /// - /// 触发事件的实体实例 - public void Invoke(Entity self) - { - Deserialize((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IDestroySystem.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IDestroySystem.cs deleted file mode 100644 index 531ebbe..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IDestroySystem.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Entitas.Interface -{ - internal interface IDestroySystem : IEntitiesSystem { } - /// - /// 实体销毁事件的抽象接口 - /// - /// - public abstract class DestroySystem : IDestroySystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Destroy(T self); - /// - /// 框架内部调用的触发Destroy的方法 - /// - /// - public void Invoke(Entity self) - { - Destroy((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IEntitiesSystem.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IEntitiesSystem.cs deleted file mode 100644 index 555d21a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IEntitiesSystem.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Fantasy.Async; - -namespace Fantasy.Entitas.Interface -{ - /// - /// ECS事件系统的核心接口,任何事件都是要继承这个接口 - /// - public interface IEntitiesSystem - { - /// - /// 实体的类型 - /// - /// - Type EntitiesType(); - /// - /// 框架内部调用的触发事件方法 - /// - /// - void Invoke(Entity entity); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IFrameUpdateSystem.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IFrameUpdateSystem.cs deleted file mode 100644 index c50061b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IFrameUpdateSystem.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; - -namespace Fantasy.Entitas.Interface -{ - internal interface IFrameUpdateSystem : IEntitiesSystem { } - /// - /// 帧更新时间的抽象接口 - /// - /// - public abstract class FrameUpdateSystem : IFrameUpdateSystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void FrameUpdate(T self); - /// - /// 框架内部调用的触发FrameUpdate的方法 - /// - /// - public void Invoke(Entity self) - { - FrameUpdate((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IUpdateSystem.cs b/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IUpdateSystem.cs deleted file mode 100644 index 4b34ac8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Entitas/Interface/System/IUpdateSystem.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; - -namespace Fantasy.Entitas.Interface -{ - internal interface IUpdateSystem : IEntitiesSystem { } - /// - /// Update事件的抽象接口 - /// - /// - public abstract class UpdateSystem : IUpdateSystem where T : Entity - { - /// - /// 实体的类型 - /// - /// - public Type EntitiesType() => typeof(T); - /// - /// 事件的抽象方法,需要自己实现这个方法 - /// - /// 触发事件的实体实例 - protected abstract void Update(T self); - /// - /// 框架内部调用的触发Update的方法 - /// - /// 触发事件的实体实例 - public void Invoke(Entity self) - { - Update((T) self); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/FTask/Builder/AsyncFTaskCompletedMethodBuilder.cs b/Fantasy/Fantays.Console/Runtime/Core/FTask/Builder/AsyncFTaskCompletedMethodBuilder.cs deleted file mode 100644 index 60b0d08..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/FTask/Builder/AsyncFTaskCompletedMethodBuilder.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - public struct AsyncFTaskCompletedMethodBuilder - { - public FTaskCompleted Task => default; - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncFTaskCompletedMethodBuilder Create() - { - return new AsyncFTaskCompletedMethodBuilder(); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - ExceptionDispatchInfo.Capture(exception).Throw(); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult() { } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.OnCompleted(stateMachine.MoveNext); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.UnsafeOnCompleted(stateMachine.MoveNext); - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetStateMachine(IAsyncStateMachine stateMachine) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/FTask/Builder/AsyncFTaskMethodBuilder.cs b/Fantasy/Fantays.Console/Runtime/Core/FTask/Builder/AsyncFTaskMethodBuilder.cs deleted file mode 100644 index 6c072cd..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/FTask/Builder/AsyncFTaskMethodBuilder.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -// ReSharper disable MemberCanBePrivate.Global -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8604 // Possible null reference argument. - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - public readonly struct AsyncFTaskMethodBuilder - { - public FTask Task - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncFTaskMethodBuilder Create() - { - return new AsyncFTaskMethodBuilder(FTask.Create()); - } - - public AsyncFTaskMethodBuilder(FTask fTask) - { - Task = fTask; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult() - { - Task.SetResult(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - Task.SetException(exception); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine - { - // 通常在异步方法中遇到 await 关键字时调用,并且需要将执行恢复到调用 await 之前的同步上下文。 - awaiter.OnCompleted(stateMachine.MoveNext); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine - { - // 通常在你不需要恢复到原始同步上下文时调用,这意味着你不关心在什么线程上恢复执行。 - awaiter.UnsafeOnCompleted(stateMachine.MoveNext); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetStateMachine(IAsyncStateMachine stateMachine) - { - // 用于设置和保存异步方法的状态机实例。 - // 编译器在生成异步方法时要求其存在。 - // 编译器生成的代码已经足够处理状态机的管理,所以这里没有什么特殊要求所以保持空实现。 - } - } - - [StructLayout(LayoutKind.Auto)] - public readonly struct AsyncFTaskMethodBuilder - { - public FTask Task - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncFTaskMethodBuilder Create() - { - return new AsyncFTaskMethodBuilder(FTask.Create()); - } - - public AsyncFTaskMethodBuilder(FTask fTask) - { - Task = fTask; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult(T value) - { - Task.SetResult(value); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - Task.SetException(exception); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.OnCompleted(stateMachine.MoveNext); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.UnsafeOnCompleted(stateMachine.MoveNext); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetStateMachine(IAsyncStateMachine stateMachine) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/FTask/Builder/AsyncFVoidMethodBuilder.cs b/Fantasy/Fantays.Console/Runtime/Core/FTask/Builder/AsyncFVoidMethodBuilder.cs deleted file mode 100644 index b9f7bc0..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/FTask/Builder/AsyncFVoidMethodBuilder.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - internal struct AsyncFVoidMethodBuilder - { - public FVoid Task - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => default; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncFVoidMethodBuilder Create() - { - return default; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult() { } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - ExceptionDispatchInfo.Capture(exception).Throw(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.OnCompleted(stateMachine.MoveNext); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine - { - awaiter.UnsafeOnCompleted(stateMachine.MoveNext); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetStateMachine(IAsyncStateMachine stateMachine) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/FTask/FCancellationToken/FCancellationToken.cs b/Fantasy/Fantays.Console/Runtime/Core/FTask/FCancellationToken/FCancellationToken.cs deleted file mode 100644 index 90913e3..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/FTask/FCancellationToken/FCancellationToken.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; - -namespace Fantasy.Async -{ - /// - /// 用于FTask取消的CancellationToken - /// - public sealed class FCancellationToken : IDisposable - { - private bool _isDispose; - private bool _isCancel; - private readonly HashSet _actions = new HashSet(); - /// - /// 当前CancellationToken是否已经取消过了 - /// - public bool IsCancel => _isDispose || _isCancel; - /// - /// 添加一个取消要执行的Action - /// - /// - public void Add(Action action) - { - if (_isDispose) - { - return; - } - - _actions.Add(action); - } - /// - /// 移除一个取消要执行的Action - /// - /// - public void Remove(Action action) - { - if (_isDispose) - { - return; - } - - _actions.Remove(action); - } - /// - /// 取消CancellationToken - /// - public void Cancel() - { - if (IsCancel) - { - return; - } - - _isCancel = true; - - foreach (var action in _actions) - { - try - { - action.Invoke(); - } - catch (Exception e) - { - Console.WriteLine(e); - } - } - - _actions.Clear(); - } - /// - /// 销毁掉CancellationToken,会执行Cancel方法。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - if (!IsCancel) - { - Cancel(); - _isCancel = true; - } - - _isDispose = true; - - if (Caches.Count > 2000) - { - return; - } - - Caches.Enqueue(this); - } - - #region Static - - private static readonly ConcurrentQueue Caches = new ConcurrentQueue(); - - /// - /// 获取一个新的CancellationToken - /// - public static FCancellationToken ToKen - { - get - { - if (!Caches.TryDequeue(out var fCancellationToken)) - { - fCancellationToken = new FCancellationToken(); - } - - fCancellationToken._isCancel = false; - fCancellationToken._isDispose = false; - return fCancellationToken; - } - } - - #endregion - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/FTask/FTask.Extension/FTask.Factory.cs b/Fantasy/Fantays.Console/Runtime/Core/FTask/FTask.Extension/FTask.Factory.cs deleted file mode 100644 index 80c7fc8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/FTask/FTask.Extension/FTask.Factory.cs +++ /dev/null @@ -1,115 +0,0 @@ -#if !FANTASY_WEBGL -using System.Collections.Concurrent; -#endif -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.CompilerServices; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Async -{ - /// - /// 一个异步任务 - /// - public partial class FTask - { - private bool _isPool; -#if FANTASY_WEBGL - private static readonly Queue Caches = new Queue(); -#else - private static readonly ConcurrentQueue Caches = new ConcurrentQueue(); -#endif - /// - /// 创建一个空的任务 - /// - public static FTaskCompleted CompletedTask => new FTaskCompleted(); - - private FTask() { } - - /// - /// 创建一个任务 - /// - /// 是否从对象池中创建 - /// - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static FTask Create(bool isPool = true) - { - if (!isPool) - { - return new FTask(); - } - - if (!Caches.TryDequeue(out var fTask)) - { - fTask = new FTask(); - } - - fTask._isPool = true; - return fTask; - } - - private void Return() - { - if (!_isPool || Caches.Count > 2000) - { - return; - } - - _callBack = null; - _status = STaskStatus.Pending; - Caches.Enqueue(this); - } - } - - /// - /// 一个异步任务 - /// - /// 任务的泛型类型 - public partial class FTask - { - private bool _isPool; -#if FANTASY_WEBGL - private static readonly Queue> Caches = new Queue>(); -#else - private static readonly ConcurrentQueue> Caches = new ConcurrentQueue>(); -#endif - /// - /// 创建一个任务 - /// - /// 是否从对象池中创建 - /// - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static FTask Create(bool isPool = true) - { - if (!isPool) - { - return new FTask(); - } - - if (!Caches.TryDequeue(out var fTask)) - { - fTask = new FTask(); - } - - fTask._isPool = true; - return fTask; - } - - private FTask() { } - - private void Return() - { - if (!_isPool || Caches.Count > 2000) - { - return; - } - - _callBack = null; - _status = STaskStatus.Pending; - Caches.Enqueue(this); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/FTask/FTask.Extension/FTask.Tools.cs b/Fantasy/Fantays.Console/Runtime/Core/FTask/FTask.Extension/FTask.Tools.cs deleted file mode 100644 index a42edec..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/FTask/FTask.Extension/FTask.Tools.cs +++ /dev/null @@ -1,345 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -using System; -using System.Collections.Generic; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Async -{ - public partial class FTask - { - #region NetTimer - - /// - /// 异步等待指定时间 - /// - /// - /// - /// - /// - public static FTask Wait(Scene scene, long time, FCancellationToken cancellationToken = null) - { - return scene.TimerComponent.Net.WaitAsync(time, cancellationToken); - } - - /// - /// 异步等待直到指定时间 - /// - /// - /// - /// - /// - public static FTask WaitTill(Scene scene, long time, FCancellationToken cancellationToken = null) - { - return scene.TimerComponent.Net.WaitTillAsync(time, cancellationToken); - } - - /// - /// 异步等待一帧时间 - /// - /// - /// - public static FTask WaitFrame(Scene scene) - { - return scene.TimerComponent.Net.WaitFrameAsync(); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间 - /// - /// - /// - /// - /// - public static long OnceTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Net.OnceTimer(time, action); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。 - /// - /// - /// - /// - /// - public static long OnceTillTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Net.OnceTillTimer(time, action); - } - - /// - /// 创建一个只执行一次的计时器,用于发布指定类型的事件。 - /// - /// - /// - /// - /// - /// - public static long OnceTimer(Scene scene, long time, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Net.OnceTimer(time, timerHandlerType); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间,用于发布指定类型的事件。 - /// - /// - /// - /// - /// - /// - public static long OnceTillTimer(Scene scene, long tillTime, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Net.OnceTillTimer(tillTime, timerHandlerType); - } - - /// - /// 创建一个重复执行的计时器。 - /// - /// - /// - /// - /// - public static long RepeatedTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Net.RepeatedTimer(time, action); - } - - /// - /// 创建一个重复执行的计时器,用于发布指定类型的事件。 - /// - /// - /// - /// - /// - /// - public static long RepeatedTimer(Scene scene, long time, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Net.RepeatedTimer(time, timerHandlerType); - } - - /// - /// 移除指定 ID 的计时器。 - /// - /// - /// - /// - public static bool RemoveTimer(Scene scene, ref long timerId) - { - return scene.TimerComponent.Net.Remove(ref timerId); - } - - #endregion - - #region Unity - -#if FANTASY_UNITY - /// - /// 异步等待指定时间。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static FTask UnityWait(Scene scene, long time, FCancellationToken cancellationToken = null) - { - return scene.TimerComponent.Unity.WaitAsync(time, cancellationToken); - } - - /// - /// 异步等待直到指定时间。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static FTask UnityWaitTill(Scene scene, long time, FCancellationToken cancellationToken = null) - { - return scene.TimerComponent.Unity.WaitTillAsync(time, cancellationToken); - } - - /// - /// 异步等待一帧时间。(使用Unity的Time时间) - /// - /// - /// - public static FTask UnityWaitFrame(Scene scene) - { - return scene.TimerComponent.Unity.WaitFrameAsync(); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static long UnityOnceTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Unity.OnceTimer(time, action); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static long UnityOnceTillTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Unity.OnceTillTimer(time, action); - } - - /// - /// 创建一个只执行一次的计时器,用于发布指定类型的事件。(使用Unity的Time时间) - /// - /// - /// - /// - /// - /// - public static long UnityOnceTimer(Scene scene, long time, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Unity.OnceTimer(time, timerHandlerType); - } - - /// - /// 创建一个只执行一次的计时器,直到指定时间,用于发布指定类型的事件。(使用Unity的Time时间) - /// - /// - /// - /// - /// - /// - public static long UnityOnceTillTimer(Scene scene, long tillTime, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Unity.OnceTillTimer(tillTime, timerHandlerType); - } - - /// - /// 创建一个重复执行的计时器。(使用Unity的Time时间) - /// - /// - /// - /// - /// - public static long UnityRepeatedTimer(Scene scene, long time, Action action) - { - return scene.TimerComponent.Unity.RepeatedTimer(time, action); - } - - /// - /// 创建一个重复执行的计时器,用于发布指定类型的事件。(使用Unity的Time时间) - /// - /// - /// - /// - /// - /// - public static long UnityRepeatedTimer(Scene scene, long time, T timerHandlerType) where T : struct - { - return scene.TimerComponent.Unity.RepeatedTimer(time, timerHandlerType); - } - - /// - /// 移除指定 ID 的计时器。(使用Unity的Time时间) - /// - /// - /// - /// - public static bool UnityRemoveTimer(Scene scene, ref long timerId) - { - return scene.TimerComponent.Unity.Remove(ref timerId); - } -#endif - - #endregion - - /// - /// 创建并运行一个异步任务 - /// - /// - /// - public static FTask Run(Func factory) - { - return factory(); - } - - /// - /// 创建并运行一个带有结果的异步任务 - /// - /// - /// - /// - public static FTask Run(Func> factory) - { - return factory(); - } - - /// - /// 等待所有任务完成 - /// - /// - public static async FTask WaitAll(List tasks) - { - if (tasks.Count <= 0) - { - return; - } - - var count = tasks.Count; - var sTaskCompletionSource = Create(); - - foreach (var task in tasks) - { - RunSTask(task).Coroutine(); - } - - await sTaskCompletionSource; - - async FVoid RunSTask(FTask task) - { - await task; - count--; - if (count <= 0) - { - sTaskCompletionSource.SetResult(); - } - } - } - /// - /// 等待其中一个任务完成 - /// - /// - public static async FTask WaitAny(List tasks) - { - if (tasks.Count <= 0) - { - return; - } - - var count = 1; - var sTaskCompletionSource = Create(); - - foreach (var task in tasks) - { - RunSTask(task).Coroutine(); - } - - await sTaskCompletionSource; - - async FVoid RunSTask(FTask task) - { - await task; - count--; - if (count == 0) - { - sTaskCompletionSource.SetResult(); - } - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/FTask/Task/FTask.cs b/Fantasy/Fantays.Console/Runtime/Core/FTask/Task/FTask.cs deleted file mode 100644 index ce925f2..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/FTask/Task/FTask.cs +++ /dev/null @@ -1,263 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable ConditionalAccessQualifierIsNonNullableAccordingToAPIContract -// ReSharper disable CheckNamespace -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Async -{ - public enum STaskStatus : byte - { - Pending = 0, // The operation has not yet completed. - Succeeded = 1, // The operation completed successfully. - Faulted = 2 // The operation completed with an error. - } - - [AsyncMethodBuilder(typeof(AsyncFTaskMethodBuilder))] - public sealed partial class FTask : ICriticalNotifyCompletion - { - private Action _callBack; - private ExceptionDispatchInfo _exception; - private STaskStatus _status = STaskStatus.Pending; - public bool IsCompleted - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _status != STaskStatus.Pending; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public FTask GetAwaiter() => this; - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private async FVoid InnerCoroutine() - { - await this; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Coroutine() - { - InnerCoroutine().Coroutine(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void GetResult() - { - switch (_status) - { - case STaskStatus.Succeeded: - { - Return(); - return; - } - case STaskStatus.Faulted: - { - Return(); - - if (_exception == null) - { - return; - } - - var exception = _exception; - _exception = null; - exception.Throw(); - return; - } - default: - { - throw new NotSupportedException("Direct call to getResult is not allowed"); - } - } - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult() - { - if (_status != STaskStatus.Pending) - { - throw new InvalidOperationException("The task has been completed"); - } - - _status = STaskStatus.Succeeded; - - if (_callBack == null) - { - return; - } - - var callBack = _callBack; - _callBack = null; - callBack.Invoke(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void OnCompleted(Action action) - { - UnsafeOnCompleted(action); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UnsafeOnCompleted(Action action) - { - if (_status != STaskStatus.Pending) - { - action?.Invoke(); - return; - } - - _callBack = action; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - if (_status != STaskStatus.Pending) - { - throw new InvalidOperationException("The task has been completed"); - } - - _status = STaskStatus.Faulted; - _exception = ExceptionDispatchInfo.Capture(exception); - _callBack?.Invoke(); - } - } - - [AsyncMethodBuilder(typeof(AsyncFTaskMethodBuilder<>))] - public sealed partial class FTask : ICriticalNotifyCompletion - { - private T _value; - private Action _callBack; - private ExceptionDispatchInfo _exception; - private STaskStatus _status = STaskStatus.Pending; - public bool IsCompleted - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _status != STaskStatus.Pending; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public FTask GetAwaiter() => this; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerHidden] - private async FVoid InnerCoroutine() - { - await this; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Coroutine() - { - InnerCoroutine().Coroutine(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T GetResult() - { - switch (_status) - { - case STaskStatus.Succeeded: - { - var value = _value; - Return(); - return value; - } - case STaskStatus.Faulted: - { - Return(); - - if (_exception == null) - { - return default; - } - - var exception = _exception; - _exception = null; - exception.Throw(); - return default; - } - default: - { - throw new NotSupportedException("Direct call to getResult is not allowed"); - } - } - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetResult(T value) - { - if (_status != STaskStatus.Pending) - { - throw new InvalidOperationException("The task has been completed"); - } - - _value = value; - _status = STaskStatus.Succeeded; - - if (_callBack == null) - { - return; - } - - var callBack = _callBack; - _callBack = null; - callBack.Invoke(); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void OnCompleted(Action action) - { - UnsafeOnCompleted(action); - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UnsafeOnCompleted(Action action) - { - if (_status != STaskStatus.Pending) - { - action?.Invoke(); - return; - } - - _callBack = action; - } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetException(Exception exception) - { - if (_status != STaskStatus.Pending) - { - throw new InvalidOperationException("The task has been completed"); - } - - _status = STaskStatus.Faulted; - _exception = ExceptionDispatchInfo.Capture(exception); - _callBack?.Invoke(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/FTask/Task/FTaskCompleted.cs b/Fantasy/Fantays.Console/Runtime/Core/FTask/Task/FTaskCompleted.cs deleted file mode 100644 index 48b9e36..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/FTask/Task/FTaskCompleted.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - [AsyncMethodBuilder(typeof(AsyncFTaskCompletedMethodBuilder))] - public struct FTaskCompleted : ICriticalNotifyCompletion - { - [DebuggerHidden] - public bool IsCompleted => true; - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public FTaskCompleted GetAwaiter() - { - return this; - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void GetResult() { } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void OnCompleted(Action continuation) { } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UnsafeOnCompleted(Action continuation) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/FTask/Task/FVoid.cs b/Fantasy/Fantays.Console/Runtime/Core/FTask/Task/FVoid.cs deleted file mode 100644 index f10ca7c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/FTask/Task/FVoid.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Fantasy.Async -{ - [StructLayout(LayoutKind.Auto)] - [AsyncMethodBuilder(typeof(AsyncFVoidMethodBuilder))] - internal struct FVoid : ICriticalNotifyCompletion - { - public bool IsCompleted - { - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => true; - } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Coroutine() { } - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void OnCompleted(Action continuation) { } - - [DebuggerHidden] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UnsafeOnCompleted(Action continuation) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/ByteHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/ByteHelper.cs deleted file mode 100644 index 9d3d6e0..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/ByteHelper.cs +++ /dev/null @@ -1,388 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; -using Fantasy.Async; - -namespace Fantasy.Helper -{ - /// - /// 提供字节操作辅助方法的静态类。 - /// - public static class ByteHelper - { - private static readonly string[] Suffix = { "Byte", "KB", "MB", "GB", "TB" }; - - /// - /// 从指定的文件流中读取一个 64 位整数。 - /// - public static long ReadInt64(FileStream stream) - { - var buffer = new byte[8]; -#if FANTASY_NET - stream.ReadExactly(buffer, 0, 8); -#else - stream.Read(buffer, 0, 8); -#endif - return BitConverter.ToInt64(buffer, 0); - } - - /// - /// 从指定的文件流中读取一个 32 位整数。 - /// - public static int ReadInt32(FileStream stream) - { - var buffer = new byte[4]; -#if FANTASY_NET - stream.ReadExactly(buffer, 0, 4); -#else - stream.Read(buffer, 0, 4); -#endif - return BitConverter.ToInt32(buffer, 0); - } - - /// - /// 从指定的内存流中读取一个 64 位整数。 - /// - public static long ReadInt64(MemoryStream stream) - { - var buffer = new byte[8]; -#if FANTASY_NET - stream.ReadExactly(buffer, 0, 8); -#else - stream.Read(buffer, 0, 8); -#endif - return BitConverter.ToInt64(buffer, 0); - } - - /// - /// 从指定的内存流中读取一个 32 位整数。 - /// - public static int ReadInt32(MemoryStream stream) - { - var buffer = new byte[4]; -#if FANTASY_NET - stream.ReadExactly(buffer, 0, 4); -#else - stream.Read(buffer, 0, 4); -#endif - return BitConverter.ToInt32(buffer, 0); - } - - /// - /// 将字节转换为十六进制字符串表示。 - /// - public static string ToHex(this byte b) - { - return b.ToString("X2"); - } - - /// - /// 将字节数组转换为十六进制字符串表示。 - /// - public static string ToHex(this byte[] bytes) - { - var stringBuilder = new StringBuilder(); - foreach (var b in bytes) - { - stringBuilder.Append(b.ToString("X2")); - } - - return stringBuilder.ToString(); - } - - /// - /// 将字节数组按指定格式转换为十六进制字符串表示。 - /// - public static string ToHex(this byte[] bytes, string format) - { - var stringBuilder = new StringBuilder(); - foreach (var b in bytes) - { - stringBuilder.Append(b.ToString(format)); - } - - return stringBuilder.ToString(); - } - - /// - /// 将字节数组的指定范围按十六进制格式转换为字符串表示。 - /// - public static string ToHex(this byte[] bytes, int offset, int count) - { - var stringBuilder = new StringBuilder(); - for (var i = offset; i < offset + count; ++i) - { - stringBuilder.Append(bytes[i].ToString("X2")); - } - - return stringBuilder.ToString(); - } - - /// - /// 将字节数组转换为默认编码的字符串表示。 - /// - public static string ToStr(this byte[] bytes) - { - return Encoding.Default.GetString(bytes); - } - - /// - /// 将字节数组的指定范围按默认编码转换为字符串表示。 - /// - public static string ToStr(this byte[] bytes, int index, int count) - { - return Encoding.Default.GetString(bytes, index, count); - } - - /// - /// 将字节数组转换为 UTF-8 编码的字符串表示。 - /// - public static string Utf8ToStr(this byte[] bytes) - { - return Encoding.UTF8.GetString(bytes); - } - - /// - /// 将字节数组的指定范围按 UTF-8 编码转换为字符串表示。 - /// - public static string Utf8ToStr(this byte[] bytes, int index, int count) - { - return Encoding.UTF8.GetString(bytes, index, count); - } - - /// - /// 将无符号整数写入字节数组的指定偏移位置。 - /// - public static void WriteTo(this byte[] bytes, int offset, uint num) - { - bytes[offset] = (byte)(num & 0xff); - bytes[offset + 1] = (byte)((num & 0xff00) >> 8); - bytes[offset + 2] = (byte)((num & 0xff0000) >> 16); - bytes[offset + 3] = (byte)((num & 0xff000000) >> 24); - } - - /// - /// 将有符号整数写入字节数组的指定偏移位置。 - /// - public static void WriteTo(this byte[] bytes, int offset, int num) - { - bytes[offset] = (byte)(num & 0xff); - bytes[offset + 1] = (byte)((num & 0xff00) >> 8); - bytes[offset + 2] = (byte)((num & 0xff0000) >> 16); - bytes[offset + 3] = (byte)((num & 0xff000000) >> 24); - } - - /// - /// 将字节写入字节数组的指定偏移位置。 - /// - public static void WriteTo(this byte[] bytes, int offset, byte num) - { - bytes[offset] = num; - } - - /// - /// 将有符号短整数写入字节数组的指定偏移位置。 - /// - public static void WriteTo(this byte[] bytes, int offset, short num) - { - bytes[offset] = (byte)(num & 0xff); - bytes[offset + 1] = (byte)((num & 0xff00) >> 8); - } - - /// - /// 将无符号短整数写入字节数组的指定偏移位置。 - /// - public static void WriteTo(this byte[] bytes, int offset, ushort num) - { - bytes[offset] = (byte)(num & 0xff); - bytes[offset + 1] = (byte)((num & 0xff00) >> 8); - } - - /// - /// 将字节数转换为可读的速度表示。 - /// - /// 字节数 - /// 可读的速度表示 - public static string ToReadableSpeed(this long byteCount) - { - var i = 0; - double dblSByte = byteCount; - if (byteCount <= 1024) - { - return $"{dblSByte:0.##}{Suffix[i]}"; - } - - for (i = 0; byteCount / 1024 > 0; i++, byteCount /= 1024) - { - dblSByte = byteCount / 1024.0; - } - - return $"{dblSByte:0.##}{Suffix[i]}"; - } - - /// - /// 将字节数转换为可读的速度表示。 - /// - /// 字节数 - /// 可读的速度表示 - public static string ToReadableSpeed(this ulong byteCount) - { - var i = 0; - double dblSByte = byteCount; - - if (byteCount <= 1024) - { - return $"{dblSByte:0.##}{Suffix[i]}"; - } - - for (i = 0; byteCount / 1024 > 0; i++, byteCount /= 1024) - { - dblSByte = byteCount / 1024.0; - } - - return $"{dblSByte:0.##}{Suffix[i]}"; - } - - /// - /// 合并两个字节数组。 - /// - /// 第一个字节数组 - /// 第二个字节数组 - /// 合并后的字节数组 - public static byte[] MergeBytes(byte[] bytes, byte[] otherBytes) - { - var result = new byte[bytes.Length + otherBytes.Length]; - bytes.CopyTo(result, 0); - otherBytes.CopyTo(result, bytes.Length); - return result; - } - - /// - /// 根据int值获取字节数组。 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(this int value, byte[] buffer) - { - if (buffer.Length < 4) - { - throw new ArgumentException("Buffer too small."); - } - -#if FANTASY_NET || FANTASY_CONSOLE - MemoryMarshal.Write(buffer.AsSpan(), in value); -#endif -#if FANTASY_UNITY - MemoryMarshal.Write(buffer.AsSpan(), ref value); -#endif - } - - /// - /// 根据int值获取字节数组。 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteBytes(this MemoryStream memoryStream, int value) - { - using var memoryOwner = MemoryPool.Shared.Rent(4); - var memorySpan = memoryOwner.Memory.Span; -#if FANTASY_NET - MemoryMarshal.Write(memorySpan, in value); -#endif -#if FANTASY_UNITY - MemoryMarshal.Write(memorySpan, ref value); -#endif - memoryStream.Write(memorySpan); - } - - /// - /// 根据uint值获取字节数组。 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(ref this uint value, byte[] buffer) - { - if (buffer.Length < 4) - { - throw new ArgumentException("Buffer too small."); - } - -#if FANTASY_NET - MemoryMarshal.Write(buffer.AsSpan(), in value); -#endif -#if FANTASY_UNITY - MemoryMarshal.Write(buffer.AsSpan(), ref value); -#endif - } - - /// - /// 根据uint值获取字节数组。 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteBytes(this MemoryStream memoryStream, uint value) - { - using var memoryOwner = MemoryPool.Shared.Rent(4); - var memorySpan = memoryOwner.Memory.Span; -#if FANTASY_NET - MemoryMarshal.Write(memorySpan, in value); -#endif -#if FANTASY_UNITY - MemoryMarshal.Write(memorySpan, ref value); -#endif - memoryStream.Write(memorySpan); - } - - /// - /// 根据int值获取字节数组。 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(this long value, byte[] buffer) - { - if (buffer.Length < 8) - { - throw new ArgumentException("Buffer too small."); - } -#if FANTASY_NET - MemoryMarshal.Write(buffer.AsSpan(), in value); -#endif -#if FANTASY_UNITY - MemoryMarshal.Write(buffer.AsSpan(), ref value); -#endif - } - - /// - /// 根据uint值获取字节数组。 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteBytes(this MemoryStream memoryStream, long value) - { - using var memoryOwner = MemoryPool.Shared.Rent(8); - var memorySpan = memoryOwner.Memory.Span; -#if FANTASY_NET - MemoryMarshal.Write(memorySpan, in value); -#endif -#if FANTASY_UNITY - MemoryMarshal.Write(memorySpan, ref value); -#endif - memoryStream.Write(memorySpan); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/ADownload.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/ADownload.cs deleted file mode 100644 index 4846d51..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/ADownload.cs +++ /dev/null @@ -1,50 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public abstract class AUnityDownload : IDisposable - { - private long _timeId; - private ulong _totalDownloadedBytes; - private Download _download; - protected UnityWebRequest UnityWebRequest; - private FCancellationToken _cancellationToken; - private Scene Scene; - - protected AUnityDownload(Scene scene,Download download) - { - Scene = scene; - _download = download; - _download.Tasks.Add(this); - } - - protected UnityWebRequestAsyncOperation Start(UnityWebRequest unityWebRequest, bool monitor) - { - UnityWebRequest = unityWebRequest; - _timeId = Scene.TimerComponent.Unity.RepeatedTimer(33, Update); - return UnityWebRequest.SendWebRequest(); - } - - private void Update() - { - var downloadSpeed = UnityWebRequest.downloadedBytes - _totalDownloadedBytes; - _download.DownloadSpeed += downloadSpeed; - _download.TotalDownloadedBytes += downloadSpeed; - _totalDownloadedBytes = UnityWebRequest.downloadedBytes; - } - - public virtual void Dispose() - { - Update(); - _totalDownloadedBytes = 0; - UnityWebRequest?.Dispose(); - _download.Tasks.Remove(this); - Scene.TimerComponent.Unity.Remove(ref _timeId); - _download = null; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/ADownload.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/ADownload.cs.meta deleted file mode 100644 index 70e1e3c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/ADownload.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c5743903d34d474a818b5c2bafa31459 -timeCreated: 1726021902 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/Download.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/Download.cs deleted file mode 100644 index a53a42a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/Download.cs +++ /dev/null @@ -1,72 +0,0 @@ -#if FANTASY_UNITY -using System.Collections.Generic; -using System.Linq; -using Fantasy.Async; -using UnityEngine; - -namespace Fantasy.Unity.Download -{ - public sealed class Download - { - public Scene Scene; - public ulong DownloadSpeed; - public ulong TotalDownloadedBytes; - public readonly HashSet Tasks = new(); - - public static Download Create(Scene scene) => new Download(scene); - - private Download(Scene scene) - { - Scene = scene; - } - - public void Clear() - { - DownloadSpeed = 0; - TotalDownloadedBytes = 0; - - if (Tasks.Count <= 0) - { - return; - } - - foreach (var aUnityDownload in Tasks.ToArray()) - { - aUnityDownload.Dispose(); - } - - Tasks.Clear(); - } - - public FTask DownloadAssetBundle(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadAssetBundle(Scene, this).StartDownload(url, monitor, cancellationToken); - } - - public FTask DownloadAudioClip(string url, AudioType audioType, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadAudioClip(Scene, this).StartDownload(url, audioType, monitor, cancellationToken); - } - - public FTask DownloadSprite(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadSprite(Scene, this).StartDownload(url, monitor, cancellationToken); - } - - public FTask DownloadTexture(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadTexture(Scene, this).StartDownload(url, monitor, cancellationToken); - } - - public FTask DownloadText(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadText(Scene, this).StartDownload(url, monitor, cancellationToken); - } - - public FTask DownloadByte(string url, bool monitor = false, FCancellationToken cancellationToken = null) - { - return new DownloadByte(Scene, this).StartDownload(url, monitor, cancellationToken); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/Download.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/Download.cs.meta deleted file mode 100644 index 41e84be..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/Download.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5715816370e84842aaab799c9776a5e4 -timeCreated: 1726023436 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAssetBundle.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAssetBundle.cs deleted file mode 100644 index 9d8f5a4..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAssetBundle.cs +++ /dev/null @@ -1,54 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadAssetBundle : AUnityDownload - { - public DownloadAssetBundle(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequestAssetBundle.GetAssetBundle(Uri.EscapeUriString(url)), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var assetBundle = DownloadHandlerAssetBundle.GetContent(UnityWebRequest); - task.SetResult(assetBundle); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAssetBundle.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAssetBundle.cs.meta deleted file mode 100644 index c6bf29a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAssetBundle.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 07cbb9a010ed4fe1b90919f81847b9ea -timeCreated: 1726023471 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAudioClip.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAudioClip.cs deleted file mode 100644 index 29b3dc5..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAudioClip.cs +++ /dev/null @@ -1,54 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadAudioClip : AUnityDownload - { - public DownloadAudioClip(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, AudioType audioType, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequestMultimedia.GetAudioClip(Uri.EscapeUriString(url), audioType), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var audioClip = DownloadHandlerAudioClip.GetContent(UnityWebRequest); - task.SetResult(audioClip); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAudioClip.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAudioClip.cs.meta deleted file mode 100644 index 6440f22..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadAudioClip.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 66d3739ec33845148534e6ecaf134b73 -timeCreated: 1726023476 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadByte.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadByte.cs deleted file mode 100644 index 6c934d9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadByte.cs +++ /dev/null @@ -1,52 +0,0 @@ -#if FANTASY_UNITY -using Fantasy.Async; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadByte : AUnityDownload - { - public DownloadByte(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequest.Get(url), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var bytes = UnityWebRequest.downloadHandler.data; - task.SetResult(bytes); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadByte.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadByte.cs.meta deleted file mode 100644 index 0aa0487..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadByte.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ae87f3ea9f4e4c9ebabedf45b0bb83b1 -timeCreated: 1726023481 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadSprite.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadSprite.cs deleted file mode 100644 index 802a967..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadSprite.cs +++ /dev/null @@ -1,55 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadSprite : AUnityDownload - { - public DownloadSprite(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequestTexture.GetTexture(Uri.EscapeUriString(url)), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var texture = DownloadHandlerTexture.GetContent(UnityWebRequest); - var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 5, 1f); - task.SetResult(sprite); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadSprite.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadSprite.cs.meta deleted file mode 100644 index 354e3e3..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadSprite.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 0c2a0f442e974169b7d8b7a5878fe0e6 -timeCreated: 1726023487 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadText.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadText.cs deleted file mode 100644 index 50d8329..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadText.cs +++ /dev/null @@ -1,52 +0,0 @@ -#if FANTASY_UNITY -using Fantasy.Async; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadText : AUnityDownload - { - public DownloadText(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequest.Get(url), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var text = UnityWebRequest.downloadHandler.text; - task.SetResult(text); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadText.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadText.cs.meta deleted file mode 100644 index 35892a9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadText.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 4284aafa8572453cb75920d2d58e9c50 -timeCreated: 1726023491 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadTexture.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadTexture.cs deleted file mode 100644 index f66533d..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadTexture.cs +++ /dev/null @@ -1,54 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity.Download -{ - public sealed class DownloadTexture : AUnityDownload - { - public DownloadTexture(Scene scene, Download download) : base(scene, download) - { - } - - public FTask StartDownload(string url, bool monitor, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequestAsyncOperation = Start(UnityWebRequestTexture.GetTexture(Uri.EscapeUriString(url)), monitor); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - Dispose(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - try - { - if (UnityWebRequest.result == UnityWebRequest.Result.Success) - { - var texture = DownloadHandlerTexture.GetContent(UnityWebRequest); - task.SetResult(texture); - } - else - { - Log.Error(UnityWebRequest.error); - task.SetResult(null); - } - } - finally - { - Dispose(); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadTexture.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadTexture.cs.meta deleted file mode 100644 index 7b48ea6..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/Download/DownloadTexture.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5eaa6023378844ebb51e4b80425d8a4e -timeCreated: 1726023496 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/EncryptHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/EncryptHelper.cs deleted file mode 100644 index be950bc..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/EncryptHelper.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.IO; -using System.Security.Cryptography; -using System.Text; - -namespace Fantasy.Helper -{ - /// - /// 提供计算 MD5 散列值的辅助方法。 - /// - public static partial class EncryptHelper - { - private static readonly SHA256 Sha256Hash = SHA256.Create(); - - /// - /// 计算指定字节数组的Sha256。 - /// - /// - /// - public static byte[] ComputeSha256Hash(byte[] bytes) - { -#if FANTASY_UNITY - using var sha256Hash = SHA256.Create(); - return sha256Hash.ComputeHash(bytes); -#else - return SHA256.HashData(bytes); -#endif - } - - /// - /// 计算指定文件的 MD5 散列值。 - /// - /// 要计算散列值的文件路径。 - /// 表示文件的 MD5 散列值的字符串。 - public static string FileMD5(string filePath) - { - using var file = new FileStream(filePath, FileMode.Open); - return FileMD5(file); - } - - /// - /// 计算给定文件流的 MD5 散列值。 - /// - /// 要计算散列值的文件流。 - /// 表示文件流的 MD5 散列值的字符串。 - public static string FileMD5(FileStream fileStream) - { - var md5 = MD5.Create(); - return md5.ComputeHash(fileStream).ToHex("x2"); - } - - /// - /// 计算给定字节数组的 MD5 散列值。 - /// - /// 要计算散列值的字节数组。 - /// 表示字节数组的 MD5 散列值的字符串。 - public static string BytesMD5(byte[] bytes) - { - var md5 = MD5.Create(); - bytes = md5.ComputeHash(bytes); - return bytes.ToHex("x2"); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/FileHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/FileHelper.cs deleted file mode 100644 index 66ff5ae..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/FileHelper.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace Fantasy.Helper -{ - /// - /// 文件操作助手类,提供了各种文件操作方法。 - /// - public static partial class FileHelper - { - /// - /// 获取相对路径的完整路径。 - /// - /// 相对路径。 - /// 完整路径。 - public static string GetFullPath(string relativePath) - { - return Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), relativePath)); - } - - /// - /// 获取相对路径的完整路径。 - /// - /// 相对于指定的目录的相对路径。 - /// 指定的目录 - /// 完整路径。 - public static string GetFullPath(string relativePath, string srcDir) - { - return Path.GetFullPath(Path.Combine(srcDir, relativePath)); - } - - /// - /// 获取相对路径的的文本信息。 - /// - /// - /// - public static async Task GetTextByRelativePath(string relativePath) - { - var fullPath = GetFullPath(relativePath); - return await File.ReadAllTextAsync(fullPath, Encoding.UTF8); - } - - /// - /// 获取绝对路径的的文本信息。 - /// - /// - /// - public static async Task GetText(string fullPath) - { - return await File.ReadAllTextAsync(fullPath, Encoding.UTF8); - } - - /// - /// 根据文件夹路径创建文件夹,如果文件夹不存在会自动创建文件夹。 - /// - /// - public static void CreateDirectory(string directoryPath) - { - if (directoryPath.LastIndexOf('/') != directoryPath.Length - 1) - { - directoryPath += "/"; - } - - var directoriesByFilePath = GetDirectoriesByFilePath(directoryPath); - - foreach (var dir in directoriesByFilePath) - { - if (Directory.Exists(dir)) - { - continue; - } - - Directory.CreateDirectory(dir); - } - } - - /// - /// 将文件复制到目标路径,如果目标目录不存在会自动创建目录。 - /// - /// 源文件路径。 - /// 目标文件路径。 - /// 是否覆盖已存在的目标文件。 - public static void Copy(string sourceFile, string destinationFile, bool overwrite) - { - CreateDirectory(destinationFile); - File.Copy(sourceFile, destinationFile, overwrite); - } - - /// - /// 获取文件路径内的所有文件夹路径。 - /// - /// 文件路径。 - /// 文件夹路径列表。 - public static IEnumerable GetDirectoriesByFilePath(string filePath) - { - var dir = ""; - var fileDirectories = filePath.Split('/'); - - for (var i = 0; i < fileDirectories.Length - 1; i++) - { - dir = $"{dir}{fileDirectories[i]}/"; - yield return dir; - } - - if (fileDirectories.Length == 1) - { - yield return filePath; - } - } - - /// - /// 将文件夹内的所有内容复制到目标位置。 - /// - /// 源文件夹路径。 - /// 目标文件夹路径。 - /// 是否覆盖已存在的文件。 - public static void CopyDirectory(string sourceDirectory, string destinationDirectory, bool overwrite) - { - // 创建目标文件夹 - - if (!Directory.Exists(destinationDirectory)) - { - Directory.CreateDirectory(destinationDirectory); - } - - // 获取当前文件夹中的所有文件 - - var files = Directory.GetFiles(sourceDirectory); - - // 拷贝文件到目标文件夹 - - foreach (var file in files) - { - var fileName = Path.GetFileName(file); - var destinationPath = Path.Combine(destinationDirectory, fileName); - File.Copy(file, destinationPath, overwrite); - } - - // 获取源文件夹中的所有子文件夹 - - var directories = Directory.GetDirectories(sourceDirectory); - - // 递归方式拷贝文件夹 - - foreach (var directory in directories) - { - var directoryName = Path.GetFileName(directory); - var destinationPath = Path.Combine(destinationDirectory, directoryName); - CopyDirectory(directory, destinationPath, overwrite); - } - } - - /// - /// 获取目录下的所有文件 - /// - /// 文件夹路径。 - /// 需要查找的文件通配符 - /// 查找的类型 - /// - public static string[] GetDirectoryFile(string folderPath, string searchPattern, SearchOption searchOption) - { - return Directory.GetFiles(folderPath, searchPattern, searchOption); - } - - /// - /// 清空文件夹内的所有文件。 - /// - /// 文件夹路径。 - public static void ClearDirectoryFile(string folderPath) - { - if (!Directory.Exists(folderPath)) - { - return; - } - - var files = Directory.GetFiles(folderPath); - - foreach (var file in files) - { - File.Delete(file); - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/HashCodeHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/HashCodeHelper.cs deleted file mode 100644 index 7f2a5af..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/HashCodeHelper.cs +++ /dev/null @@ -1,229 +0,0 @@ -using System.Security.Cryptography; -using System.Text; -// ReSharper disable InconsistentNaming - -namespace Fantasy.Helper -{ - /// - /// HashCode算法帮助类 - /// - public static partial class HashCodeHelper - { - private static readonly SHA256 Sha256Hash = SHA256.Create(); - - /// - /// 计算两个字符串的HashCode - /// - /// - /// - /// - public static int GetHashCode(string a, string b) - { - var hash = 17; - hash = hash * 31 + a.GetHashCode(); - hash = hash * 31 + b.GetHashCode(); - return hash; - } -#if FANTASY_NET || !FANTASY_WEBGL - /// - /// 使用bkdr算法生成一个long的值 - /// - /// - /// - public static unsafe long GetBKDRHashCode(string str) - { - ulong hash = 0; - // 如果要修改这个种子、建议选择一个质数来做种子 - const uint seed = 13131; // 31 131 1313 13131 131313 etc.. - fixed (char* p = str) - { - for (var i = 0; i < str.Length; i++) - { - var c = p[i]; - var high = (byte)(c >> 8); - var low = (byte)(c & byte.MaxValue); - hash = hash * seed + high; - hash = hash * seed + low; - } - } - return (long)hash; - } - - /// - /// 使用MurmurHash3算法生成一个uint的值 - /// - /// - /// - public static unsafe uint MurmurHash3(string str) - { - const uint seed = 0xc58f1a7b; - uint hash = seed; - uint c1 = 0xcc9e2d51; - uint c2 = 0x1b873593; - - fixed (char* p = str) - { - var current = p; - - for (var i = 0; i < str.Length; i++) - { - var k1 = (uint)(*current); - k1 *= c1; - k1 = (k1 << 15) | (k1 >> (32 - 15)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 13) | (hash >> (32 - 13)); - hash = hash * 5 + 0xe6546b64; - - current++; - } - } - - hash ^= (uint)str.Length; - hash ^= hash >> 16; - hash *= 0x85ebca6b; - hash ^= hash >> 13; - hash *= 0xc2b2ae35; - hash ^= hash >> 16; - return hash; - } - - /// - /// 使用MurmurHash3算法生成一个long的值 - /// - /// - /// - public static unsafe long ComputeHash64(string str) - { - const ulong seed = 0xc58f1a7bc58f1a7bUL; // 64-bit seed - var hash = seed; - var c1 = 0x87c37b91114253d5UL; - var c2 = 0x4cf5ad432745937fUL; - - fixed (char* p = str) - { - var current = p; - - for (var i = 0; i < str.Length; i++) - { - var k1 = (ulong)(*current); - k1 *= c1; - k1 = (k1 << 31) | (k1 >> (64 - 31)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 27) | (hash >> (64 - 27)); - hash = hash * 5 + 0x52dce729; - - current++; - } - } - - hash ^= (ulong)str.Length; - hash ^= hash >> 33; - hash *= 0xff51afd7ed558ccdUL; - hash ^= hash >> 33; - hash *= 0xc4ceb9fe1a85ec53UL; - hash ^= hash >> 33; - return (long)hash; - } -#endif -#if FANTASY_WEBGL - /// - /// 使用bkdr算法生成一个long的值 - /// - /// - /// - public static long GetBKDRHashCode(string str) - { - long hash = 0; - // 如果要修改这个种子、建议选择一个质数来做种子 - const uint seed = 13131; // 31 131 1313 13131 131313 etc.. - foreach (var c in str) - { - var high = (byte)(c >> 8); - var low = (byte)(c & byte.MaxValue); - hash = hash * seed + high; - hash = hash * seed + low; - } - return hash; - } - /// - /// 使用MurmurHash3算法生成一个uint的值 - /// - /// - /// - public static uint MurmurHash3(string str) - { - const uint seed = 0xc58f1a7b; - uint hash = seed; - uint c1 = 0xcc9e2d51; - uint c2 = 0x1b873593; - - foreach (var t in str) - { - var k1 = (uint)(t); - k1 *= c1; - k1 = (k1 << 15) | (k1 >> (32 - 15)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 13) | (hash >> (32 - 13)); - hash = hash * 5 + 0xe6546b64; - } - - hash ^= (uint)str.Length; - hash ^= hash >> 16; - hash *= 0x85ebca6b; - hash ^= hash >> 13; - hash *= 0xc2b2ae35; - hash ^= hash >> 16; - return hash; - } - - /// - /// 使用MurmurHash3算法生成一个long的值 - /// - /// - /// - public static long ComputeHash64(string str) - { - const ulong seed = 0xc58f1a7bc58f1a7bUL; // 64-bit seed - var hash = seed; - var c1 = 0x87c37b91114253d5UL; - var c2 = 0x4cf5ad432745937fUL; - - foreach (var t in str) - { - var k1 = (ulong)(t); - k1 *= c1; - k1 = (k1 << 31) | (k1 >> (64 - 31)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 27) | (hash >> (64 - 27)); - hash = hash * 5 + 0x52dce729; - } - - hash ^= (ulong)str.Length; - hash ^= hash >> 33; - hash *= 0xff51afd7ed558ccdUL; - hash ^= hash >> 33; - hash *= 0xc4ceb9fe1a85ec53UL; - hash ^= hash >> 33; - return (long)hash; - } -#endif - /// - /// 根据字符串计算一个Hash值 - /// - /// - /// - public static int ComputeSha256HashAsInt(string rawData) - { - var bytes = Sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData)); - return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs deleted file mode 100644 index 3954a8c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs +++ /dev/null @@ -1,144 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Pool; -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Http -{ - /// - /// HTTP帮助类 - /// - public static partial class HttpClientHelper - { - private static readonly HttpClient Client = new HttpClient(new HttpClientHandler - { - ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true - }); - - /// - /// 用Post方式请求string数据 - /// - /// - /// - /// - /// - public static async FTask CallNotDeserializeByPost(string url, HttpContent content) - { - var response = await Client.PostAsync(url, content); - - if (response.StatusCode != HttpStatusCode.OK) - { - throw new Exception($"Unable to connect to server url {(object)url} HttpStatusCode:{(object)response.StatusCode}"); - } - - return await response.Content.ReadAsStringAsync(); - } - - /// - /// 用Get方式请求string数据 - /// - /// - /// - /// - public static async FTask CallNotDeserializeByGet(string url) - { - var response = await Client.GetAsync(url); - - if (response.StatusCode != HttpStatusCode.OK) - { - throw new Exception($"Unable to connect to server url {(object)url} HttpStatusCode:{(object)response.StatusCode}"); - } - - return await response.Content.ReadAsStringAsync(); - } - - /// - /// 用Post方式请求JSON数据,并自动把JSON转换为对象。 - /// - /// - /// - /// - /// - public static async FTask CallByPost(string url, HttpContent content) - { - return await Deserialize(url, await Client.PostAsync(url, content)); - } - - /// - /// 用Post方式请求JSON数据,并自动把JSON转换为对象。 - /// - /// - /// - /// - /// - public static async FTask CallByPost(string url, HttpMethod method) - { - return await Deserialize(url, await Client.SendAsync(new HttpRequestMessage(method, url))); - } - - /// - /// 用Get方式请求JSON数据,并自动把JSON转换为对象。 - /// - /// - /// - /// - public static async FTask CallByGet(string url) - { - return await Deserialize(url, await Client.GetAsync(url)); - } - - /// - /// 用Post方式请求JSON数据,并自动把JSON转换为对象。 - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static async FTask Call(string url, int id, AuthenticationHeaderValue authentication, string method, params object[] @params) where TRequest : class, IJsonRpcRequest, new() - { - var request = Pool.Rent(); - using var httpClientPool = HttpClientPool.Create(); - var client = httpClientPool.Client; - client.DefaultRequestHeaders.Authorization = authentication; - - try - { - request.Init(method, id, @params); - var content = new StringContent(request.ToJson(), Encoding.UTF8, "application/json"); - var response = await Deserialize(url, await client.PostAsync(url, content)); - return response; - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - Pool.Return(request); - } - - return default; - } - - private static async FTask Deserialize(string url, HttpResponseMessage response) - { - if (response.StatusCode != HttpStatusCode.OK) - { - throw new Exception($"Unable to connect to server url {(object)url} HttpStatusCode:{(object)response.StatusCode}"); - } - - return (await response.Content.ReadAsStringAsync()).Deserialize(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs.meta deleted file mode 100644 index 70e3bd5..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientHelper.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f8005f3a1a1945a2929442f82832e765 -timeCreated: 1726023741 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientPool.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientPool.cs deleted file mode 100644 index de421ff..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientPool.cs +++ /dev/null @@ -1,44 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Net.Http; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Http -{ - internal class HttpClientPool : IDisposable - { - private bool IsDispose { get; set; } - public HttpClient Client { get; private set; } - private static readonly Queue Pools = new Queue(); - private static readonly HttpClientHandler ClientHandler = new HttpClientHandler - { - ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true - }; - - public static HttpClientPool Create() - { - if (Pools.TryDequeue(out var httpClientPool)) - { - httpClientPool.IsDispose = false; - return httpClientPool; - } - - httpClientPool = new HttpClientPool(); - httpClientPool.Client = new HttpClient(ClientHandler); - return httpClientPool; - } - - public void Dispose() - { - if (IsDispose) - { - return; - } - - IsDispose = true; - Pools.Enqueue(this); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientPool.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientPool.cs.meta deleted file mode 100644 index a1ac3bf..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/HttpClientPool.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: a78c441357d244d5ba490a13c89e1c50 -timeCreated: 1726023895 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs deleted file mode 100644 index ae756c5..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Fantasy.Pool; - -#if !FANTASY_WEBGL -namespace Fantasy.Http -{ - /// - /// 一个JsonRPC的接口 - /// - public interface IJsonRpcRequest : IPool - { - /// - /// 用于初始化这个Json对象 - /// - /// - /// - /// - void Init(string method, int id, params object[] @params); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs.meta deleted file mode 100644 index 9e01783..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/HttpClient/IJsonRpcRequest.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 72a03580c619417b9f8f92d99938e371 -timeCreated: 1726023900 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/JsonHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/JsonHelper.cs deleted file mode 100644 index 2b10fab..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/JsonHelper.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using Newtonsoft.Json; -#pragma warning disable CS8603 - -namespace Fantasy.Helper -{ - /// - /// 提供操作 JSON 数据的辅助方法。 - /// - public static partial class JsonHelper - { - /// - /// 将对象序列化为 JSON 字符串。 - /// - /// 要序列化的对象类型。 - /// 要序列化的对象。 - /// 表示序列化对象的 JSON 字符串。 - public static string ToJson(this T t) - { - return JsonConvert.SerializeObject(t); - } - - /// - /// 反序列化 JSON 字符串为指定类型的对象。 - /// - /// 要反序列化的 JSON 字符串。 - /// 目标对象的类型。 - /// 是否使用反射进行反序列化(默认为 true)。 - /// 反序列化后的对象。 - public static object Deserialize(this string json, Type type, bool reflection = true) - { - return JsonConvert.DeserializeObject(json, type); - } - - /// - /// 反序列化 JSON 字符串为指定类型的对象。 - /// - /// 目标对象的类型。 - /// 要反序列化的 JSON 字符串。 - /// 反序列化后的对象。 - public static T Deserialize(this string json) - { - return JsonConvert.DeserializeObject(json); - } - - /// - /// 克隆对象,通过将对象序列化为 JSON,然后再进行反序列化。 - /// - /// 要克隆的对象类型。 - /// 要克隆的对象。 - /// 克隆后的对象。 - public static T Clone(T t) - { - return t.ToJson().Deserialize(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/NetworkHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/NetworkHelper.cs deleted file mode 100644 index 6a35a61..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/NetworkHelper.cs +++ /dev/null @@ -1,443 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.NetworkInformation; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -#pragma warning disable CS8603 // Possible null reference return. - -// ReSharper disable InconsistentNaming - -namespace Fantasy.Helper -{ - /// - /// 提供网络操作相关的帮助方法。 - /// - public static partial class NetworkHelper - { - /// - /// 根据字符串获取一个IPEndPoint - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IPEndPoint GetIPEndPoint(string address) - { - try - { - var addressSplit = address.Split(':'); - if (addressSplit.Length != 2) - { - throw new FormatException("Invalid format"); - } - - var ipString = addressSplit[0]; - var portString = addressSplit[1]; - - if (!IPAddress.TryParse(ipString, out var ipAddress)) - { - throw new FormatException("Invalid IP address"); - } - - if (!int.TryParse(portString, out var port) || port < 0 || port > 65535) - { - throw new FormatException("Invalid port number"); - } - - return new IPEndPoint(ipAddress, port); - } - catch (Exception e) - { - Log.Error($"Error parsing IP and Port:{e.Message}"); - return null; - } - } - - /// - /// 克隆一个IPEndPoint - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IPEndPoint Clone(this EndPoint endPoint) - { - var ip = (IPEndPoint)endPoint; - return new IPEndPoint(ip.Address, ip.Port); - } - - /// - /// 比较两个IPEndPoint是否相等 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IPEndPointEquals(this EndPoint endPoint, IPEndPoint ipEndPoint) - { - var ip = (IPEndPoint)endPoint; - return ip.Address.Equals(ipEndPoint.Address) && ip.Port == ipEndPoint.Port; - } - - /// - /// 比较两个IPEndPoint是否相等 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IPEndPointEquals(this IPEndPoint endPoint, IPEndPoint ipEndPoint) - { - return endPoint.Address.Equals(ipEndPoint.Address) && endPoint.Port == ipEndPoint.Port; - } - -#if !FANTASY_WEBGL - /// - /// 将SocketAddress写入到Byte[]中 - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void SocketAddressToByte(this SocketAddress socketAddress, byte[] buffer, int offset) - { - if (socketAddress == null) - { - throw new ArgumentNullException(nameof(socketAddress), "The SocketAddress cannot be null."); - } - - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer), "The buffer cannot be null."); - } - - if (buffer.Length < socketAddress.Size + offset + 8) - { - throw new ArgumentException("The buffer length is insufficient. It must be at least the size of the SocketAddress plus 8 bytes.", nameof(buffer)); - } - - fixed (byte* pBuffer = buffer) - { - var pOffsetBuffer = pBuffer + offset; - var addressFamilyValue = (int)socketAddress.Family; - var socketAddressSizeValue = socketAddress.Size; - Buffer.MemoryCopy(&addressFamilyValue, pOffsetBuffer, buffer.Length - offset, sizeof(int)); - Buffer.MemoryCopy(&socketAddressSizeValue, pOffsetBuffer + 4, buffer.Length - offset -4, sizeof(int)); - for (var i = 0; i < socketAddress.Size - 2; i++) - { - pOffsetBuffer[8 + i] = socketAddress[i + 2]; - } - } - } - - /// - /// 将byre[]转换为SocketAddress - /// - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int ByteToSocketAddress(byte[] buffer, int offset, out SocketAddress socketAddress) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer), "The buffer cannot be null."); - } - - if (buffer.Length < 8) - { - throw new ArgumentException("Buffer length is insufficient. It must be at least 8 bytes.", nameof(buffer)); - } - - try - { - fixed (byte* pBuffer = buffer) - { - var pOffsetBuffer = pBuffer + offset; - var addressFamily = (AddressFamily)Marshal.ReadInt32((IntPtr)pOffsetBuffer); - var socketAddressSize = Marshal.ReadInt32((IntPtr)(pOffsetBuffer + 4)); - - if (buffer.Length < offset + 8 + socketAddressSize) - { - throw new ArgumentException("Buffer length is insufficient for the given SocketAddress size.", nameof(buffer)); - } - - socketAddress = new SocketAddress(addressFamily, socketAddressSize); - - for (var i = 0; i < socketAddressSize - 2; i++) - { - socketAddress[i + 2] = *(pOffsetBuffer + 8 + i); - } - - return 8 + offset + socketAddressSize; - } - } - catch (ArgumentNullException ex) - { - throw new InvalidOperationException("An argument provided to the method is null.", ex); - } - catch (ArgumentException ex) - { - throw new InvalidOperationException("An argument provided to the method is invalid.", ex); - } - catch (Exception ex) - { - throw new InvalidOperationException("An unexpected error occurred while processing the buffer.", ex); - } - } - - /// - /// 将ReadOnlyMemory转换为SocketAddress - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int ByteToSocketAddress(ReadOnlyMemory buffer, int offset, out SocketAddress socketAddress) - { - if (buffer.Length < 8) - { - throw new ArgumentException("Buffer length is insufficient. It must be at least 8 bytes.", nameof(buffer)); - } - - try - { - fixed (byte* pBuffer = buffer.Span) - { - var pOffsetBuffer = pBuffer + offset; - var addressFamily = (AddressFamily)Marshal.ReadInt32((IntPtr)pOffsetBuffer); - var socketAddressSize = Marshal.ReadInt32((IntPtr)(pOffsetBuffer + 4)); - - if (buffer.Length < offset + 8 + socketAddressSize) - { - throw new ArgumentException("Buffer length is insufficient for the given SocketAddress size.", nameof(buffer)); - } - - socketAddress = new SocketAddress(addressFamily, socketAddressSize); - - for (var i = 0; i < socketAddressSize - 2; i++) - { - socketAddress[i + 2] = *(pOffsetBuffer + 8 + i); - } - - return 8 + offset + socketAddressSize; - } - } - catch (ArgumentNullException ex) - { - throw new InvalidOperationException("An argument provided to the method is null.", ex); - } - catch (ArgumentException ex) - { - throw new InvalidOperationException("An argument provided to the method is invalid.", ex); - } - catch (Exception ex) - { - throw new InvalidOperationException("An unexpected error occurred while processing the buffer.", ex); - } - } - - /// - /// 根据SocketAddress获得IPEndPoint - /// - /// - /// - /// - public static unsafe IPEndPoint GetIPEndPoint(this SocketAddress socketAddress) - { - switch (socketAddress.Family) - { - case AddressFamily.InterNetwork: - { - var ipBytes = new byte[4]; - for (var i = 0; i < 4; i++) - { - ipBytes[i] = socketAddress[4 + i]; - } - var port = (socketAddress[2] << 8) + socketAddress[3]; - var ip = new IPAddress(ipBytes); - return new IPEndPoint(ip, port); - } - case AddressFamily.InterNetworkV6: - { - var ipBytes = new byte[16]; - Span socketAddressSpan = stackalloc byte[28]; - - for (var i = 0; i < 28; i++) - { - socketAddressSpan[i] = socketAddress[i]; - } - - fixed (byte* pSocketAddress = socketAddressSpan) - { - for (var i = 0; i < 16; i++) - { - ipBytes[i] = *(pSocketAddress + 8 + i); - } - - var port = (*(pSocketAddress + 2) << 8) + *(pSocketAddress + 3); - var scopeId = Marshal.ReadInt64((IntPtr)(pSocketAddress + 24)); - var ip = new IPAddress(ipBytes, scopeId); - return new IPEndPoint(ip, port); - } - } - default: - { - throw new NotSupportedException("Address family not supported."); - } - } - } -#endif - /// - /// 获取本机所有网络适配器的IP地址。 - /// - /// IP地址数组。 - public static string[] GetAddressIPs() - { - var list = new List(); - foreach (var networkInterface in NetworkInterface.GetAllNetworkInterfaces()) - { - // 仅考虑以太网类型的网络适配器 - if (networkInterface.NetworkInterfaceType != NetworkInterfaceType.Ethernet) - { - continue; - } - - foreach (var add in networkInterface.GetIPProperties().UnicastAddresses) - { - list.Add(add.Address.ToString()); - } - } - - return list.ToArray(); - } - - /// - /// 将主机名和端口号转换为 实例。 - /// - /// 主机名。 - /// 端口号。 - /// 实例。 - public static IPEndPoint ToIPEndPoint(string host, int port) - { - return new IPEndPoint(IPAddress.Parse(host), port); - } - - /// - /// 将地址字符串转换为 实例。 - /// - /// 地址字符串,格式为 "主机名:端口号"。 - /// 实例。 - public static IPEndPoint ToIPEndPoint(string address) - { - var index = address.LastIndexOf(':'); - var host = address.Substring(0, index); - var p = address.Substring(index + 1); - var port = int.Parse(p); - return ToIPEndPoint(host, port); - } - - /// - /// 将 实例转换为字符串表示形式。 - /// - /// 实例。 - /// 表示 的字符串。 - public static string IPEndPointToStr(this IPEndPoint self) - { - return $"{self.Address}:{self.Port}"; - } - - /// - /// 针对 Windows 平台设置UDP连接重置选项。 - /// - /// 要设置选项的 实例。 - public static void SetSioUdpConnReset(this Socket socket) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return; - } - - /* - 目前这个问题只有Windows下才会出现。 - 服务器端在发送数据时捕获到了一个异常, - 这个异常导致原因应该是远程客户端的UDP监听已停止导致数据发送出错。 - 按理说UDP是无连接的,报这个异常是不合理的 - 这个异常让整UDP的服务监听也停止了。 - 这样就因为一个客户端的数据发送无法到达而导致了服务挂了,所有客户端都无法与服务器通信了 - 想详细了解看下https://blog.csdn.net/sunzhen6251/article/details/124168805*/ - const uint IOC_IN = 0x80000000; - const uint IOC_VENDOR = 0x18000000; - const int SIO_UDP_CONNRESET = unchecked((int) (IOC_IN | IOC_VENDOR | 12)); - - socket.IOControl(SIO_UDP_CONNRESET, new[] {Convert.ToByte(false)}, null); - } - - /// - /// 将 Socket 缓冲区大小设置为操作系统限制。 - /// - /// 要设置缓冲区大小的 Socket。 - public static void SetSocketBufferToOsLimit(this Socket socket) - { - socket.SetReceiveBufferToOSLimit(); - socket.SetSendBufferToOSLimit(); - } - - /// - /// 将 Socket 接收缓冲区大小设置为操作系统限制。 - /// 尝试增加接收缓冲区大小的次数 = 默认 + 最大增加 100 MB。 - /// - /// 要设置接收缓冲区大小的 Socket。 - /// 每次增加的步长大小。 - /// 尝试增加缓冲区大小的次数。 - public static void SetReceiveBufferToOSLimit(this Socket socket, int stepSize = 1024, int attempts = 100_000) - { - // setting a too large size throws a socket exception. - // so let's keep increasing until we encounter it. - for (int i = 0; i < attempts; ++i) - { - // increase in 1 KB steps - try - { - socket.ReceiveBufferSize += stepSize; - } - catch (SocketException) - { - break; - } - } - } - - /// - /// 将 Socket 发送缓冲区大小设置为操作系统限制。 - /// 尝试增加发送缓冲区大小的次数 = 默认 + 最大增加 100 MB。 - /// - /// 要设置发送缓冲区大小的 Socket。 - /// 每次增加的步长大小。 - /// 尝试增加缓冲区大小的次数。 - public static void SetSendBufferToOSLimit(this Socket socket, int stepSize = 1024, int attempts = 100_000) - { - // setting a too large size throws a socket exception. - // so let's keep increasing until we encounter it. - for (var i = 0; i < attempts; ++i) - { - // increase in 1 KB steps - try - { - socket.SendBufferSize += stepSize; - } - catch (SocketException) - { - break; - } - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/RandomHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/RandomHelper.cs deleted file mode 100644 index c90a16c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/RandomHelper.cs +++ /dev/null @@ -1,311 +0,0 @@ -#if FANTASY_NET || !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using Fantasy.LowLevel; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -namespace Fantasy.Helper -{ - /// - /// 随机数操作助手类,提供各种随机数生成和操作方法。 - /// - public static partial class RandomHelper - { - [ThreadStatic] - private static Random _random; - - /// - /// 生成一个随机的无符号 64 位整数。 - /// - /// 无符号 64 位整数。 - public static ulong RandUInt64() - { - var byte8 = new FixedBytes8().AsSpan(); - var random = _random ??= new Random(); - random.NextBytes(byte8); - return BitConverter.ToUInt64(byte8); - } - - /// - /// 生成一个随机的 64 位整数。 - /// - /// 64 位整数。 - public static long RandInt64() - { - var byte8 = new FixedBytes8().AsSpan(); - var random = _random ??= new Random(); - random.NextBytes(byte8); - return BitConverter.ToInt64(byte8); - } - - /// - /// 生成一个随机的无符号 32 位整数。 - /// - /// 无符号 32 位整数。 - public static uint RandUInt32() - { - var random = _random ??= new Random(); - return (uint) random.Next(); - } - - /// - /// 生成一个随机的无符号 16 位整数。 - /// - /// 无符号 16 位整数。 - public static ushort RandUInt16() - { - var byte2 = new FixedBytes2().AsSpan(); - var random = _random ??= new Random(); - random.NextBytes(byte2); - return BitConverter.ToUInt16(byte2); - } - - /// - /// 在指定范围内生成一个随机整数(包含下限,不包含上限)。 - /// - /// 下限。 - /// 上限。 - /// 生成的随机整数。 - public static int RandomNumber(int lower, int upper) - { - var random = _random ??= new Random(); - return random.Next(lower, upper); - } - - /// - /// 生成一个随机的布尔值。 - /// - /// 随机的布尔值。 - public static bool RandomBool() - { - var random = _random ??= new Random(); - return (random.Next() & 1) == 0; - } - - /// - /// 从数组中随机选择一个元素。 - /// - /// 数组元素的类型。 - /// 要选择的数组。 - /// 随机选择的数组元素。 - public static T RandomArray(this T[] array) - { - return array[RandomNumber(0, array.Count())]; - } - - /// - /// 从列表中随机选择一个元素。 - /// - /// 列表元素的类型。 - /// 要选择的列表。 - /// 随机选择的列表元素。 - public static T RandomArray(this List array) - { - return array[RandomNumber(0, array.Count())]; - } - - /// - /// 打乱列表中元素的顺序。 - /// - /// 列表元素的类型。 - /// 要打乱顺序的列表。 - public static void BreakRank(List arr) - { - if (arr == null || arr.Count < 2) - { - return; - } - - var random = _random ??= new Random(); - for (var i = 0; i < arr.Count / 2; i++) - { - var index = random.Next(0, arr.Count); - (arr[index], arr[arr.Count - index - 1]) = (arr[arr.Count - index - 1], arr[index]); - } - } - - /// - /// 生成一个介于 0 和 1 之间的随机单精度浮点数。 - /// - /// 随机单精度浮点数。 - public static float RandFloat01() - { - var random = _random ??= new Random(); - var value = random.NextDouble(); - return (float) value; - } - - private static int Rand(int n) - { - var rd = new Random(); - // 注意,返回值是左闭右开,所以maxValue要加1 - return rd.Next(1, n + 1); - } - - /// - /// 根据权重随机选择一个索引。 - /// - /// 权重数组,每个元素表示相应索引的权重。 - /// 随机选择的索引值。 - public static int RandomByWeight(int[] weights) - { - var sum = weights.Sum(); - var numberRand = Rand(sum); - var sumTemp = 0; - for (var i = 0; i < weights.Length; i++) - { - sumTemp += weights[i]; - if (numberRand <= sumTemp) - { - return i; - } - } - - return -1; - } - - /// - /// 根据固定概率随机选择一个索引,即某个数值上限内随机多少次。 - /// - /// 概率数组,每个元素表示相应索引的概率。 - /// 随机选择的索引值。 - public static int RandomByFixedProbability(int[] args) - { - var random = _random ??= new Random(); - var argCount = args.Length; - var sum = args.Sum(); - var value = random.NextDouble() * sum; - while (sum > value) - { - sum -= args[argCount - 1]; - argCount--; - } - - return argCount; - } - - /// - /// 返回随机数。 - /// - /// 是否包含负数。 - /// 返回一个随机的单精度浮点数。 - public static float NextFloat(bool containNegative = false) - { - var random = _random ??= new Random(); - float f; - var buffer = new FixedBytes4().AsSpan(); - if (containNegative) - { - do - { - random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer); - } while ((f >= float.MinValue && f < float.MaxValue) == false); - - return f; - } - - do - { - random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer); - } while ((f >= 0 && f < float.MaxValue) == false); - - return f; - } - - /// - /// 返回一个小于所指定最大值的非负随机数。 - /// - /// 要生成的随机数的上限(随机数不能取该上限值)。 maxValue 必须大于或等于零。 - /// 大于等于零且小于 maxValue 的单精度浮点数,即:返回值的范围通常包括零但不包括 maxValue。 不过,如果 maxValue 等于零,则返回 maxValue。 - public static float NextFloat(float maxValue) - { - if (maxValue.Equals(0)) - { - return maxValue; - } - - if (maxValue < 0) - { - throw new ArgumentOutOfRangeException("“maxValue”必须大于 0。", "maxValue"); - } - - var random = _random ??= new Random(); - float f; - var buffer = new FixedBytes4().AsSpan(); - - do - { - random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer); - } while ((f >= 0 && f < maxValue) == false); - - return f; - } - - /// - /// 返回一个指定范围内的随机数。 - /// - /// 返回的随机数的下界(随机数可取该下界值)。 - /// 返回的随机数的上界(随机数不能取该上界值)。 maxValue 必须大于或等于 minValue。 - /// 一个大于等于 minValue 且小于 maxValue 的单精度浮点数,即:返回的值范围包括 minValue 但不包括 maxValue。 如果 minValue 等于 maxValue,则返回 minValue。 - public static float NextFloat(float minValue, float maxValue) - { - if (minValue.Equals(maxValue)) - { - return minValue; - } - - if (minValue > maxValue) - { - throw new ArgumentOutOfRangeException("“minValue”不能大于 maxValue。", "minValue"); - } - - var random = _random ??= new Random(); - var buffer = new FixedBytes4().AsSpan(); - float f; - - do - { - random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer); - } while ((f >= minValue && f < maxValue) == false); - - return f; - } - - /// - /// 在指定的矩形区域内随机生成一个二维向量位置。 - /// - /// X轴最小值。 - /// X轴最大值。 - /// Y轴最小值。 - /// Y轴最大值。 - /// 随机生成的二维向量位置。 - public static Vector2 NextVector2(float minX, float maxX, float minY, float maxY) - { - return new Vector2(NextFloat(minX, maxX), NextFloat(minY, maxY)); - } - - /// - /// 生成指定长度的随机数字代码。 - /// - /// 数字代码的长度。 - /// 生成的随机数字代码。 - public static string RandomNumberCode(int len = 6) - { - int num = 0; - for (int i = 0; i < len; i++) - { - int number = RandomNumber(0, 10); - num = num * 10 + number; - } - - return num.ToString(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/RandomHelperWebgl.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/RandomHelperWebgl.cs deleted file mode 100644 index 0820acf..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/RandomHelperWebgl.cs +++ /dev/null @@ -1,295 +0,0 @@ -#if FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; - -namespace Fantasy.Helper -{ - /// - /// 随机数操作助手类,提供各种随机数生成和操作方法。 - /// - public static partial class RandomHelper - { - private static readonly Random Random = new Random(); - private static readonly byte[] Byte8 = new byte[8]; - private static readonly byte[] Byte2 = new byte[2]; - - /// - /// 生成一个随机的无符号 64 位整数。 - /// - /// 无符号 64 位整数。 - public static ulong RandUInt64() - { - Random.NextBytes(Byte8); - return BitConverter.ToUInt64(Byte8, 0); - } - - /// - /// 生成一个随机的 64 位整数。 - /// - /// 64 位整数。 - public static long RandInt64() - { - Random.NextBytes(Byte8); - return BitConverter.ToInt64(Byte8, 0); - } - - /// - /// 生成一个随机的无符号 32 位整数。 - /// - /// 无符号 32 位整数。 - public static uint RandUInt32() - { - return (uint) Random.Next(); - } - - /// - /// 生成一个随机的无符号 16 位整数。 - /// - /// 无符号 16 位整数。 - public static ushort RandUInt16() - { - Random.NextBytes(Byte2); - return BitConverter.ToUInt16(Byte2, 0); - } - - /// - /// 在指定范围内生成一个随机整数(包含下限,不包含上限)。 - /// - /// 下限。 - /// 上限。 - /// 生成的随机整数。 - public static int RandomNumber(int lower, int upper) - { - return Random.Next(lower, upper); - } - - /// - /// 生成一个随机的布尔值。 - /// - /// 随机的布尔值。 - public static bool RandomBool() - { - return Random.Next(2) == 0; - } - - /// - /// 从数组中随机选择一个元素。 - /// - /// 数组元素的类型。 - /// 要选择的数组。 - /// 随机选择的数组元素。 - public static T RandomArray(this T[] array) - { - return array[RandomNumber(0, array.Count())]; - } - - /// - /// 从列表中随机选择一个元素。 - /// - /// 列表元素的类型。 - /// 要选择的列表。 - /// 随机选择的列表元素。 - public static T RandomArray(this List array) - { - return array[RandomNumber(0, array.Count())]; - } - - /// - /// 打乱列表中元素的顺序。 - /// - /// 列表元素的类型。 - /// 要打乱顺序的列表。 - public static void BreakRank(List arr) - { - if (arr == null || arr.Count < 2) - { - return; - } - - for (var i = 0; i < arr.Count / 2; i++) - { - var index = Random.Next(0, arr.Count); - (arr[index], arr[arr.Count - index - 1]) = (arr[arr.Count - index - 1], arr[index]); - } - } - - /// - /// 生成一个介于 0 和 1 之间的随机单精度浮点数。 - /// - /// 随机单精度浮点数。 - public static float RandFloat01() - { - var value = Random.NextDouble(); - return (float) value; - } - - private static int Rand(int n) - { - var rd = new Random(); - // 注意,返回值是左闭右开,所以maxValue要加1 - return rd.Next(1, n + 1); - } - - /// - /// 根据权重随机选择一个索引。 - /// - /// 权重数组,每个元素表示相应索引的权重。 - /// 随机选择的索引值。 - public static int RandomByWeight(int[] weights) - { - var sum = weights.Sum(); - var numberRand = Rand(sum); - var sumTemp = 0; - for (var i = 0; i < weights.Length; i++) - { - sumTemp += weights[i]; - if (numberRand <= sumTemp) - { - return i; - } - } - - return -1; - } - - /// - /// 根据固定概率随机选择一个索引,即某个数值上限内随机多少次。 - /// - /// 概率数组,每个元素表示相应索引的概率。 - /// 随机选择的索引值。 - public static int RandomByFixedProbability(int[] args) - { - var argCount = args.Length; - var sum = args.Sum(); - var random = Random.NextDouble() * sum; - while (sum > random) - { - sum -= args[argCount - 1]; - argCount--; - } - - return argCount; - } - - /// - /// 返回随机数。 - /// - /// 是否包含负数。 - /// 返回一个随机的单精度浮点数。 - public static float NextFloat(bool containNegative = false) - { - float f; - var buffer = new byte[4]; - if (containNegative) - { - do - { - Random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer, 0); - } while ((f >= float.MinValue && f < float.MaxValue) == false); - - return f; - } - - do - { - Random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer, 0); - } while ((f >= 0 && f < float.MaxValue) == false); - - return f; - } - - /// - /// 返回一个小于所指定最大值的非负随机数。 - /// - /// 要生成的随机数的上限(随机数不能取该上限值)。 maxValue 必须大于或等于零。 - /// 大于等于零且小于 maxValue 的单精度浮点数,即:返回值的范围通常包括零但不包括 maxValue。 不过,如果 maxValue 等于零,则返回 maxValue。 - public static float NextFloat(float maxValue) - { - if (maxValue.Equals(0)) - { - return maxValue; - } - - if (maxValue < 0) - { - throw new ArgumentOutOfRangeException("“maxValue”必须大于 0。", "maxValue"); - } - - float f; - var buffer = new byte[4]; - - do - { - Random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer, 0); - } while ((f >= 0 && f < maxValue) == false); - - return f; - } - - /// - /// 返回一个指定范围内的随机数。 - /// - /// 返回的随机数的下界(随机数可取该下界值)。 - /// 返回的随机数的上界(随机数不能取该上界值)。 maxValue 必须大于或等于 minValue。 - /// 一个大于等于 minValue 且小于 maxValue 的单精度浮点数,即:返回的值范围包括 minValue 但不包括 maxValue。 如果 minValue 等于 maxValue,则返回 minValue。 - public static float NextFloat(float minValue, float maxValue) - { - if (minValue.Equals(maxValue)) - { - return minValue; - } - - if (minValue > maxValue) - { - throw new ArgumentOutOfRangeException("“minValue”不能大于 maxValue。", "minValue"); - } - - float f; - var buffer = new byte[4]; - - do - { - Random.NextBytes(buffer); - f = BitConverter.ToSingle(buffer, 0); - } while ((f >= minValue && f < maxValue) == false); - - return f; - } - - /// - /// 在指定的矩形区域内随机生成一个二维向量位置。 - /// - /// X轴最小值。 - /// X轴最大值。 - /// Y轴最小值。 - /// Y轴最大值。 - /// 随机生成的二维向量位置。 - public static Vector2 NextVector2(float minX, float maxX, float minY, float maxY) - { - return new Vector2(NextFloat(minX, maxX), NextFloat(minY, maxY)); - } - - /// - /// 生成指定长度的随机数字代码。 - /// - /// 数字代码的长度。 - /// 生成的随机数字代码。 - public static string RandomNumberCode(int len = 6) - { - int num = 0; - for (int i = 0; i < len; i++) - { - int number = RandomNumber(0, 10); - num = num * 10 + number; - } - - return num.ToString(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/SocketHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/SocketHelper.cs deleted file mode 100644 index 15027c5..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/SocketHelper.cs +++ /dev/null @@ -1,74 +0,0 @@ -#if !FANTASY_WEBGL -using System.Net; -using System.Net.Sockets; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Helper -{ - /// - /// Socket帮助类 - /// - public static partial class SocketHelper - { - // always pass the same IPEndPointNonAlloc instead of allocating a new - // one each time. - // - // use IPEndPointNonAlloc.temp to get the latest SocketAdddress written - // by ReceiveFrom_Internal! - // - // IMPORTANT: .temp will be overwritten in next call! - // hash or manually copy it if you need to store it, e.g. - // when adding a new connection. - public static int ReceiveFrom_NonAlloc( - this Socket socket, - byte[] buffer, - int offset, - int size, - SocketFlags socketFlags, - EndPoint remoteEndPoint) - { - // call ReceiveFrom with IPEndPointNonAlloc. - // need to wrap this in ReceiveFrom_NonAlloc because it's not - // obvious that IPEndPointNonAlloc.Create does NOT create a new - // IPEndPoint. it saves the result in IPEndPointNonAlloc.temp! -#if FANTASY_UNITY - EndPoint casted = remoteEndPoint; - return socket.ReceiveFrom(buffer, offset, size, socketFlags, ref casted); -#else - return socket.ReceiveFrom(buffer, offset, size, socketFlags, ref remoteEndPoint); -#endif - } - - // same as above, different parameters - public static int ReceiveFrom_NonAlloc(this Socket socket, byte[] buffer, ref EndPoint remoteEndPoint) - { -#if UNITY - EndPoint casted = remoteEndPoint; - return socket.ReceiveFrom(buffer, ref casted); -#else - return socket.ReceiveFrom(buffer, ref remoteEndPoint); -#endif - - } - - // SendTo allocates too: - // https://github.com/mono/mono/blob/f74eed4b09790a0929889ad7fc2cf96c9b6e3757/mcs/class/System/System.Net.Sockets/Socket.cs#L2240 - // -> the allocation is in EndPoint.Serialize() - // NOTE: technically this function isn't necessary. - // could just pass IPEndPointNonAlloc. - // still good for strong typing. - //public static int SendTo_NonAlloc( - // this Socket socket, - // byte[] buffer, - // int offset, - // int size, - // SocketFlags socketFlags, - // IPEndPointNonAlloc remoteEndPoint) - //{ - // EndPoint casted = remoteEndPoint; - // return socket.SendTo(buffer, offset, size, socketFlags, casted); - //} - } -} -#endif - - diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/TimeHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/TimeHelper.cs deleted file mode 100644 index b0eb60a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/TimeHelper.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -#if FANTASY_UNITY -using UnityEngine; -#endif - -namespace Fantasy.Helper -{ - /// - /// 提供与时间相关的帮助方法。 - /// - public static partial class TimeHelper - { - /// - /// 一小时的毫秒值。 - /// - public const long Hour = 3600000; - /// - /// 一分钟的毫秒值。 - /// - public const long Minute = 60000; - /// - /// 一天的毫秒值。 - /// - public const long OneDay = 86400000; - // 1970年1月1日的Ticks - private const long Epoch = 621355968000000000L; - /// - /// 获取当前时间的毫秒数,从1970年1月1日开始计算。 - /// - public static long Now => (DateTime.UtcNow.Ticks - Epoch) / 10000; -#if FANTASY_UNITY || FANTASY_CONSOLE - /// - /// 与服务器时间的偏差。 - /// - public static long TimeDiff; - /// - /// 获取当前服务器时间的毫秒数,加上与服务器时间的偏差。 - /// - public static long ServerNow => Now + TimeDiff; -#if FANTASY_UNITY - /// - /// 获取当前Unity运行的总时间的毫秒数。 - /// - public static long UnityNow => (long) (Time.time * 1000); -#endif -#endif - /// - /// 根据时间获取时间戳 - /// - public static long Transition(DateTime dateTime) - { - return (dateTime.ToUniversalTime().Ticks - Epoch) / 10000; - } - - /// - /// 根据时间获取 时间戳 - /// - public static long TransitionToSeconds(DateTime dateTime) - { - return (dateTime.ToUniversalTime().Ticks - Epoch) / 10000000; - } - - /// - /// 将毫秒数转换为日期时间。 - /// - /// 要转换的毫秒数。 - /// 转换后的日期时间。 - public static DateTime Transition(this long timeStamp) - { - return new DateTime(Epoch + timeStamp * 10000, DateTimeKind.Utc).ToUniversalTime(); - } - - /// - /// 将毫秒数转换为本地时间的日期时间。 - /// - /// 要转换的毫秒数。 - /// 转换后的本地时间的日期时间。 - public static DateTime TransitionLocal(this long timeStamp) - { - return new DateTime(Epoch + timeStamp * 10000, DateTimeKind.Utc).ToLocalTime(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs deleted file mode 100644 index dbc0334..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs +++ /dev/null @@ -1,244 +0,0 @@ -#if FANTASY_UNITY -using System; -using Fantasy.Async; -using UnityEngine; -using UnityEngine.Networking; - -namespace Fantasy.Unity -{ - /// - /// UnityWebRequest的帮助类 - /// - public static class UnityWebRequestHelper - { - /// - /// 获取一个文本 - /// - /// - /// - /// - public static FTask GetText(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequest.Get(url); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var text = unityWebRequest.downloadHandler.text; - task.SetResult(text); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - - /// - /// 获取一个Sprite - /// - /// - /// - /// - public static FTask GetSprite(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequestTexture.GetTexture(Uri.EscapeUriString(url)); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var texture = DownloadHandlerTexture.GetContent(unityWebRequest); - var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 5, 1f); - task.SetResult(sprite); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - - /// - /// 获取一个Texture - /// - /// - /// - /// - public static FTask GetTexture(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequestTexture.GetTexture(Uri.EscapeUriString(url)); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var texture = DownloadHandlerTexture.GetContent(unityWebRequest); - task.SetResult(texture); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - - /// - /// 获取Bytes - /// - /// - /// - /// - public static FTask GetBytes(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequest.Get(url); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var bytes = unityWebRequest.downloadHandler.data; - task.SetResult(bytes); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - - /// - /// 获取AssetBundle - /// - /// - /// - /// - public static FTask GetAssetBundle(string url, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequestAssetBundle.GetAssetBundle(Uri.EscapeUriString(url)); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var assetBundle = DownloadHandlerAssetBundle.GetContent(unityWebRequest); - task.SetResult(assetBundle); - return; - } - - Log.Error(unityWebRequest.error); - task.SetResult(null); - }; - - return task; - } - - /// - /// 获取AudioClip - /// - /// - /// - /// - /// - public static FTask GetAudioClip(string url, AudioType audioType, FCancellationToken cancellationToken = null) - { - var task = FTask.Create(false); - var unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(Uri.EscapeUriString(url), audioType); - var unityWebRequestAsyncOperation = unityWebRequest.SendWebRequest(); - - if (cancellationToken != null) - { - cancellationToken.Add(() => - { - unityWebRequest.Abort(); - task.SetResult(null); - }); - } - - unityWebRequestAsyncOperation.completed += operation => - { - if (unityWebRequest.result == UnityWebRequest.Result.Success) - { - var audioClip = DownloadHandlerAudioClip.GetContent(unityWebRequest); - task.SetResult(audioClip); - } - else - { - Log.Error(unityWebRequest.error); - task.SetResult(null); - } - }; - - return task; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs.meta b/Fantasy/Fantays.Console/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs.meta deleted file mode 100644 index 53b7c3c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/UnityWebRequest/UnityWebRequestHelper.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 4a679bf05117455388666f6d8cc35d7d -timeCreated: 1726022012 \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/WebSocketHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/WebSocketHelper.cs deleted file mode 100644 index 822db06..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/WebSocketHelper.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace Fantasy.Helper -{ - /// - /// WebSocket帮助类 - /// - public static partial class WebSocketHelper - { - /// - /// 根据字符串获取WebSocket的连接地址 - /// - /// 目标服务器地址格式为:127.0.0.1:2000 - /// 目标服务器是否为加密连接也就是https - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string GetWebSocketAddress(string address, bool isHttps) - { - var addressSplit = address.Split(':'); - if (addressSplit.Length != 2) - { - throw new FormatException("Invalid format"); - } - - var ipString = addressSplit[0]; - var portString = addressSplit[1]; - - if (!int.TryParse(portString, out var port) || port < 0 || port > 65535) - { - throw new FormatException("Invalid port number"); - } - - return isHttps ? $"wss://{ipString}:{portString}" : $"ws://{ipString}:{portString}"; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Helper/WinPeriod.cs b/Fantasy/Fantays.Console/Runtime/Core/Helper/WinPeriod.cs deleted file mode 100644 index a1a5aca..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Helper/WinPeriod.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Fantasy.Helper -{ - /// - /// 精度设置 - /// - public static partial class WinPeriod - { - // 一般默认的精度不止1毫秒(不同操作系统有所不同),需要调用timeBeginPeriod与timeEndPeriod来设置精度 - [DllImport("winmm")] - private static extern void timeBeginPeriod(int t); - /// - /// 针对Windows平台设置精度 - /// - public static void Initialize() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - timeBeginPeriod(1); - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Default/EntityIdStruct.cs b/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Default/EntityIdStruct.cs deleted file mode 100644 index ef30b18..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Default/EntityIdStruct.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.IdFactory -{ - /// - /// 表示一个唯一实体的ID。 - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct EntityIdStruct - { - // EntityId:39 + 16 + 18 = 64 - // +-------------------+-----------------------------+------------------------------------+ - // | time(30) 最大34年 | SceneId(16) 最多65535个Scene | sequence(18) 每秒每个进程能生产262143个 - // +-------------------+-----------------------------+------------------------------------+ - public uint Time { get; set; } - public uint SceneId { get; set; } - public uint Sequence { get; set; } - - public const uint MaskSequence = 0x3FFFF; - public const uint MaskSceneId = 0xFFFF; - public const uint MaskTime = 0x3FFFFFFF; - - /// - /// WorldEntityIdStruct(如果超过下面参数的设定该ID会失效)。 - /// - /// time不能超过1073741823 - /// sceneId不能超过65535 - /// sequence不能超过262143 - public EntityIdStruct(uint time, uint sceneId, uint sequence) - { - // 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。 - Time = time; - SceneId = sceneId; - Sequence = sequence; - } - - public static implicit operator long(EntityIdStruct entityIdStruct) - { - ulong result = 0; - result |= entityIdStruct.Sequence; - result |= (ulong)entityIdStruct.SceneId << 18; - result |= (ulong)entityIdStruct.Time << 34; - return (long)result; - } - - public static implicit operator EntityIdStruct(long entityId) - { - var result = (ulong) entityId; - var entityIdStruct = new EntityIdStruct - { - Sequence = (uint)(result & MaskSequence) - }; - result >>= 18; - entityIdStruct.SceneId = (uint)(result & MaskSceneId); - result >>= 16; - entityIdStruct.Time = (uint)(result & MaskTime); - return entityIdStruct; - } - } - - public sealed class EntityIdFactory : IEntityIdFactory - { - private readonly ushort _sceneId; - - private uint _lastTime; - private uint _lastSequence; - private static readonly long Epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; - private static readonly long EpochThisYear = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000 - Epoch1970; - - private EntityIdFactory() { } - - public EntityIdFactory(uint sceneId) - { - switch (sceneId) - { - case > 65535: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255"); - } - default: - { - _sceneId = (ushort)sceneId; - break; - } - } - } - - public long Create - { - get - { - var time = (uint)((TimeHelper.Now - EpochThisYear) / 1000); - - if (time > _lastTime) - { - _lastTime = time; - _lastSequence = 0; - } - else if (++_lastSequence > EntityIdStruct.MaskSequence - 1) - { - _lastTime++; - _lastSequence = 0; - } - - return new EntityIdStruct(time, _sceneId, _lastSequence); - } - } - } - - public sealed class EntityIdFactoryTool : IIdFactoryTool - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetTime(ref long entityId) - { - var result = (ulong)entityId >> 34; - return (uint)(result & EntityIdStruct.MaskTime); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetSceneId(ref long entityId) - { - var result = (ulong)entityId >> 18; - return (uint)(result & EntityIdStruct.MaskSceneId); - } - - public byte GetWorldId(ref long entityId) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Default/RuntimeIdStruct.cs b/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Default/RuntimeIdStruct.cs deleted file mode 100644 index a5d5e10..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Default/RuntimeIdStruct.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.IdFactory -{ - /// - /// 表示一个运行时的ID。 - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct RuntimeIdStruct - { - // RuntimeId:23 + 8 + 8 + 25 = 64 - // +-------------------+-----------------------------+--------------------------------------+ - // | time(23) 最大60天 | SceneId(16) 最多65535个Scene | sequence(25) 每秒每个进程能生产33554431个 - // +-------------------+-----------------------------+--------------------------------------+ - public uint Time { get; private set; } - public uint SceneId { get; private set; } - public uint Sequence { get; private set; } - - public const uint MaskSequence = 0x1FFFFFF; - public const uint MaskSceneId = 0xFFFF; - public const uint MaskTime = 0x7FFFFF; - - /// - /// RuntimeIdStruct(如果超过下面参数的设定该ID会失效)。 - /// - /// time不能超过8388607 - /// sceneId不能超过65535 - /// sequence不能超过33554431 - public RuntimeIdStruct(uint time, uint sceneId, uint sequence) - { - // 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。 - Time = time; - SceneId = sceneId; - Sequence = sequence; - } - - public static implicit operator long(RuntimeIdStruct runtimeIdStruct) - { - ulong result = runtimeIdStruct.Sequence; - result |= (ulong)runtimeIdStruct.SceneId << 25; - result |= (ulong)runtimeIdStruct.Time << 41; - return (long)result; - } - - public static implicit operator RuntimeIdStruct(long runtimeId) - { - var result = (ulong)runtimeId; - var runtimeIdStruct = new RuntimeIdStruct - { - Sequence = (uint)(result & MaskSequence) - }; - result >>= 25; - runtimeIdStruct.SceneId = (byte)(result & MaskSceneId); - result >>= 16; - runtimeIdStruct.Time = (uint)(result & MaskTime); - return runtimeIdStruct; - } - } - - public sealed class RuntimeIdFactory : IRuntimeIdFactory - { - private readonly uint _sceneId; - - private uint _lastTime; - private uint _lastSequence; - private readonly long _epochNow; - private readonly long _epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; - - private RuntimeIdFactory() { } - - public RuntimeIdFactory(uint sceneId) : this(TimeHelper.Now, sceneId) { } - - public RuntimeIdFactory(long epochNow, uint sceneId) - { - switch (sceneId) - { - case > 65535: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255"); - } - default: - { - _sceneId = (ushort)sceneId; - _epochNow = epochNow - _epoch1970; - break; - } - } - } - - public long Create - { - get - { - var time = (uint)((TimeHelper.Now - _epochNow) / 1000); - - if (time > _lastTime) - { - _lastTime = time; - _lastSequence = 0; - } - else if (++_lastSequence > RuntimeIdStruct.MaskSequence - 1) - { - _lastTime++; - _lastSequence = 0; - } - - return new RuntimeIdStruct(time, _sceneId, _lastSequence); - } - } - } - - public sealed class RuntimeIdFactoryTool : IIdFactoryTool - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetTime(ref long runtimeId) - { - var result = (ulong)runtimeId >> 41; - return (uint)(result & RuntimeIdStruct.MaskTime); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetSceneId(ref long runtimeId) - { - var result = (ulong)runtimeId >> 25; - return (uint)(result & RuntimeIdStruct.MaskSceneId); - } - - public byte GetWorldId(ref long entityId) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/IdFactoryHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/IdFactory/IdFactoryHelper.cs deleted file mode 100644 index 4251d53..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/IdFactoryHelper.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using Fantasy.Helper; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -namespace Fantasy.IdFactory -{ - /// - /// Id生成器帮助类 - /// - public static class IdFactoryHelper - { - private static IdFactoryType _idFactoryType = IdFactoryType.World; - - /// - /// EntityId工具 - /// - public static IIdFactoryTool EntityIdTool { get; private set; } = new WorldEntityIdFactoryTool(); - - /// - /// RuntimeId工具 - /// - public static IIdFactoryTool RuntimeIdTool { get; private set; } = new WorldRuntimeIdFactoryTool(); - - /// - /// 初始化 - /// - /// - public static void Initialize(IdFactoryType idFactoryType) - { - _idFactoryType = idFactoryType; - - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - EntityIdTool = new EntityIdFactoryTool(); - RuntimeIdTool = new RuntimeIdFactoryTool(); - return; - } - case IdFactoryType.World: - { - EntityIdTool = new WorldEntityIdFactoryTool(); - RuntimeIdTool = new WorldRuntimeIdFactoryTool(); - return; - } - } - } - - internal static IEntityIdFactory EntityIdFactory(uint sceneId, byte worldId) - { - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - return new EntityIdFactory(sceneId); - } - case IdFactoryType.World: - { - return new WorldEntityIdFactory(sceneId, worldId); - } - default: - { - throw new NotSupportedException($"IdFactoryType {_idFactoryType} is not supported."); - } - } - } - - internal static IRuntimeIdFactory RuntimeIdFactory(long epochNow, uint sceneId, byte worldId) - { - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - return new RuntimeIdFactory(sceneId); - } - case IdFactoryType.World: - { - if (epochNow == 0) - { - epochNow = TimeHelper.Now; - } - - return new WorldRuntimeIdFactory(epochNow, sceneId, worldId); - } - default: - { - throw new NotSupportedException($"IdFactoryType {_idFactoryType} is not supported."); - } - } - } - - internal static long EntityId(uint time, uint sceneId, byte wordId, uint sequence) - { - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - return new EntityIdStruct(time, sceneId, sequence); - } - case IdFactoryType.World: - { - return new WorldEntityIdStruct(time, sceneId, wordId, sequence); - } - default: - { - throw new NotSupportedException($"IdFactoryType {_idFactoryType} is not supported."); - } - } - } - - internal static long RuntimeId(uint time, uint sceneId, byte wordId, uint sequence) - { - switch (_idFactoryType) - { - case IdFactoryType.Default: - { - return new RuntimeIdStruct(time, sceneId, sequence); - } - case IdFactoryType.World: - { - return new WorldRuntimeIdStruct(time, sceneId, wordId, sequence); - } - default: - { - throw new NotSupportedException($"IdFactoryType {_idFactoryType} is not supported."); - } - } - } - } -} - diff --git a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/IdFactoryType.cs b/Fantasy/Fantays.Console/Runtime/Core/IdFactory/IdFactoryType.cs deleted file mode 100644 index d465b5b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/IdFactoryType.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Fantasy.IdFactory -{ - /// - /// ID生成器规则 - /// - public enum IdFactoryType - { - /// - /// 空。 - /// - None = 0, - /// - /// 默认生成器 - /// Scene最大为65535个。 - /// - Default = 1, - /// - /// ID中包含World,使用这种方式可以不用管理合区的ID重复的问题。 - /// 但Scene的数量也会限制到255个。 - /// - World = 2 - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Interface/IIdFactory.cs b/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Interface/IIdFactory.cs deleted file mode 100644 index d71c15b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Interface/IIdFactory.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Fantasy.IdFactory -{ - /// - /// EntityId生成器接口类 - /// - public interface IEntityIdFactory - { - /// - /// 创建一个新的Id - /// - public long Create { get; } - } - - /// - /// RuntimeId生成器接口类 - /// - public interface IRuntimeIdFactory - { - /// - /// 创建一个新的Id - /// - public long Create { get; } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Interface/IIdFactoryTool.cs b/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Interface/IIdFactoryTool.cs deleted file mode 100644 index 8dd1e99..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/Interface/IIdFactoryTool.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Fantasy.IdFactory -{ - /// - /// Id扩展工具接口 - /// - public interface IIdFactoryTool - { - /// - /// 获得创建时间 - /// - /// - /// - public uint GetTime(ref long entityId); - /// - /// 获得SceneId - /// - /// - /// - public uint GetSceneId(ref long entityId); - /// - /// 获得WorldId - /// - /// - /// - public byte GetWorldId(ref long entityId); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/World/WorldEntityIdFactory.cs b/Fantasy/Fantays.Console/Runtime/Core/IdFactory/World/WorldEntityIdFactory.cs deleted file mode 100644 index dbba88f..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/World/WorldEntityIdFactory.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.IdFactory -{ - /// - /// 表示一个唯一实体的ID。 - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct WorldEntityIdStruct - { - // EntityId:39 + 8 + 8 + 18 = 64 - // +-------------------+--------------------------+-----------------------+------------------------------------+ - // | time(30) 最大34年 | SceneId(8) 最多255个Scene | WordId(8) 最多255个世界 | sequence(18) 每秒每个进程能生产262143个 - // +-------------------+--------------------------+-----------------------+------------------------------------+ - public uint Time { get; private set; } - public uint SceneId { get; private set; } - public byte WordId { get; private set; } - public uint Sequence { get; private set; } - - public const uint MaskSequence = 0x3FFFF; - public const uint MaskSceneId = 0xFF; - public const uint MaskWordId = 0xFF; - public const uint MaskTime = 0x3FFFFFFF; - - /// - /// WorldEntityIdStruct(如果超过下面参数的设定该ID会失效)。 - /// - /// time不能超过1073741823 - /// sceneId不能超过255 - /// wordId不能超过255 - /// sequence不能超过262143 - public WorldEntityIdStruct(uint time, uint sceneId, byte wordId, uint sequence) - { - // 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。 - Time = time; - SceneId = sceneId; - WordId = wordId; - Sequence = sequence; - } - - public static implicit operator long(WorldEntityIdStruct entityIdStruct) - { - ulong result = 0; - result |= entityIdStruct.Sequence; - result |= (ulong)entityIdStruct.WordId << 18; - result |= (ulong)(entityIdStruct.SceneId % (entityIdStruct.WordId * 1000)) << 26; - result |= (ulong)entityIdStruct.Time << 34; - return (long)result; - } - - public static implicit operator WorldEntityIdStruct(long entityId) - { - var result = (ulong) entityId; - var entityIdStruct = new WorldEntityIdStruct - { - Sequence = (uint)(result & MaskSequence) - }; - result >>= 18; - entityIdStruct.WordId = (byte)(result & MaskWordId); - result >>= 8; - entityIdStruct.SceneId = (uint)(result & MaskSceneId) + (uint)entityIdStruct.WordId * 1000; - result >>= 8; - entityIdStruct.Time = (uint)(result & MaskTime); - return entityIdStruct; - } - } - - public sealed class WorldEntityIdFactory : IEntityIdFactory - { - private readonly uint _sceneId; - private readonly byte _worldId; - - private uint _lastTime; - private uint _lastSequence; - private static readonly long Epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; - private static readonly long EpochThisYear = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000 - Epoch1970; - - private WorldEntityIdFactory() { } - - public WorldEntityIdFactory(uint sceneId, byte worldId) - { - switch (sceneId) - { - case > 255255: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255"); - } - case < 1001: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be less than 1001"); - } - default: - { - _sceneId = sceneId; - _worldId = worldId; - break; - } - } - } - - public long Create - { - get - { - var time = (uint)((TimeHelper.Now - EpochThisYear) / 1000); - - if (time > _lastTime) - { - _lastTime = time; - _lastSequence = 0; - } - else if (++_lastSequence > WorldEntityIdStruct.MaskSequence - 1) - { - _lastTime++; - _lastSequence = 0; - } - - return new WorldEntityIdStruct(time, _sceneId, _worldId, _lastSequence); - } - } - } - - public sealed class WorldEntityIdFactoryTool : IIdFactoryTool - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetTime(ref long entityId) - { - var result = (ulong)entityId >> 34; - return (uint)(result & WorldEntityIdStruct.MaskTime); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetSceneId(ref long entityId) - { - var result = (ulong)entityId >> 18; - var worldId = (uint)(result & WorldEntityIdStruct.MaskWordId) * 1000; - result >>= 8; - return (uint)(result & WorldEntityIdStruct.MaskSceneId) + worldId; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public byte GetWorldId(ref long entityId) - { - var result = (ulong)entityId >> 18; - return (byte)(result & WorldEntityIdStruct.MaskWordId); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/World/WorldRuntimeIdFactory.cs b/Fantasy/Fantays.Console/Runtime/Core/IdFactory/World/WorldRuntimeIdFactory.cs deleted file mode 100644 index a5d582b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/IdFactory/World/WorldRuntimeIdFactory.cs +++ /dev/null @@ -1,155 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.IdFactory -{ - /// - /// 表示一个运行时的ID。 - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct WorldRuntimeIdStruct - { - // RuntimeId:23 + 8 + 8 + 25 = 64 - // +-------------------+--------------------------+-----------------------+--------------------------------------+ - // | time(23) 最大60天 | SceneId(8) 最多255个Scene | WordId(8) 最多255个世界 | sequence(25) 每秒每个进程能生产33554431个 - // +-------------------+--------------------------+-----------------------+--------------------------------------+ - public uint Time { get; private set; } - public uint SceneId { get; private set; } - public byte WordId { get; private set; } - public uint Sequence { get; private set; } - - public const uint MaskSequence = 0x1FFFFFF; - public const uint MaskSceneId = 0xFF; - public const uint MaskWordId = 0xFF; - public const uint MaskTime = 0x7FFFFF; - - /// - /// WorldRuntimeIdStruct(如果超过下面参数的设定该ID会失效)。 - /// - /// time不能超过8388607 - /// sceneId不能超过255 - /// wordId不能超过255 - /// sequence不能超过33554431 - public WorldRuntimeIdStruct(uint time, uint sceneId, byte wordId, uint sequence) - { - // 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。 - Time = time; - SceneId = sceneId; - WordId = wordId; - Sequence = sequence; - } - - public static implicit operator long(WorldRuntimeIdStruct runtimeIdStruct) - { - ulong result = runtimeIdStruct.Sequence; - result |= (ulong)runtimeIdStruct.WordId << 25; - result |= (ulong)(runtimeIdStruct.SceneId % (runtimeIdStruct.WordId * 1000)) << 33; - result |= (ulong)runtimeIdStruct.Time << 41; - return (long)result; - } - - public static implicit operator WorldRuntimeIdStruct(long runtimeId) - { - var result = (ulong)runtimeId; - var runtimeIdStruct = new WorldRuntimeIdStruct - { - Sequence = (uint)(result & MaskSequence) - }; - result >>= 25; - runtimeIdStruct.WordId = (byte)(result & MaskWordId); - result >>= 8; - runtimeIdStruct.SceneId = (uint)(result & MaskSceneId) + (uint)runtimeIdStruct.WordId * 1000; - result >>= 8; - runtimeIdStruct.Time = (uint)(result & MaskTime); - return runtimeIdStruct; - } - } - - public sealed class WorldRuntimeIdFactory : IRuntimeIdFactory - { - private readonly uint _sceneId; - private readonly byte _worldId; - - private uint _lastTime; - private uint _lastSequence; - private readonly long _epochNow; - private readonly long _epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; - - private WorldRuntimeIdFactory() { } - - public WorldRuntimeIdFactory(uint sceneId, byte worldId) : this(TimeHelper.Now, sceneId, worldId) { } - - public WorldRuntimeIdFactory(long epochNow, uint sceneId, byte worldId) - { - switch (sceneId) - { - case > 255255: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255"); - } - case < 1001: - { - throw new NotSupportedException($"sceneId:{sceneId} cannot be less than 1001"); - } - default: - { - _sceneId = sceneId; - _worldId = worldId; - _epochNow = epochNow - _epoch1970; - break; - } - } - } - - public long Create - { - get - { - var time = (uint)((TimeHelper.Now - _epochNow) / 1000); - - if (time > _lastTime) - { - _lastTime = time; - _lastSequence = 0; - } - else if (++_lastSequence > WorldRuntimeIdStruct.MaskSequence - 1) - { - _lastTime++; - _lastSequence = 0; - } - - return new WorldRuntimeIdStruct(time, _sceneId, _worldId, _lastSequence); - } - } - } - - public sealed class WorldRuntimeIdFactoryTool : IIdFactoryTool - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetTime(ref long runtimeId) - { - var result = (ulong)runtimeId >> 41; - return (uint)(result & WorldRuntimeIdStruct.MaskTime); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetSceneId(ref long runtimeId) - { - var result = (ulong)runtimeId >> 25; - var worldId = (uint)(result & WorldRuntimeIdStruct.MaskWordId) * 1000; - result >>= 8; - return (uint)(result & WorldRuntimeIdStruct.MaskSceneId) + worldId; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public byte GetWorldId(ref long runtimeId) - { - var result = (ulong)runtimeId >> 25; - return (byte)(result & WorldRuntimeIdStruct.MaskWordId); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/InnerErrorCode.cs b/Fantasy/Fantays.Console/Runtime/Core/InnerErrorCode.cs deleted file mode 100644 index e549a22..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/InnerErrorCode.cs +++ /dev/null @@ -1,66 +0,0 @@ -namespace Fantasy.Network -{ - /// - /// 定义 Fantasy 框架中的内部错误代码。 - /// - public class InnerErrorCode - { - private InnerErrorCode() { } - /// - /// 表示 Rpc 消息发送失败的错误代码。 - /// - public const uint ErrRpcFail = 100000002; - /// - /// 表示未找到 Route 消息的错误代码。 - /// - public const uint ErrNotFoundRoute = 100000003; - /// - /// 表示发送 Route 消息超时的错误代码。 - /// - public const uint ErrRouteTimeout = 100000004; - /// - /// 表示未找到实体的错误代码。 - /// - public const uint ErrEntityNotFound = 100000008; - /// - /// 表示传送过程中发生错误的错误代码。 - /// - public const uint ErrTransfer = 100000009; - /// - /// 表示连接Roaming时候已经存在同RoamingType的Roaming了。 - /// - public const uint ErrLinkRoamingAlreadyExists = 100000009; - /// - /// 表示连接Roaming时候在漫游终端已经存在同Id的终端。 - /// - public const uint ErrAddRoamingTerminalAlreadyExists = 100000010; - /// - /// 表示未找到 Roaming 消息的错误代码。 - /// - public const uint ErrNotFoundRoaming = 100000011; - /// - /// 表示发送 Roaming 消息超时的错误代码。 - /// - public const uint ErrRoamingTimeout = 100000012; - /// - /// 表示再锁定 Roaming 消息的时候没有找到对应的Session错误代码。 - /// - public const uint ErrLockTerminusIdNotFoundSession = 100000013; - /// - /// 表示再锁定 Roaming 消息的时候没有找到对应的RoamingType错误代码。 - /// - public const uint ErrLockTerminusIdNotFoundRoamingType = 100000014; - /// - /// 表示再解除锁定 Roaming 消息的时候没有找到对应的Session错误代码。 - /// - public const uint ErrUnLockTerminusIdNotFoundSession = 100000015; - /// - /// 表示再解除锁定 Roaming 消息的时候没有找到对应的RoamingType错误代码。 - /// - public const uint ErrUnLockTerminusIdNotFoundRoamingType = 100000016; - /// - /// 表示再传送 Terminus 时对应的错误代码。 - /// - public const uint ErrTerminusStartTransfer = 100000017; - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Log/ConsoleLog.cs b/Fantasy/Fantays.Console/Runtime/Core/Log/ConsoleLog.cs deleted file mode 100644 index 0d57e22..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Log/ConsoleLog.cs +++ /dev/null @@ -1,144 +0,0 @@ -#if FANTASY_NET -using Fantasy.Platform.Net; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy; - -/// -/// 标准的控制台Log -/// -public sealed class ConsoleLog : ILog -{ - /// - /// 初始化方法 - /// - /// - public void Initialize(ProcessMode processMode) { } - - /// - /// 记录跟踪级别的日志消息。 - /// - /// 日志消息。 - public void Trace(string message) - { - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(message); - } - - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - public void Warning(string message) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine(message); - } - - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - public void Info(string message) - { - Console.ForegroundColor = ConsoleColor.Gray; - Console.WriteLine(message); - } - - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - public void Debug(string message) - { - Console.ForegroundColor = ConsoleColor.DarkGreen; - Console.WriteLine(message); - } - - /// - /// 记录错误级别的日志消息。 - /// - /// 日志消息。 - public void Error(string message) - { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.WriteLine(message); - } - - /// - /// 记录严重错误级别的日志消息。 - /// - /// 日志消息。 - public void Fatal(string message) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(message); - } - - /// - /// 记录跟踪级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Trace(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(message, args); - } - - /// - /// 记录警告级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Warning(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine(message, args); - } - - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Info(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.Gray; - Console.WriteLine(message, args); - } - - /// - /// 记录调试级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Debug(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.DarkGreen; - Console.WriteLine(message, args); - } - - /// - /// 记录错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Error(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.WriteLine(message, args); - } - - /// - /// 记录严重错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public void Fatal(string message, params object[] args) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(message, args); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Log/ILog.cs b/Fantasy/Fantays.Console/Runtime/Core/Log/ILog.cs deleted file mode 100644 index b01e857..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Log/ILog.cs +++ /dev/null @@ -1,74 +0,0 @@ -#if FANTASY_NET -using Fantasy.Platform.Net; -#endif -namespace Fantasy -{ - /// - /// 定义日志记录功能的接口。 - /// - public interface ILog - { -#if FANTASY_NET - /// - /// 初始化 - /// - /// - void Initialize(ProcessMode processMode); -#endif - /// - /// 记录跟踪级别的日志消息。 - /// - /// 日志消息。 - void Trace(string message); - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - void Warning(string message); - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - void Info(string message); - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - void Debug(string message); - /// - /// 记录错误级别的日志消息。 - /// - /// 日志消息。 - void Error(string message); - /// - /// 记录跟踪级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Trace(string message, params object[] args); - /// - /// 记录警告级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Warning(string message, params object[] args); - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Info(string message, params object[] args); - /// - /// 记录调试级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Debug(string message, params object[] args); - /// - /// 记录错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Error(string message, params object[] args); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Log/Log.cs b/Fantasy/Fantays.Console/Runtime/Core/Log/Log.cs deleted file mode 100644 index 8069fff..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Log/Log.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Diagnostics; -#if FANTASY_NET -using Fantasy.Platform.Net; -#endif - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy -{ - /// - /// 提供日志记录功能的静态类。 - /// - public static class Log - { - private static ILog _logCore; - private static bool _isRegister; -#if FANTASY_NET - /// - /// 初始化Log系统 - /// - public static void Initialize() - { - if (!_isRegister) - { - Register(new ConsoleLog()); - return; - } - - var processMode = ProcessMode.None; - - switch (ProcessDefine.Options.Mode) - { - case "Develop": - { - processMode = ProcessMode.Develop; - break; - } - case "Release": - { - processMode = ProcessMode.Release; - break; - } - } - - _logCore.Initialize(processMode); - } -#endif - /// - /// 注册一个日志系统 - /// - /// - public static void Register(ILog log) - { - if (_isRegister) - { - return; - } - - _logCore = log; - _isRegister = true; - } - - /// - /// 记录跟踪级别的日志消息。 - /// - /// 日志消息。 - public static void Trace(string msg) - { - var st = new StackTrace(1, true); - _logCore.Trace($"{msg}\n{st}"); - } - - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - public static void Debug(string msg) - { - _logCore.Debug(msg); - } - - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - public static void Info(string msg) - { - _logCore.Info(msg); - } - - /// - /// 记录跟踪级别的日志消息,并附带调用栈信息。 - /// - /// 日志消息。 - public static void TraceInfo(string msg) - { - var st = new StackTrace(1, true); - _logCore.Trace($"{msg}\n{st}"); - } - - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - public static void Warning(string msg) - { - _logCore.Warning(msg); - } - - /// - /// 记录错误级别的日志消息,并附带调用栈信息。 - /// - /// 日志消息。 - public static void Error(string msg) - { - var st = new StackTrace(1, true); - _logCore.Error($"{msg}\n{st}"); - } - - /// - /// 记录异常的错误级别的日志消息,并附带调用栈信息。 - /// - /// 异常对象。 - public static void Error(Exception e) - { - if (e.Data.Contains("StackTrace")) - { - _logCore.Error($"{e.Data["StackTrace"]}\n{e}"); - return; - } - var str = e.ToString(); - _logCore.Error(str); - } - - /// - /// 记录跟踪级别的格式化日志消息,并附带调用栈信息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Trace(string message, params object[] args) - { - var st = new StackTrace(1, true); - _logCore.Trace($"{string.Format(message, args)}\n{st}"); - } - - /// - /// 记录警告级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Warning(string message, params object[] args) - { - _logCore.Warning(string.Format(message, args)); - } - - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Info(string message, params object[] args) - { - _logCore.Info(string.Format(message, args)); - } - - /// - /// 记录调试级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Debug(string message, params object[] args) - { - _logCore.Debug(string.Format(message, args)); - } - - /// - /// 记录错误级别的格式化日志消息,并附带调用栈信息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Error(string message, params object[] args) - { - var st = new StackTrace(1, true); - var s = string.Format(message, args) + '\n' + st; - _logCore.Error(s); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Log/UnityLog.cs b/Fantasy/Fantays.Console/Runtime/Core/Log/UnityLog.cs deleted file mode 100644 index df95444..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Log/UnityLog.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Collections.Generic; -#if UNITY_EDITOR -using System; -using System.Reflection; -using System.Text.RegularExpressions; -using UnityEditor; -using UnityEditor.Callbacks; -using UnityEditorInternal; -#else -using System; -#endif - -#if FANTASY_UNITY -namespace Fantasy -{ - public class UnityLog : ILog - { - public void Trace(string msg) - { - UnityEngine.Debug.Log(msg); - } - - public void Debug(string msg) - { - UnityEngine.Debug.Log(msg); - } - - public void Info(string msg) - { - UnityEngine.Debug.Log(msg); - } - - public void Warning(string msg) - { - UnityEngine.Debug.LogWarning(msg); - } - - public void Error(string msg) - { - UnityEngine.Debug.LogError(msg); - } - - public void Error(Exception e) - { - UnityEngine.Debug.LogException(e); - } - - public void Trace(string message, params object[] args) - { - UnityEngine.Debug.LogFormat(message, args); - } - - public void Warning(string message, params object[] args) - { - UnityEngine.Debug.LogWarningFormat(message, args); - } - - public void Info(string message, params object[] args) - { - UnityEngine.Debug.LogFormat(message, args); - } - - public void Debug(string message, params object[] args) - { - UnityEngine.Debug.LogFormat(message, args); - } - - public void Error(string message, params object[] args) - { - UnityEngine.Debug.LogErrorFormat(message, args); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/LowLevel/FantasyMemory.cs b/Fantasy/Fantays.Console/Runtime/Core/LowLevel/FantasyMemory.cs deleted file mode 100644 index cadfd16..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/LowLevel/FantasyMemory.cs +++ /dev/null @@ -1,267 +0,0 @@ -#if FANTASY_NET -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using mimalloc; -#if NET7_0_OR_GREATER -using System.Runtime.Intrinsics; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#endif - -namespace Fantasy.LowLevel -{ - public static unsafe class FantasyMemory - { - private static delegate* managed _alloc; - private static delegate* managed _allocZeroed; - private static delegate* managed _free; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Initialize() - { - // KCP 使用 FantasyMemory - kcp.KCP.ikcp_allocator(&Alloc, &Free); - - try - { - _ = MiMalloc.mi_version(); - } - catch - { - Log.Info("mimalloc的二进制文件丢失"); - return; - } - - try - { - var ptr = MiMalloc.mi_malloc(MiMalloc.MI_SMALL_SIZE_MAX); - MiMalloc.mi_free(ptr); - } - catch - { - Log.Info("mimalloc权限不足,\r\n可能的问题:\r\n1. 禁止了虚拟内存分配 -> 允许虚拟内存分配;\r\n2. 没有硬盘读写权限 -> 管理员获取所有权限"); - return; - } - - Custom(&MiAlloc, &MiAllocZeroed, &MiFree); - - return; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static void* MiAlloc(nuint size) => MiMalloc.mi_malloc(size); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static void* MiAllocZeroed(nuint size) - { - var ptr = MiAlloc(size); - Unsafe.InitBlockUnaligned(ptr, 0, (uint)size); - return ptr; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static void MiFree(void* ptr) => MiMalloc.mi_free(ptr); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Custom(delegate* alloc, delegate* allocZeroed, delegate* free) - { - _alloc = alloc; - _allocZeroed = allocZeroed; - _free = free; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint Align(nuint size) => AlignUp(size, (nuint)sizeof(nint)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint AlignUp(nuint size, nuint alignment) => (size + (alignment - 1)) & ~(alignment - 1); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint AlignDown(nuint size, nuint alignment) => size - (size & (alignment - 1)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void* Alloc(nuint byteCount) - { - if (_alloc != null) - return _alloc(byteCount); -#if NET6_0_OR_GREATER - return NativeMemory.Alloc(byteCount); -#else - return (void*)Marshal.AllocHGlobal((nint)byteCount); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void* AllocZeroed(nuint byteCount) - { - if (_allocZeroed != null) - return _allocZeroed(byteCount); - void* ptr; - if (_alloc != null) - { - ptr = _alloc(byteCount); - Unsafe.InitBlockUnaligned(ptr, 0, (uint)byteCount); - return ptr; - } -#if NET6_0_OR_GREATER - return NativeMemory.AllocZeroed(byteCount, 1); -#else - ptr = (void*)Marshal.AllocHGlobal((nint)byteCount); - Unsafe.InitBlockUnaligned(ptr, 0, (uint)byteCount); - return ptr; -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Free(void* ptr) - { - if (_free != null) - { - _free(ptr); - return; - } -#if NET6_0_OR_GREATER - NativeMemory.Free(ptr); -#else - Marshal.FreeHGlobal((nint)ptr); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Copy(void* destination, void* source, nuint byteCount) => Unsafe.CopyBlockUnaligned(destination, source, (uint)byteCount); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Move(void* destination, void* source, nuint byteCount) => Buffer.MemoryCopy(source, destination, byteCount, byteCount); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Set(void* startAddress, byte value, nuint byteCount) => Unsafe.InitBlockUnaligned(startAddress, value, (uint)byteCount); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool Compare(void* left, void* right, nuint byteCount) - { - ref var first = ref *(byte*)left; - ref var second = ref *(byte*)right; - if (byteCount >= (nuint)sizeof(nuint)) - { - if (!Unsafe.AreSame(ref first, ref second)) - { -#if NET7_0_OR_GREATER - if (Vector128.IsHardwareAccelerated) - { -#if NET8_0_OR_GREATER - if (Vector512.IsHardwareAccelerated && byteCount >= (nuint)Vector512.Count) - { - nuint offset = 0; - var lengthToExamine = byteCount - (nuint)Vector512.Count; - if (lengthToExamine != 0) - { - do - { - if (Vector512.LoadUnsafe(ref first, offset) != Vector512.LoadUnsafe(ref second, offset)) - return false; - offset += (nuint)Vector512.Count; - } while (lengthToExamine > offset); - } - return Vector512.LoadUnsafe(ref first, lengthToExamine) == Vector512.LoadUnsafe(ref second, lengthToExamine); - } -#endif - if (Vector256.IsHardwareAccelerated && byteCount >= (nuint)Vector256.Count) - { - nuint offset = 0; - var lengthToExamine = byteCount - (nuint)Vector256.Count; - if (lengthToExamine != 0) - { - do - { - if (Vector256.LoadUnsafe(ref first, offset) != Vector256.LoadUnsafe(ref second, offset)) - return false; - offset += (nuint)Vector256.Count; - } while (lengthToExamine > offset); - } - return Vector256.LoadUnsafe(ref first, lengthToExamine) == Vector256.LoadUnsafe(ref second, lengthToExamine); - } - if (byteCount >= (nuint)Vector128.Count) - { - nuint offset = 0; - var lengthToExamine = byteCount - (nuint)Vector128.Count; - if (lengthToExamine != 0) - { - do - { - if (Vector128.LoadUnsafe(ref first, offset) != Vector128.LoadUnsafe(ref second, offset)) - return false; - offset += (nuint)Vector128.Count; - } while (lengthToExamine > offset); - } - return Vector128.LoadUnsafe(ref first, lengthToExamine) == Vector128.LoadUnsafe(ref second, lengthToExamine); - } - } - if (sizeof(nint) == 8 && Vector128.IsHardwareAccelerated) - { - var offset = byteCount - (nuint)sizeof(nuint); - var differentBits = Unsafe.ReadUnaligned(ref first) - Unsafe.ReadUnaligned(ref second); - differentBits |= Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, offset)) - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, offset)); - return differentBits == 0; - } - else -#endif - { - nuint offset = 0; - var lengthToExamine = byteCount - (nuint)sizeof(nuint); - if (lengthToExamine > 0) - { - do - { -#if NET7_0_OR_GREATER - if (Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, offset)) != Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, offset))) -#else - if (Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, (nint)offset)) != Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, (nint)offset))) -#endif - return false; - offset += (nuint)sizeof(nuint); - } while (lengthToExamine > offset); - } -#if NET7_0_OR_GREATER - return Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, lengthToExamine)) == Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, lengthToExamine)); -#else - return Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, (nint)lengthToExamine)) == Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, (nint)lengthToExamine)); -#endif - } - } - - return true; - } - - if (byteCount < sizeof(uint) || sizeof(nint) != 8) - { - uint differentBits = 0; - var offset = byteCount & 2; - if (offset != 0) - { - differentBits = Unsafe.ReadUnaligned(ref first); - differentBits -= Unsafe.ReadUnaligned(ref second); - } - - if ((byteCount & 1) != 0) -#if NET7_0_OR_GREATER - differentBits |= Unsafe.AddByteOffset(ref first, offset) - (uint)Unsafe.AddByteOffset(ref second, offset); -#else - differentBits |= Unsafe.AddByteOffset(ref first, (nint)offset) - (uint)Unsafe.AddByteOffset(ref second, (nint)offset); -#endif - return differentBits == 0; - } - else - { - var offset = byteCount - sizeof(uint); - var differentBits = Unsafe.ReadUnaligned(ref first) - Unsafe.ReadUnaligned(ref second); -#if NET7_0_OR_GREATER - differentBits |= Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, offset)) - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, offset)); -#else - differentBits |= Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, (nint)offset)) - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, (nint)offset)); -#endif - return differentBits == 0; - } - } - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/LowLevel/FixedBytes.cs b/Fantasy/Fantays.Console/Runtime/Core/LowLevel/FixedBytes.cs deleted file mode 100644 index 7c5a7a4..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/LowLevel/FixedBytes.cs +++ /dev/null @@ -1,107 +0,0 @@ -#if FANTASY_NET || !FANTASY_WEBGL -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.LowLevel -{ - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes1 - { - private byte _e0; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes2 - { - private FixedBytes1 _e0; - private FixedBytes1 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes4 - { - private FixedBytes2 _e0; - private FixedBytes2 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes8 - { - private FixedBytes4 _e0; - private FixedBytes4 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes16 - { - private FixedBytes8 _e0; - private FixedBytes8 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes32 - { - private FixedBytes16 _e0; - private FixedBytes16 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes64 - { - private FixedBytes32 _e0; - private FixedBytes32 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes128 - { - private FixedBytes64 _e0; - private FixedBytes64 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes256 - { - private FixedBytes128 _e0; - private FixedBytes128 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes512 - { - private FixedBytes256 _e0; - private FixedBytes256 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } - - [StructLayout(LayoutKind.Sequential)] - public struct FixedBytes1024 - { - private FixedBytes512 _e0; - private FixedBytes512 _e1; - - public Span AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Unsafe.SizeOf()); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/LowLevel/XxHash.cs b/Fantasy/Fantays.Console/Runtime/Core/LowLevel/XxHash.cs deleted file mode 100644 index dff36b3..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/LowLevel/XxHash.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -#pragma warning disable CS1591 - -namespace Fantasy.LowLevel -{ - public static class XxHash - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Hash32(string obj, uint seed = 0) => Hash32(obj.AsSpan(), seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Hash32(in T obj, uint seed = 0) where T : unmanaged => Hash32(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref Unsafe.AsRef(in obj)), Unsafe.SizeOf()), seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Hash32(ReadOnlySpan buffer, uint seed = 0) where T : unmanaged => Hash32(MemoryMarshal.Cast(buffer), seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Hash32(ReadOnlySpan buffer, uint seed = 0) - { - int length = buffer.Length; - ref byte local1 = ref MemoryMarshal.GetReference(buffer); - uint num1; - if (buffer.Length >= 16) - { - uint num2 = seed + 606290984U; - uint num3 = seed + 2246822519U; - uint num4 = seed; - uint num5 = seed - 2654435761U; - for (; length >= 16; length -= 16) - { - const nint elementOffset1 = 4; - const nint elementOffset2 = 8; - const nint elementOffset3 = 12; - nint byteOffset = buffer.Length - length; - ref byte local2 = ref Unsafe.AddByteOffset(ref local1, byteOffset); - uint num6 = num2 + Unsafe.ReadUnaligned(ref local2) * 2246822519U; - num2 = (uint)((((int)num6 << 13) | (int)(num6 >> 19)) * -1640531535); - uint num7 = num3 + Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, elementOffset1)) * 2246822519U; - num3 = (uint)((((int)num7 << 13) | (int)(num7 >> 19)) * -1640531535); - uint num8 = num4 + Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, elementOffset2)) * 2246822519U; - num4 = (uint)((((int)num8 << 13) | (int)(num8 >> 19)) * -1640531535); - uint num9 = num5 + Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, elementOffset3)) * 2246822519U; - num5 = (uint)((((int)num9 << 13) | (int)(num9 >> 19)) * -1640531535); - } - - num1 = (uint)((((int)num2 << 1) | (int)(num2 >> 31)) + (((int)num3 << 7) | (int)(num3 >> 25)) + (((int)num4 << 12) | (int)(num4 >> 20)) + (((int)num5 << 18) | (int)(num5 >> 14)) + buffer.Length); - } - else - num1 = (uint)((int)seed + 374761393 + buffer.Length); - - for (; length >= 4; length -= 4) - { - nint byteOffset = buffer.Length - length; - uint num10 = Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local1, byteOffset)); - uint num11 = num1 + num10 * 3266489917U; - num1 = (uint)((((int)num11 << 17) | (int)(num11 >> 15)) * 668265263); - } - - nint byteOffset1 = buffer.Length - length; - ref byte local3 = ref Unsafe.AddByteOffset(ref local1, byteOffset1); - for (int index = 0; index < length; ++index) - { - nint byteOffset2 = index; - uint num12 = Unsafe.AddByteOffset(ref local3, byteOffset2); - uint num13 = num1 + num12 * 374761393U; - num1 = (uint)((((int)num13 << 11) | (int)(num13 >> 21)) * -1640531535); - } - -#if NET7_0_OR_GREATER - int num14 = ((int)num1 ^ (int)(num1 >> 15)) * -2048144777; - int num15 = (num14 ^ (num14 >>> 13)) * -1028477379; - return num15 ^ (num15 >>> 16); -#else - int num14 = ((int)num1 ^ (int)(num1 >> 15)) * -2048144777; - int num15 = (num14 ^ (int)((uint)num14 >> 13)) * -1028477379; - return num15 ^ (int)((uint)num15 >> 16); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Hash64(string obj, ulong seed = 0) => Hash64(obj.AsSpan(), seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Hash64(in T obj, ulong seed = 0) where T : unmanaged => Hash64(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref Unsafe.AsRef(in obj)), Unsafe.SizeOf()), seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Hash64(ReadOnlySpan buffer, ulong seed = 0) where T : unmanaged => Hash64(MemoryMarshal.Cast(buffer), seed); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Hash64(ReadOnlySpan buffer, ulong seed = 0) - { - ref var local1 = ref MemoryMarshal.GetReference(buffer); - var length = buffer.Length; - ulong num1; - if (buffer.Length >= 32) - { - var num2 = seed + 6983438078262162902UL; - var num3 = seed + 14029467366897019727UL; - var num4 = seed; - var num5 = seed - 11400714785074694791UL; - for (; length >= 32; length -= 32) - { - ref var local2 = ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length)); - var num6 = num2 + Unsafe.ReadUnaligned(ref local2) * 14029467366897019727UL; - num2 = (ulong)((((long)num6 << 31) | (long)(num6 >> 33)) * -7046029288634856825L); - var num7 = num3 + Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, new UIntPtr(8U))) * 14029467366897019727UL; - num3 = (ulong)((((long)num7 << 31) | (long)(num7 >> 33)) * -7046029288634856825L); - var num8 = num4 + Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, new UIntPtr(16U))) * 14029467366897019727UL; - num4 = (ulong)((((long)num8 << 31) | (long)(num8 >> 33)) * -7046029288634856825L); - var num9 = num5 + Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local2, new UIntPtr(24U))) * 14029467366897019727UL; - num5 = (ulong)((((long)num9 << 31) | (long)(num9 >> 33)) * -7046029288634856825L); - } - - var num10 = (((long)num2 << 1) | (long)(num2 >> 63)) + (((long)num3 << 7) | (long)(num3 >> 57)) + (((long)num4 << 12) | (long)(num4 >> 52)) + (((long)num5 << 18) | (long)(num5 >> 46)); - var num11 = num2 * 14029467366897019727UL; - var num12 = (((long)num11 << 31) | (long)(num11 >> 33)) * -7046029288634856825L; - var num13 = (num10 ^ num12) * -7046029288634856825L + -8796714831421723037L; - var num14 = num3 * 14029467366897019727UL; - var num15 = (((long)num14 << 31) | (long)(num14 >> 33)) * -7046029288634856825L; - var num16 = (num13 ^ num15) * -7046029288634856825L + -8796714831421723037L; - var num17 = num4 * 14029467366897019727UL; - var num18 = (((long)num17 << 31) | (long)(num17 >> 33)) * -7046029288634856825L; - var num19 = (num16 ^ num18) * -7046029288634856825L + -8796714831421723037L; - var num20 = num5 * 14029467366897019727UL; - var num21 = (((long)num20 << 31) | (long)(num20 >> 33)) * -7046029288634856825L; - num1 = (ulong)((num19 ^ num21) * -7046029288634856825L + -8796714831421723037L); - } - else - num1 = seed + 2870177450012600261UL; - - var num22 = num1 + (ulong)buffer.Length; - for (; length >= 8; length -= 8) - { - var num23 = Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length))) * 14029467366897019727UL; - var num24 = (ulong)((((long)num23 << 31) | (long)(num23 >> 33)) * -7046029288634856825L); - var num25 = num22 ^ num24; - num22 = (ulong)((((long)num25 << 27) | (long)(num25 >> 37)) * -7046029288634856825L + -8796714831421723037L); - } - - if (length >= 4) - { - ulong num26 = Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length))); - var num27 = num22 ^ (num26 * 11400714785074694791UL); - num22 = (ulong)((((long)num27 << 23) | (long)(num27 >> 41)) * -4417276706812531889L + 1609587929392839161L); - length -= 4; - } - - for (var byteOffset = 0; byteOffset < length; ++byteOffset) - { - ulong num28 = Unsafe.AddByteOffset(ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length)), (IntPtr)byteOffset); - var num29 = num22 ^ (num28 * 2870177450012600261UL); - num22 = (ulong)((((long)num29 << 11) | (long)(num29 >> 53)) * -7046029288634856825L); - } - -#if NET7_0_OR_GREATER - var num30 = (long)num22; - var num31 = (num30 ^ (num30 >>> 33)) * -4417276706812531889L; - var num32 = (num31 ^ (num31 >>> 29)) * 1609587929392839161L; - return num32 ^ (num32 >>> 32); -#else - var num30 = (long)num22; - var num31 = (num30 ^ (long)((ulong)num30 >> 33)) * -4417276706812531889L; - var num32 = (num31 ^ (long)((ulong)num31 >> 29)) * 1609587929392839161L; - return num32 ^ (long)((ulong)num32 >> 32); -#endif - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableHelper.cs deleted file mode 100644 index 098ba8a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableHelper.cs +++ /dev/null @@ -1,141 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Platform.Net; -namespace Fantasy.Network.Route -{ - /// - /// 提供操作地址映射的辅助方法。 - /// - public static class AddressableHelper - { - // 声明一个私有静态只读列表 AddressableScenes,用于存储地址映射的场景配置信息 - private static readonly List AddressableScenes = new List(); - - static AddressableHelper() - { - // 遍历场景配置信息,筛选出地址映射类型的场景,并添加到 AddressableScenes 列表中 - foreach (var sceneConfig in SceneConfigData.Instance.List) - { - if (sceneConfig.SceneTypeString == "Addressable") - { - AddressableScenes.Add(new AddressableScene(sceneConfig)); - } - } - } - - /// - /// 添加地址映射并返回操作结果。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - /// 路由 ID。 - /// 是否锁定。 - public static async FTask AddAddressable(Scene scene, long addressableId, long routeId, bool isLock = true) - { - // 获取指定索引的地址映射场景配置信息 - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - // 调用内部路由方法,发送添加地址映射的请求并等待响应 - var response = await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableAdd_Request - { - AddressableId = addressableId, RouteId = routeId, IsLock = isLock - }); - if (response.ErrorCode != 0) - { - Log.Error($"AddAddressable error is {response.ErrorCode}"); - } - } - - /// - /// 获取地址映射的路由 ID。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - /// 地址映射的路由 ID。 - public static async FTask GetAddressableRouteId(Scene scene, long addressableId) - { - // 获取指定索引的地址映射场景配置信息 - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - // 调用内部路由方法,发送获取地址映射路由 ID 的请求并等待响应 - var response = (I_AddressableGet_Response) await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableGet_Request - { - AddressableId = addressableId - }); - // 检查响应错误码,如果为零,返回路由 ID;否则,输出错误信息并返回 0 - if (response.ErrorCode == 0) - { - return response.RouteId; - } - - Log.Error($"GetAddressable error is {response.ErrorCode} addressableId:{addressableId}"); - return 0; - } - - /// - /// 移除指定地址映射。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - public static async FTask RemoveAddressable(Scene scene, long addressableId) - { - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - var response = await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableRemove_Request - { - AddressableId = addressableId - }); - - if (response.ErrorCode != 0) - { - Log.Error($"RemoveAddressable error is {response.ErrorCode}"); - } - } - - /// - /// 锁定指定地址映射。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - public static async FTask LockAddressable(Scene scene, long addressableId) - { - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - var response = await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableLock_Request - { - AddressableId = addressableId - }); - - if (response.ErrorCode != 0) - { - Log.Error($"LockAddressable error is {response.ErrorCode}"); - } - } - - /// - /// 解锁指定地址映射。 - /// - /// 场景实例。 - /// 地址映射的唯一标识。 - /// 路由 ID。 - /// 解锁来源。 - public static async FTask UnLockAddressable(Scene scene, long addressableId, long routeId, string source) - { - var addressableScene = AddressableScenes[(int)addressableId % AddressableScenes.Count]; - var response = await scene.NetworkMessagingComponent.CallInnerRoute(addressableScene.RunTimeId, - new I_AddressableUnLock_Request - { - AddressableId = addressableId, - RouteId = routeId, - Source = source - }); - - if (response.ErrorCode != 0) - { - Log.Error($"UnLockAddressable error is {response.ErrorCode}"); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableManageComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableManageComponent.cs deleted file mode 100644 index 8d08f08..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableManageComponent.cs +++ /dev/null @@ -1,144 +0,0 @@ -#if FANTASY_NET -using System; -using System.Collections.Generic; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network.Route -{ - public class AddressableManageComponentAwakeSystem : AwakeSystem - { - protected override void Awake(AddressableManageComponent self) - { - self.AddressableLock = self.Scene.CoroutineLockComponent.Create(self.GetType().TypeHandle.Value.ToInt64()); - } - } - - public class AddressableManageComponentDestroySystem : DestroySystem - { - protected override void Destroy(AddressableManageComponent self) - { - foreach (var (_, waitCoroutineLock) in self.Locks) - { - waitCoroutineLock.Dispose(); - } - - self.Locks.Clear(); - self.Addressable.Clear(); - self.AddressableLock.Dispose(); - self.AddressableLock = null; - } - } - - public sealed class AddressableManageComponent : Entity - { - public CoroutineLock AddressableLock; - public readonly Dictionary Addressable = new(); - public readonly Dictionary Locks = new(); - - /// - /// 添加地址映射。 - /// - /// 地址映射的唯一标识。 - /// 路由 ID。 - /// 是否进行锁定。 - public async FTask Add(long addressableId, long routeId, bool isLock) - { - WaitCoroutineLock waitCoroutineLock = null; - - try - { - if (isLock) - { - waitCoroutineLock = await AddressableLock.Wait(addressableId); - } - - Addressable[addressableId] = routeId; -#if FANTASY_DEVELOP - Log.Debug($"AddressableManageComponent Add addressableId:{addressableId} routeId:{routeId}"); -#endif - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - waitCoroutineLock?.Dispose(); - } - } - - /// - /// 获取地址映射的路由 ID。 - /// - /// 地址映射的唯一标识。 - /// 地址映射的路由 ID。 - public async FTask Get(long addressableId) - { - using (await AddressableLock.Wait(addressableId)) - { - Addressable.TryGetValue(addressableId, out var routeId); - return routeId; - } - } - - /// - /// 移除地址映射。 - /// - /// 地址映射的唯一标识。 - public async FTask Remove(long addressableId) - { - using (await AddressableLock.Wait(addressableId)) - { - Addressable.Remove(addressableId); -#if FANTASY_DEVELOP - Log.Debug($"Addressable Remove addressableId: {addressableId} _addressable:{Addressable.Count}"); -#endif - } - } - - /// - /// 锁定地址映射。 - /// - /// 地址映射的唯一标识。 - public async FTask Lock(long addressableId) - { - var waitCoroutineLock = await AddressableLock.Wait(addressableId); - Locks.Add(addressableId, waitCoroutineLock); - } - - /// - /// 解锁地址映射。 - /// - /// 地址映射的唯一标识。 - /// 新的路由 ID。 - /// 解锁来源。 - public void UnLock(long addressableId, long routeId, string source) - { - if (!Locks.Remove(addressableId, out var coroutineLock)) - { - Log.Error($"Addressable unlock not found addressableId: {addressableId} Source:{source}"); - return; - } - - Addressable.TryGetValue(addressableId, out var oldAddressableId); - - if (routeId != 0) - { - Addressable[addressableId] = routeId; - } - - coroutineLock.Dispose(); -#if FANTASY_DEVELOP - Log.Debug($"Addressable UnLock key: {addressableId} oldAddressableId : {oldAddressableId} routeId: {routeId} Source:{source}"); -#endif - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableMessageComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableMessageComponent.cs deleted file mode 100644 index 03e0def..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableMessageComponent.cs +++ /dev/null @@ -1,91 +0,0 @@ -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - public class AddressableMessageComponentDestroySystem : DestroySystem - { - protected override void Destroy(AddressableMessageComponent self) - { - if (self.AddressableId != 0) - { - AddressableHelper.RemoveAddressable(self.Scene, self.AddressableId).Coroutine(); - self.AddressableId = 0; - } - } - } - - /// - /// 可寻址消息组件、挂载了这个组件可以接收Addressable消息 - /// - public sealed class AddressableMessageComponent : Entity - { - /// - /// 可寻址消息组件的唯一标识。 - /// - public long AddressableId; - - /// - /// 注册可寻址消息组件。 - /// - /// 是否进行锁定。 - public FTask Register(bool isLock = true) - { - if (Parent == null) - { - throw new Exception("AddressableRouteComponent must be mounted under a component"); - } - - AddressableId = Parent.Id; - - if (AddressableId == 0) - { - throw new Exception("AddressableRouteComponent.Parent.Id is null"); - } - -#if FANTASY_DEVELOP - Log.Debug($"AddressableMessageComponent Register addressableId:{AddressableId} RouteId:{Parent.RouteId}"); -#endif - return AddressableHelper.AddAddressable(Scene, AddressableId, Parent.RouteId, isLock); - } - - /// - /// 锁定可寻址消息组件。 - /// - public FTask Lock() - { -#if FANTASY_DEVELOP - Log.Debug($"AddressableMessageComponent Lock {Parent.Id}"); -#endif - return AddressableHelper.LockAddressable(Scene, Parent.Id); - } - - /// - /// 解锁可寻址消息组件。 - /// - /// 解锁来源。 - public FTask UnLock(string source) - { -#if FANTASY_DEVELOP - Log.Debug($"AddressableMessageComponent UnLock {Parent.Id} {Parent.RouteId}"); -#endif - return AddressableHelper.UnLockAddressable(Scene, Parent.Id, Parent.RouteId, source); - } - - /// - /// 锁定可寻址消息并且释放掉AddressableMessageComponent组件。 - /// 该方法不会自动取Addressable中心删除自己的信息。 - /// 用于传送或转移到其他服务器时使用 - /// - public async FTask LockAndRelease() - { - await Lock(); - AddressableId = 0; - Dispose(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableRouteComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableRouteComponent.cs deleted file mode 100644 index bf439d7..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableRouteComponent.cs +++ /dev/null @@ -1,218 +0,0 @@ -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Scheduler; -using Fantasy.Timer; - -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - public class AddressableRouteComponentAwakeSystem : AwakeSystem - { - protected override void Awake(AddressableRouteComponent self) - { - ((Session)self.Parent).AddressableRouteComponent = self; - - var selfScene = self.Scene; - self.TimerComponent = selfScene.TimerComponent; - self.NetworkMessagingComponent = selfScene.NetworkMessagingComponent; - self.MessageDispatcherComponent = selfScene.MessageDispatcherComponent; - self.AddressableRouteLock = - selfScene.CoroutineLockComponent.Create(self.GetType().TypeHandle.Value.ToInt64()); - } - } - - public class AddressableRouteComponentDestroySystem : DestroySystem - { - protected override void Destroy(AddressableRouteComponent self) - { - self.AddressableRouteLock.Dispose(); - - self.AddressableRouteId = 0; - self.AddressableId = 0; - self.TimerComponent = null; - self.AddressableRouteLock = null; - self.NetworkMessagingComponent = null; - self.MessageDispatcherComponent = null; - } - } - - /// - /// 可寻址路由消息组件,挂载了这个组件可以接收和发送 Addressable 消息。 - /// - public sealed class AddressableRouteComponent : Entity - { - public long AddressableId; - public long AddressableRouteId; - public CoroutineLock AddressableRouteLock; - public TimerComponent TimerComponent; - public NetworkMessagingComponent NetworkMessagingComponent; - public MessageDispatcherComponent MessageDispatcherComponent; - - internal void Send(IAddressableRouteMessage message) - { - Call(message).Coroutine(); - } - - internal async FTask Send(Type requestType, APackInfo packInfo) - { - await Call(requestType, packInfo); - } - - internal async FTask Call(Type requestType, APackInfo packInfo) - { - if (IsDisposed) - { - return MessageDispatcherComponent.CreateResponse(requestType, InnerErrorCode.ErrNotFoundRoute); - } - - packInfo.IsDisposed = true; - var failCount = 0; - var runtimeId = RuntimeId; - IResponse iRouteResponse = null; - - try - { - using (await AddressableRouteLock.Wait(AddressableId, "AddressableRouteComponent Call MemoryStream")) - { - while (!IsDisposed) - { - if (AddressableRouteId == 0) - { - AddressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, AddressableId); - } - - if (AddressableRouteId == 0) - { - return MessageDispatcherComponent.CreateResponse(requestType, - InnerErrorCode.ErrNotFoundRoute); - } - - iRouteResponse = await NetworkMessagingComponent.CallInnerRoute(AddressableRouteId, requestType, packInfo); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRouteTimeout; - } - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrRouteTimeout: - { - return iRouteResponse; - } - case InnerErrorCode.ErrNotFoundRoute: - { - if (++failCount > 20) - { - Log.Error($"AddressableComponent.Call failCount > 20 route send message fail, routeId: {RouteId} AddressableRouteComponent:{Id}"); - return iRouteResponse; - } - - await TimerComponent.Net.WaitAsync(100); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRouteTimeout; - } - - AddressableRouteId = 0; - continue; - } - default: - { - return iRouteResponse; // 对于其他情况,直接返回响应,无需额外处理 - } - } - } - } - } - finally - { - packInfo.Dispose(); - } - - - return iRouteResponse; - } - - /// - /// 调用可寻址路由消息并等待响应。 - /// - /// 可寻址路由请求。 - private async FTask Call(IAddressableRouteMessage request) - { - if (IsDisposed) - { - return MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoute); - } - - var failCount = 0; - var runtimeId = RuntimeId; - - using (await AddressableRouteLock.Wait(AddressableId, "AddressableRouteComponent Call")) - { - while (true) - { - if (AddressableRouteId == 0) - { - AddressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, AddressableId); - } - - if (AddressableRouteId == 0) - { - return MessageDispatcherComponent.CreateResponse(request.GetType(), - InnerErrorCode.ErrNotFoundRoute); - } - - var iRouteResponse = await NetworkMessagingComponent.CallInnerRoute(AddressableRouteId, request); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRouteTimeout; - } - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrNotFoundRoute: - { - if (++failCount > 20) - { - Log.Error( - $"AddressableRouteComponent.Call failCount > 20 route send message fail, routeId: {RouteId} AddressableRouteComponent:{Id}"); - return iRouteResponse; - } - - await TimerComponent.Net.WaitAsync(500); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRouteTimeout; - } - - AddressableRouteId = 0; - continue; - } - case InnerErrorCode.ErrRouteTimeout: - { - return iRouteResponse; - } - default: - { - return iRouteResponse; - } - } - } - } - } - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableScene.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableScene.cs deleted file mode 100644 index 3105fca..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/AddressableScene.cs +++ /dev/null @@ -1,31 +0,0 @@ -#if FANTASY_NET -using Fantasy.IdFactory; -using Fantasy.Platform.Net; - -namespace Fantasy.Network.Route -{ - /// - /// AddressableScene - /// - public sealed class AddressableScene - { - /// - /// Id - /// - public readonly long Id; - /// - /// RunTimeId - /// - public readonly long RunTimeId; - /// - /// 构造方法 - /// - /// sceneConfig - public AddressableScene(SceneConfig sceneConfig) - { - Id = IdFactoryHelper.EntityId(0, sceneConfig.Id, (byte)sceneConfig.WorldConfigId, 0); - RunTimeId = IdFactoryHelper.RuntimeId(0, sceneConfig.Id, (byte)sceneConfig.WorldConfigId, 0); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableAddHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableAddHandler.cs deleted file mode 100644 index 847625b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableAddHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableAddHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableAddHandler : RouteRPC - { - /// - /// 在收到地址映射添加请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableAdd_Request 实例。 - /// 用于构建响应的 I_AddressableAdd_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableAdd_Request request, I_AddressableAdd_Response response, Action reply) - { - await scene.GetComponent().Add(request.AddressableId, request.RouteId, request.IsLock); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableGetHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableGetHandler.cs deleted file mode 100644 index f53c1f1..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableGetHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableGetHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableGetHandler : RouteRPC - { - /// - /// 在收到地址映射获取请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableGet_Request 实例。 - /// 用于构建响应的 I_AddressableGet_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableGet_Request request, I_AddressableGet_Response response, Action reply) - { - response.RouteId = await scene.GetComponent().Get(request.AddressableId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableLockHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableLockHandler.cs deleted file mode 100644 index b964274..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableLockHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableLockHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableLockHandler : RouteRPC - { - /// - /// 在收到地址映射锁定请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableLock_Request 实例。 - /// 用于构建响应的 I_AddressableLock_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableLock_Request request, I_AddressableLock_Response response, Action reply) - { - await scene.GetComponent().Lock(request.AddressableId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableRemoveHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableRemoveHandler.cs deleted file mode 100644 index c4e9654..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableRemoveHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableRemoveHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableRemoveHandler : RouteRPC - { - /// - /// 在收到地址映射移除请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableRemove_Request 实例。 - /// 用于构建响应的 I_AddressableRemove_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableRemove_Request request, I_AddressableRemove_Response response, Action reply) - { - await scene.GetComponent().Remove(request.AddressableId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableUnLockHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableUnLockHandler.cs deleted file mode 100644 index 1ab3937..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Addressable/Handler/I_AddressableUnLockHandler.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network.Route -{ - /// - /// 声明一个 sealed 类 I_AddressableUnLockHandler,继承自 RouteRPC 类,并指定泛型参数 - /// - public sealed class I_AddressableUnLockHandler : RouteRPC - { - /// - /// 在收到地址映射解锁请求时执行的逻辑。 - /// - /// 当前场景实例。 - /// 包含请求信息的 I_AddressableUnLock_Request 实例。 - /// 用于构建响应的 I_AddressableUnLock_Response 实例。 - /// 执行响应的回调操作。 - protected override async FTask Run(Scene scene, I_AddressableUnLock_Request request, I_AddressableUnLock_Response response, Action reply) - { - scene.GetComponent().UnLock(request.AddressableId, request.RouteId, request.Source); - await FTask.CompletedTask; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/MemoryStreamBufferPool.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/MemoryStreamBufferPool.cs deleted file mode 100644 index 6e6d4f7..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/MemoryStreamBufferPool.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Serialize; -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Network -{ - /// - /// MemoryStreamBuffer对象池类 - /// - public sealed class MemoryStreamBufferPool : IDisposable - { - private readonly int _poolSize; - private readonly int _maxMemoryStreamSize; - private readonly Queue _memoryStreamPool = new Queue(); - - /// - /// 构造方法 - /// - /// - /// - public MemoryStreamBufferPool(int maxMemoryStreamSize = 2048, int poolSize = 512) - { - _poolSize = poolSize; - _maxMemoryStreamSize = maxMemoryStreamSize; - } - - /// - /// 租借MemoryStream - /// - /// - /// - /// - public MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0) - { - if (size > _maxMemoryStreamSize) - { - return new MemoryStreamBuffer(memoryStreamBufferSource, size); - } - - if (size < _maxMemoryStreamSize) - { - size = _maxMemoryStreamSize; - } - - if (_memoryStreamPool.Count == 0) - { - return new MemoryStreamBuffer(memoryStreamBufferSource, size); - } - - if (_memoryStreamPool.TryDequeue(out var memoryStream)) - { - memoryStream.MemoryStreamBufferSource = memoryStreamBufferSource; - return memoryStream; - } - - return new MemoryStreamBuffer(memoryStreamBufferSource, size); - } - - /// - /// 归还ReturnMemoryStream - /// - /// - public void ReturnMemoryStream(MemoryStreamBuffer memoryStreamBuffer) - { - if (memoryStreamBuffer.Capacity > _maxMemoryStreamSize) - { - return; - } - - if (_memoryStreamPool.Count > _poolSize) - { - // 设置该值只能是内网或服务器转发的时候可能在连接之前发送的数据过多的情况下可以修改。 - // 设置过大会导致内存占用过大,所以要谨慎设置。 - return; - } - - memoryStreamBuffer.SetLength(0); - memoryStreamBuffer.MemoryStreamBufferSource = MemoryStreamBufferSource.None; - _memoryStreamPool.Enqueue(memoryStreamBuffer); - } - - /// - /// 销毁方法 - /// - public void Dispose() - { - foreach (var memoryStreamBuffer in _memoryStreamPool) - { - memoryStreamBuffer.MemoryStreamBufferSource = MemoryStreamBufferSource.None; - memoryStreamBuffer.Dispose(); - } - _memoryStreamPool.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Dispatcher/Interface/IMessageHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Dispatcher/Interface/IMessageHandler.cs deleted file mode 100644 index d8f928e..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Dispatcher/Interface/IMessageHandler.cs +++ /dev/null @@ -1,220 +0,0 @@ -// ReSharper disable InconsistentNaming - -using System; -using System.Collections.Generic; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.Serialize; - -namespace Fantasy.Network.Interface -{ - /// - /// 表示消息处理器的接口,处理特定类型的消息。 - /// - public interface IMessageHandler - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type(); - /// - /// 处理消息的方法。 - /// - /// 会话对象。 - /// RPC标识。 - /// 消息类型代码。 - /// 要处理的消息。 - /// 异步任务。 - FTask Handle(Session session, uint rpcId, uint messageTypeCode, object message); - } - - /// - /// 泛型消息基类,实现了 接口。 - /// - public abstract class Message : IMessageHandler - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(T); - } - - /// - /// 处理消息的方法。 - /// - /// 会话对象。 - /// RPC标识。 - /// 消息类型代码。 - /// 要处理的消息。 - /// 异步任务。 - public async FTask Handle(Session session, uint rpcId, uint messageTypeCode, object message) - { - try - { - await Run(session, (T) message); - } - catch (Exception e) - { - Log.Error(e); - } - } - - /// - /// 运行消息处理逻辑。 - /// - /// 会话对象。 - /// 要处理的消息。 - /// 异步任务。 - protected abstract FTask Run(Session session, T message); - } - - /// - /// 泛型消息RPC基类,实现了 接口,用于处理请求和响应类型的消息。 - /// - public abstract class MessageRPC : IMessageHandler where TRequest : IRequest where TResponse : AMessage, IResponse, new() - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TRequest); - } - - /// - /// 处理消息的方法。 - /// - /// 会话对象。 - /// RPC标识。 - /// 消息类型代码。 - /// 要处理的消息。 - /// 异步任务。 - public async FTask Handle(Session session, uint rpcId, uint messageTypeCode, object message) - { - if (message is not TRequest request) - { - Log.Error($"消息类型转换错误: {message.GetType().Name} to {typeof(TRequest).Name}"); - return; - } - - var response = new TResponse(); - var isReply = false; - - void Reply() - { - if (isReply) - { - return; - } - - isReply = true; - - if (session.IsDisposed) - { - return; - } - - session.Send(response, rpcId); - } - - try - { - await Run(session, request, response, Reply); - } - catch (Exception e) - { - Log.Error(e); - response.ErrorCode = InnerErrorCode.ErrRpcFail; - } - finally - { - Reply(); - } - } - - /// - /// 运行消息处理逻辑。 - /// - /// 会话对象。 - /// 请求消息。 - /// 响应消息。 - /// 发送响应的方法。 - /// 异步任务。 - protected abstract FTask Run(Session session, TRequest request, TResponse response, Action reply); - } -#if FANTASY_UNITY - public interface IMessageDelegateHandler - { - /// - /// 注册消息处理器。 - /// - /// - public void Register(object @delegate); - /// - /// 取消注册消息处理器。 - /// - /// - public int UnRegister(object @delegate); - /// - /// 处理消息的方法。 - /// - /// - /// - public void Handle(Session session, object message); - } - public delegate FTask MessageDelegate(Session session, T msg) where T : IMessage; - public sealed class MessageDelegateHandler : IMessageDelegateHandler, IDisposable where T : IMessage - { - private readonly List> _delegates = new List>(); - - public Type Type() - { - return typeof(T); - } - - public void Register(object @delegate) - { - var a = (MessageDelegate)@delegate; - - if (_delegates.Contains(a)) - { - Log.Error($"{typeof(T).Name} already register action delegateName:{a.Method.Name}"); - return; - } - - _delegates.Add(a); - } - - public int UnRegister(object @delegate) - { - _delegates.Remove((MessageDelegate)@delegate); - return _delegates.Count; - } - - public void Handle(Session session, object message) - { - foreach (var registerDelegate in _delegates) - { - try - { - registerDelegate(session, (T)message).Coroutine(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public void Dispose() - { - _delegates.Clear(); - } - } -#endif -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Dispatcher/Interface/IRouteMessageHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Dispatcher/Interface/IRouteMessageHandler.cs deleted file mode 100644 index 4a367b2..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Dispatcher/Interface/IRouteMessageHandler.cs +++ /dev/null @@ -1,490 +0,0 @@ -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Serialize; - -#if FANTASY_NET -// ReSharper disable InconsistentNaming - -namespace Fantasy.Network.Interface -{ - /// - /// 表示路由消息处理器的接口,处理特定类型的路由消息。 - /// - public interface IRouteMessageHandler - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type(); - - /// - /// 处理路由消息的方法。 - /// - /// 会话对象。 - /// 实体对象。 - /// RPC标识。 - /// 要处理的路由消息。 - /// 异步任务。 - FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage); - } - - /// - /// 泛型路由基类,实现了 接口,用于处理特定实体和路由消息类型的路由。 - /// - /// 实体类型。 - /// 路由消息类型。 - public abstract class Route : IRouteMessageHandler where TEntity : Entity where TMessage : IRouteMessage - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TMessage); - } - - /// - /// 处理路由消息的方法。 - /// - /// 会话对象。 - /// 实体对象。 - /// RPC标识。 - /// 要处理的路由消息。 - /// 异步任务。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TMessage ruteMessage) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TMessage).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"Route type conversion error: {entity.GetType().Name} to {nameof(TEntity)}"); - return; - } - - try - { - await Run(tEntity, ruteMessage); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - } - } - - /// - /// 运行路由消息处理逻辑。 - /// - /// 实体对象。 - /// 要处理的路由消息。 - /// 异步任务。 - protected abstract FTask Run(TEntity entity, TMessage message); - } - - /// - /// 泛型路由RPC基类,实现了 接口,用于处理请求和响应类型的路由。 - /// - /// 实体类型。 - /// 路由请求类型。 - /// 路由响应类型。 - public abstract class RouteRPC : IRouteMessageHandler where TEntity : Entity where TRouteRequest : IRouteRequest where TRouteResponse : AMessage, IRouteResponse, new() - { - /// - /// 获取处理的消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TRouteRequest); - } - - /// - /// 处理路由消息的方法。 - /// - /// 会话对象。 - /// 实体对象。 - /// RPC标识。 - /// 要处理的路由消息。 - /// 异步任务。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TRouteRequest tRouteRequest) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TRouteRequest).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"Route type conversion error: {entity.GetType().Name} to {nameof(TEntity)}"); - return; - } - - var isReply = false; - var response = new TRouteResponse(); - - void Reply() - { - if (isReply) - { - return; - } - - isReply = true; - - if (session.IsDisposed) - { - return; - } - - session.Send(response, rpcId); - } - - try - { - await Run(tEntity, tRouteRequest, response, Reply); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - response.ErrorCode = InnerErrorCode.ErrRpcFail; - } - finally - { - Reply(); - } - } - - /// - /// 运行路由消息处理逻辑。 - /// - /// 实体对象。 - /// 请求路由消息。 - /// 响应路由消息。 - /// 发送响应的方法。 - /// 异步任务。 - protected abstract FTask Run(TEntity entity, TRouteRequest request, TRouteResponse response, Action reply); - } - - /// - /// 泛型可寻址路由基类,实现了 接口,用于处理特定实体和可寻址路由消息类型的路由。 - /// - /// 实体类型。 - /// 可寻址路由消息类型。 - public abstract class Addressable : IRouteMessageHandler where TEntity : Entity where TMessage : IAddressableRouteMessage - { - /// - /// 获取消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TMessage); - } - - /// - /// 处理可寻址路由消息。 - /// - /// 会话。 - /// 实体。 - /// RPC标识。 - /// 可寻址路由消息。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TMessage ruteMessage) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TMessage).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"Route type conversion error: {entity.GetType().Name} to {nameof(TEntity)}"); - return; - } - - try - { - await Run(tEntity, ruteMessage); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - } - finally - { - session.Send(new RouteResponse(), rpcId); - } - } - - /// - /// 运行处理可寻址路由消息。 - /// - /// 实体。 - /// 可寻址路由消息。 - protected abstract FTask Run(TEntity entity, TMessage message); - } - - /// - /// 泛型可寻址RPC路由基类,实现了 接口,用于处理特定实体和可寻址RPC路由请求类型的路由。 - /// - /// 实体类型。 - /// 可寻址RPC路由请求类型。 - /// 可寻址RPC路由响应类型。 - public abstract class AddressableRPC : IRouteMessageHandler where TEntity : Entity where TRouteRequest : IAddressableRouteRequest where TRouteResponse : IAddressableRouteResponse, new() - { - /// - /// 获取消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TRouteRequest); - } - - /// - /// 处理可寻址RPC路由请求。 - /// - /// 会话。 - /// 实体。 - /// RPC标识。 - /// 可寻址RPC路由请求。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TRouteRequest tRouteRequest) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TRouteRequest).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"Route type conversion error: {entity.GetType().Name} to {nameof(TEntity)}"); - return; - } - - var isReply = false; - var response = new TRouteResponse(); - - void Reply() - { - if (isReply) - { - return; - } - - isReply = true; - - if (session.IsDisposed) - { - return; - } - - session.Send(response, rpcId); - } - - try - { - await Run(tEntity, tRouteRequest, response, Reply); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - response.ErrorCode = InnerErrorCode.ErrRpcFail; - } - finally - { - Reply(); - } - } - - /// - /// 运行处理可寻址RPC路由请求。 - /// - /// 实体。 - /// 可寻址RPC路由请求。 - /// 可寻址RPC路由响应。 - /// 回复操作。 - protected abstract FTask Run(TEntity entity, TRouteRequest request, TRouteResponse response, Action reply); - } - - /// - /// 泛型漫游路由基类,实现了 接口,用于处理特定实体和漫游路由消息类型的路由。 - /// - /// 实体类型。 - /// 漫游消息类型。 - public abstract class Roaming : IRouteMessageHandler where TEntity : Entity where TMessage : IRoamingMessage - { - /// - /// 获取消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TMessage); - } - - /// - /// 处理漫游消息。 - /// - /// 会话。 - /// 实体。 - /// RPC标识。 - /// 漫游消息。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TMessage ruteMessage) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TMessage).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"Route type conversion error: {entity.GetType().Name} to {nameof(TEntity)}"); - return; - } - - try - { - await Run(tEntity, ruteMessage); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - } - finally - { - session.Send(new RouteResponse(), rpcId); - } - } - - /// - /// 运行处理漫游消息。 - /// - /// 终点实体。 - /// 漫游消息。 - protected abstract FTask Run(TEntity terminus, TMessage message); - } - - /// - /// 漫游RPC路由基类,实现了 接口,用于处理特定实体和漫游RPC路由请求类型的路由。 - /// - /// 实体类型。 - /// 漫游RPC路由请求类型。 - /// 漫游RPC路由响应类型。 - public abstract class RoamingRPC : IRouteMessageHandler where TEntity : Entity where TRouteRequest : IRoamingRequest where TRouteResponse : IRoamingResponse, new() - { - /// - /// 获取消息类型。 - /// - /// 消息类型。 - public Type Type() - { - return typeof(TRouteRequest); - } - - /// - /// 处理漫游RPC路由请求。 - /// - /// 会话。 - /// 实体。 - /// RPC标识。 - /// 漫游RPC路由请求。 - public async FTask Handle(Session session, Entity entity, uint rpcId, object routeMessage) - { - if (routeMessage is not TRouteRequest tRouteRequest) - { - Log.Error($"Message type conversion error: {routeMessage.GetType().FullName} to {typeof(TRouteRequest).Name}"); - return; - } - - if (entity is not TEntity tEntity) - { - Log.Error($"Route type conversion error: {entity.GetType().Name} to {nameof(TEntity)}"); - return; - } - - var isReply = false; - var response = new TRouteResponse(); - - void Reply() - { - if (isReply) - { - return; - } - - isReply = true; - - if (session.IsDisposed) - { - return; - } - - session.Send(response, rpcId); - } - - try - { - await Run(tEntity, tRouteRequest, response, Reply); - } - catch (Exception e) - { - if (entity is not Scene scene) - { - scene = entity.Scene; - } - - Log.Error($"SceneConfigId:{session.Scene.SceneConfigId} ProcessConfigId:{scene.Process.Id} SceneType:{scene.SceneType} EntityId {tEntity.Id} : Error {e}"); - response.ErrorCode = InnerErrorCode.ErrRpcFail; - } - finally - { - Reply(); - } - } - - /// - /// 运行处理漫游RPC路由请求。 - /// - /// 终点实体。 - /// 漫游RPC路由请求。 - /// 漫游RPC路由响应。 - /// 回复操作。 - protected abstract FTask Run(TEntity terminus, TRouteRequest request, TRouteResponse response, Action reply); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Dispatcher/MessageDispatcherComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Dispatcher/MessageDispatcherComponent.cs deleted file mode 100644 index 0a24770..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Dispatcher/MessageDispatcherComponent.cs +++ /dev/null @@ -1,426 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.DataStructure.Dictionary; -using Fantasy.Entitas; -using Fantasy.InnerMessage; -using Fantasy.Network; -#pragma warning disable CS8604 // Possible null reference argument. - -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network.Interface -{ - /// - /// 用于存储消息处理器的信息,包括类型和对象实例。 - /// - /// 消息处理器的类型 - internal sealed class HandlerInfo - { - /// - /// 获取或设置消息处理器对象。 - /// - public T Obj; - /// - /// 获取或设置消息处理器的类型。 - /// - public Type Type; - } - - /// - /// 网络消息分发组件。 - /// - public sealed class MessageDispatcherComponent : Entity, IAssembly - { - public long AssemblyIdentity { get; set; } - private readonly Dictionary _responseTypes = new Dictionary(); - private readonly DoubleMapDictionary _networkProtocols = new DoubleMapDictionary(); - private readonly Dictionary _messageHandlers = new Dictionary(); - private readonly OneToManyList _assemblyResponseTypes = new OneToManyList(); - private readonly OneToManyList _assemblyNetworkProtocols = new OneToManyList(); - private readonly OneToManyList> _assemblyMessageHandlers = new OneToManyList>(); -#if FANTASY_UNITY - private readonly Dictionary _messageDelegateHandlers = new Dictionary(); -#endif -#if FANTASY_NET - private readonly Dictionary _customRouteMap = new Dictionary(); - private readonly OneToManyList _assemblyCustomRouteMap = new OneToManyList(); - private readonly Dictionary _routeMessageHandlers = new Dictionary(); - private readonly OneToManyList> _assemblyRouteMessageHandlers = new OneToManyList>(); -#endif - private CoroutineLock _receiveRouteMessageLock; - - #region Initialize - - internal async FTask Initialize() - { - _receiveRouteMessageLock = Scene.CoroutineLockComponent.Create(GetType().TypeHandle.Value.ToInt64()); - await AssemblySystem.Register(this); - return this; - } - - public async FTask Load(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - private void LoadInner(long assemblyIdentity) - { - // 遍历所有实现了IMessage接口的类型,获取OpCode并添加到_networkProtocols字典中 - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IMessage))) - { - var obj = (IMessage) Activator.CreateInstance(type); - var opCode = obj.OpCode(); - - _networkProtocols.Add(opCode, type); - - var responseType = type.GetProperty("ResponseType"); - - // 如果类型具有ResponseType属性,将其添加到_responseTypes字典中 - if (responseType != null) - { - _responseTypes.Add(type, responseType.PropertyType); - _assemblyResponseTypes.Add(assemblyIdentity, type); - } - - _assemblyNetworkProtocols.Add(assemblyIdentity, opCode); - } - - // 遍历所有实现了IMessageHandler接口的类型,创建实例并添加到_messageHandlers字典中 - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IMessageHandler))) - { - var obj = (IMessageHandler) Activator.CreateInstance(type); - - if (obj == null) - { - throw new Exception($"message handle {type.Name} is null"); - } - - var key = obj.Type(); - _messageHandlers.Add(key, obj); - _assemblyMessageHandlers.Add(assemblyIdentity, new HandlerInfo() - { - Obj = obj, Type = key - }); - } - - // 如果编译符号FANTASY_NET存在,遍历所有实现了IRouteMessageHandler接口的类型,创建实例并添加到_routeMessageHandlers字典中 -#if FANTASY_NET - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IRouteMessageHandler))) - { - var obj = (IRouteMessageHandler) Activator.CreateInstance(type); - - if (obj == null) - { - throw new Exception($"message handle {type.Name} is null"); - } - - var key = obj.Type(); - _routeMessageHandlers.Add(key, obj); - _assemblyRouteMessageHandlers.Add(assemblyIdentity, new HandlerInfo() - { - Obj = obj, Type = key - }); - } - - foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(ICustomRoute))) - { - var obj = (ICustomRoute) Activator.CreateInstance(type); - - if (obj == null) - { - throw new Exception($"message handle {type.Name} is null"); - } - - var opCode = obj.OpCode(); - _customRouteMap[opCode] = obj.RouteType; - _assemblyCustomRouteMap.Add(assemblyIdentity, opCode); - } -#endif - } - - public async FTask ReLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - LoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - public async FTask OnUnLoad(long assemblyIdentity) - { - var tcs = FTask.Create(false); - Scene?.ThreadSynchronizationContext.Post(() => - { - OnUnLoadInner(assemblyIdentity); - tcs.SetResult(); - }); - await tcs; - } - - private void OnUnLoadInner(long assemblyIdentity) - { - // 移除程序集对应的ResponseType类型和OpCode信息 - if (_assemblyResponseTypes.TryGetValue(assemblyIdentity, out var removeResponseTypes)) - { - foreach (var removeResponseType in removeResponseTypes) - { - _responseTypes.Remove(removeResponseType); - } - - _assemblyResponseTypes.RemoveByKey(assemblyIdentity); - } - - if (_assemblyNetworkProtocols.TryGetValue(assemblyIdentity, out var removeNetworkProtocols)) - { - foreach (var removeNetworkProtocol in removeNetworkProtocols) - { - _networkProtocols.RemoveByKey(removeNetworkProtocol); - } - - _assemblyNetworkProtocols.RemoveByKey(assemblyIdentity); - } - - // 移除程序集对应的消息处理器信息 - if (_assemblyMessageHandlers.TryGetValue(assemblyIdentity, out var removeMessageHandlers)) - { - foreach (var removeMessageHandler in removeMessageHandlers) - { - _messageHandlers.Remove(removeMessageHandler.Type); - } - - _assemblyMessageHandlers.RemoveByKey(assemblyIdentity); - } - - // 如果编译符号FANTASY_NET存在,移除程序集对应的路由消息处理器信息 -#if FANTASY_NET - if (_assemblyRouteMessageHandlers.TryGetValue(assemblyIdentity, out var removeRouteMessageHandlers)) - { - foreach (var removeRouteMessageHandler in removeRouteMessageHandlers) - { - _routeMessageHandlers.Remove(removeRouteMessageHandler.Type); - } - - _assemblyRouteMessageHandlers.RemoveByKey(assemblyIdentity); - } - - if (_assemblyCustomRouteMap.TryGetValue(assemblyIdentity, out var removeCustomRouteMap)) - { - foreach (var removeCustom in removeCustomRouteMap) - { - _customRouteMap.Remove(removeCustom); - } - - _assemblyCustomRouteMap.RemoveByKey(assemblyIdentity); - } -#endif - } - -#if FANTASY_UNITY - /// - /// 手动注册一个消息处理器。 - /// - /// - /// - public void RegisterHandler(MessageDelegate @delegate) where T : IMessage - { - var type = typeof(T); - - if (!_messageDelegateHandlers.TryGetValue(type, out var messageDelegate)) - { - messageDelegate = new MessageDelegateHandler(); - _messageDelegateHandlers.Add(type,messageDelegate); - } - - messageDelegate.Register(@delegate); - } - - /// - /// 手动卸载一个消息处理器,必须是通过RegisterHandler方法注册的消息处理器。 - /// - /// - /// - public void UnRegisterHandler(MessageDelegate @delegate) where T : IMessage - { - var type = typeof(T); - - if (!_messageDelegateHandlers.TryGetValue(type, out var messageDelegate)) - { - return; - } - - if (messageDelegate.UnRegister(@delegate) != 0) - { - return; - } - - _messageDelegateHandlers.Remove(type); - } -#endif - #endregion - - /// - /// 处理普通消息,将消息分发给相应的消息处理器。 - /// - /// 会话对象 - /// 消息类型 - /// 消息对象 - /// RPC标识 - /// 协议码 - public void MessageHandler(Session session, Type type, object message, uint rpcId, uint protocolCode) - { -#if FANTASY_UNITY - if(_messageDelegateHandlers.TryGetValue(type,out var messageDelegateHandler)) - { - messageDelegateHandler.Handle(session, message); - return; - } -#endif - if (!_messageHandlers.TryGetValue(type, out var messageHandler)) - { - Log.Warning($"Scene:{session.Scene.Id} Found Unhandled Message: {message.GetType()}"); - return; - } - - // 调用消息处理器的Handle方法并启动协程执行处理逻辑 - messageHandler.Handle(session, rpcId, protocolCode, message).Coroutine(); - } - - // 如果编译符号FANTASY_NET存在,定义处理路由消息的方法 -#if FANTASY_NET - /// - /// 处理路由消息,将消息分发给相应的路由消息处理器。 - /// - /// 会话对象 - /// 消息类型 - /// 实体对象 - /// 消息对象 - /// RPC标识 - public async FTask RouteMessageHandler(Session session, Type type, Entity entity, object message, uint rpcId) - { - if (!_routeMessageHandlers.TryGetValue(type, out var routeMessageHandler)) - { - Log.Warning($"Scene:{session.Scene.Id} Found Unhandled RouteMessage: {message.GetType()}"); - - if (message is IRouteRequest request) - { - FailRouteResponse(session, request.GetType(), InnerErrorCode.ErrEntityNotFound, rpcId); - } - - return; - } - - var runtimeId = entity.RuntimeId; - var sessionRuntimeId = session.RuntimeId; - - if (entity is Scene) - { - // 如果是Scene的话、就不要加锁了、如果加锁很一不小心就可能会造成死锁 - await routeMessageHandler.Handle(session, entity, rpcId, message); - return; - } - - // 使用协程锁来确保多线程安全 - using (await _receiveRouteMessageLock.Wait(runtimeId)) - { - if (sessionRuntimeId != session.RuntimeId) - { - return; - } - - if (runtimeId != entity.RuntimeId) - { - if (message is IRouteRequest request) - { - FailRouteResponse(session, request.GetType(), InnerErrorCode.ErrEntityNotFound, rpcId); - } - - return; - } - - await routeMessageHandler.Handle(session, entity, rpcId, message); - } - } - - internal bool GetCustomRouteType(long protocolCode, out int routeType) - { - return _customRouteMap.TryGetValue(protocolCode, out routeType); - } -#endif - internal void FailRouteResponse(Session session, Type requestType, uint error, uint rpcId) - { - var response = CreateRouteResponse(requestType, error); - session.Send(response, rpcId); - } - - internal IResponse CreateResponse(Type requestType, uint error) - { - IResponse response; - - if (_responseTypes.TryGetValue(requestType, out var responseType)) - { - response = (IResponse) Activator.CreateInstance(responseType); - } - else - { - response = new Response(); - } - - response.ErrorCode = error; - return response; - } - - internal IRouteResponse CreateRouteResponse(Type requestType, uint error) - { - IRouteResponse response; - - if (_responseTypes.TryGetValue(requestType, out var responseType)) - { - response = (IRouteResponse) Activator.CreateInstance(responseType); - } - else - { - response = new RouteResponse(); - } - - response.ErrorCode = error; - return response; - } - - /// - /// 根据消息类型获取对应的OpCode。 - /// - /// 消息类型 - /// 消息对应的OpCode - public uint GetOpCode(Type type) - { - return _networkProtocols.GetKeyByValue(type); - } - - /// - /// 根据OpCode获取对应的消息类型。 - /// - /// OpCode - /// OpCode对应的消息类型 - public Type GetOpCodeType(uint code) - { - return _networkProtocols.GetValueByKey(code); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/IMessage.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/IMessage.cs deleted file mode 100644 index aea7d08..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/IMessage.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.Interface -{ - /// - /// 表示通用消息接口。 - /// - public interface IMessage - { - /// - /// 获取消息的操作代码。 - /// - /// 操作代码。 - uint OpCode(); - } - - /// - /// 表示请求消息接口。 - /// - public interface IRequest : IMessage - { - - } - - /// - /// 表示响应消息接口。 - /// - public interface IResponse : IMessage - { - /// - /// 获取或设置错误代码。 - /// - uint ErrorCode { get; set; } - } - // 普通路由消息 - /// - /// 表示普通路由消息的接口,继承自请求接口。 - /// - public interface IRouteMessage : IRequest - { - - } - - /// - /// 普通路由请求接口,继承自普通路由消息接口。 - /// - public interface IRouteRequest : IRouteMessage { } - /// - /// 普通路由响应接口,继承自响应接口。 - /// - public interface IRouteResponse : IResponse { } - // 可寻址协议 - /// - /// 表示可寻址协议的普通路由消息接口,继承自普通路由消息接口。 - /// - public interface IAddressableRouteMessage : IRouteMessage { } - /// - /// 可寻址协议的普通路由请求接口,继承自可寻址协议的普通路由消息接口。 - /// - public interface IAddressableRouteRequest : IRouteRequest { } - /// - /// 可寻址协议的普通路由响应接口,继承自普通路由响应接口。 - /// - public interface IAddressableRouteResponse : IRouteResponse { } - // 自定义Route协议 - public interface ICustomRoute : IMessage - { - int RouteType { get; } - } - /// - /// 表示自定义Route协议的普通路由消息接口,继承自普通路由消息接口。 - /// - public interface ICustomRouteMessage : IRouteMessage, ICustomRoute { } - /// - /// 自定义Route协议的普通路由请求接口,继承自自定义Route协议的普通路由消息接口。 - /// - public interface ICustomRouteRequest : IRouteRequest, ICustomRoute { } - /// - /// 自定义Route协议的普通路由响应接口,继承自普通路由响应接口。 - /// - public interface ICustomRouteResponse : IRouteResponse { } - /// - /// 表示漫游协议的普通路由消息接口,继承自普通路由消息接口。 - /// - public interface IRoamingMessage : IRouteMessage, ICustomRoute { } - /// - /// 漫游协议的普通路由请求接口,继承自自定义Route协议的普通路由消息接口。 - /// - public interface IRoamingRequest : IRoamingMessage { } - /// - /// 漫游协议的普通路由响应接口,继承自普通路由响应接口。 - /// - public interface IRoamingResponse : IRouteResponse { } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/InnerMessage.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/InnerMessage.cs deleted file mode 100644 index 643c92b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/InnerMessage.cs +++ /dev/null @@ -1,319 +0,0 @@ -using Fantasy.Network.Interface; -using Fantasy.Serialize; -using MongoDB.Bson.Serialization.Attributes; -using ProtoBuf; -#if FANTASY_NET -using Fantasy.Network.Roaming; -#endif -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// ReSharper disable InconsistentNaming -// ReSharper disable PropertyCanBeMadeInitOnly.Global -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.InnerMessage -{ - [ProtoContract] - public sealed partial class BenchmarkMessage : AMessage, IMessage - { - public uint OpCode() - { - return Fantasy.Network.OpCode.BenchmarkMessage; - } - } - [ProtoContract] - public partial class BenchmarkRequest : AMessage, IRequest - { - public uint OpCode() - { - return Fantasy.Network.OpCode.BenchmarkRequest; - } - [ProtoIgnore] - public BenchmarkResponse ResponseType { get; set; } - [ProtoMember(1)] - public long RpcId { get; set; } - } - - [ProtoContract] - public partial class BenchmarkResponse : AMessage, IResponse - { - public uint OpCode() - { - return Fantasy.Network.OpCode.BenchmarkResponse; - } - [ProtoMember(1)] - public long RpcId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - public sealed partial class Response : AMessage, IResponse - { - public uint OpCode() - { - return Fantasy.Network.OpCode.DefaultResponse; - } - [ProtoMember(1)] - public long RpcId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public sealed partial class RouteResponse : AMessage, IRouteResponse - { - public uint OpCode() - { - return Fantasy.Network.OpCode.DefaultRouteResponse; - } - [ProtoMember(1)] - public long RpcId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class PingRequest : AMessage, IRequest - { - public uint OpCode() - { - return Fantasy.Network.OpCode.PingRequest; - } - [ProtoIgnore] - public PingResponse ResponseType { get; set; } - [ProtoMember(1)] - public long RpcId { get; set; } - } - - [ProtoContract] - public partial class PingResponse : AMessage, IResponse - { - public uint OpCode() - { - return Fantasy.Network.OpCode.PingResponse; - } - [ProtoMember(1)] - public long RpcId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - [ProtoMember(3)] - public long Now; - } - [ProtoContract] - public partial class I_AddressableAdd_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableAdd_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableAddRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - [ProtoMember(2)] - public long RouteId { get; set; } - [ProtoMember(3)] - public bool IsLock { get; set; } - } - [ProtoContract] - public partial class I_AddressableAdd_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableAddResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class I_AddressableGet_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableGet_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableGetRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - } - [ProtoContract] - public partial class I_AddressableGet_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableGetResponse; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - [ProtoMember(1)] - public long RouteId { get; set; } - } - [ProtoContract] - public partial class I_AddressableRemove_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableRemove_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableRemoveRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - } - [ProtoContract] - public partial class I_AddressableRemove_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableRemoveResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class I_AddressableLock_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableLock_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableLockRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - } - [ProtoContract] - public partial class I_AddressableLock_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableLockResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class I_AddressableUnLock_Request : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_AddressableUnLock_Response ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.AddressableUnLockRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long AddressableId { get; set; } - [ProtoMember(2)] - public long RouteId { get; set; } - [ProtoMember(3)] - public string Source { get; set; } - } - [ProtoContract] - public partial class I_AddressableUnLock_Response : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.AddressableUnLockResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } -#if FANTASY_NET - [ProtoContract] - public sealed class I_LinkRoamingRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_LinkRoamingResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.LinkRoamingRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long RoamingId { get; set; } - [ProtoMember(2)] - public int RoamingType { get; set; } - [ProtoMember(3)] - public long ForwardSessionRouteId { get; set; } - [ProtoMember(4)] - public long SceneRouteId { get; set; } - } - [ProtoContract] - public sealed class I_LinkRoamingResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.LinkRoamingResponse; } - [ProtoMember(1)] - public long TerminusId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public sealed class I_UnLinkRoamingRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_UnLinkRoamingResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.UnLinkRoamingRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long RoamingId { get; set; } - [ProtoMember(2)] - public bool DisposeRoaming { get; set; } - } - [ProtoContract] - public sealed class I_UnLinkRoamingResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.UnLinkRoamingResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public partial class I_LockTerminusIdRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_LockTerminusIdResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.LockTerminusIdRequest; } - [ProtoMember(1)] - public long SessionRuntimeId { get; set; } - [ProtoMember(2)] - public int RoamingType { get; set; } - } - [ProtoContract] - public partial class I_LockTerminusIdResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.LockTerminusIdResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - [ProtoContract] - public sealed class I_UnLockTerminusIdRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_UnLockTerminusIdResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.UnLockTerminusIdRequest; } - public long RouteTypeOpCode() { return 1; } - [ProtoMember(1)] - public long SessionRuntimeId { get; set; } - [ProtoMember(2)] - public int RoamingType { get; set; } - [ProtoMember(3)] - public long TerminusId { get; set; } - [ProtoMember(4)] - public long TargetSceneRouteId { get; set; } - } - [ProtoContract] - public sealed class I_UnLockTerminusIdResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.UnLockTerminusIdResponse; } - [ProtoMember(1)] - public uint ErrorCode { get; set; } - } - /// - /// 漫游传送终端的请求 - /// - public partial class I_TransferTerminusRequest : AMessage, IRouteRequest - { - [BsonIgnore] - public I_TransferTerminusResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.TransferTerminusRequest; } - public Terminus Terminus { get; set; } - } - public partial class I_TransferTerminusResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.TransferTerminusResponse; } - public uint ErrorCode { get; set; } - } - /// - /// 用于服务器之间获取漫游的TerminusId。 - /// - [ProtoContract] - public partial class I_GetTerminusIdRequest : AMessage, IRouteRequest - { - [ProtoIgnore] - public I_GetTerminusIdResponse ResponseType { get; set; } - public uint OpCode() { return Fantasy.Network.OpCode.GetTerminusIdRequest; } - [ProtoMember(1)] - public int RoamingType { get; set; } - [ProtoMember(2)] - public long SessionRuntimeId { get; set; } - } - [ProtoContract] - public partial class I_GetTerminusIdResponse : AMessage, IRouteResponse - { - public uint OpCode() { return Fantasy.Network.OpCode.GetTerminusIdResponse; } - [ProtoMember(1)] - public long TerminusId { get; set; } - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } -#endif -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/BufferPacketParser.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/BufferPacketParser.cs deleted file mode 100644 index e4d1540..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/BufferPacketParser.cs +++ /dev/null @@ -1,386 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -namespace Fantasy.PacketParser -{ - /// - /// BufferPacketParser消息格式化器抽象类 - /// 这个不会用在TCP协议中、因此不用考虑分包和粘包的问题。 - /// 目前这个只会用在KCP协议中、因为KCP出来的就是一个完整的包、所以可以一次性全部解析出来。 - /// 如果是用在其他协议上可能会出现问题。 - /// - public abstract class BufferPacketParser : APacketParser - { - protected uint RpcId; - protected long RouteId; - protected uint ProtocolCode; - protected int MessagePacketLength; - public override void Dispose() - { - RpcId = 0; - RouteId = 0; - ProtocolCode = 0; - MessagePacketLength = 0; - base.Dispose(); - } - /// - /// 解包方法 - /// - /// buffer - /// count - /// packInfo - /// - public abstract bool UnPack(byte[] buffer, ref int count, out APackInfo packInfo); - } -#if FANTASY_NET - /// - /// 服务器之间专用的BufferPacketParser消息格式化器 - /// - public sealed class InnerBufferPacketParser : BufferPacketParser - { - /// - /// - /// - /// - /// - /// - /// - /// - public override unsafe bool UnPack(byte[] buffer, ref int count, out APackInfo packInfo) - { - packInfo = null; - - if (buffer.Length < count) - { - throw new ScanException($"The buffer length is less than the specified count. buffer.Length={buffer.Length} count={count}"); - } - - if (count < Packet.InnerPacketHeadLength) - { - // 如果内存资源中的数据长度小于内部消息头的长度,无法解析 - return false; - } - - fixed (byte* bufferPtr = buffer) - { - MessagePacketLength = *(int*)bufferPtr; - - if (MessagePacketLength > Packet.PacketBodyMaxLength || count < MessagePacketLength) - { - // 检查消息体长度是否超出限制 - throw new ScanException($"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - ProtocolCode = *(uint*)(bufferPtr + Packet.PacketLength); - RpcId = *(uint*)(bufferPtr + Packet.InnerPacketRpcIdLocation); - RouteId = *(long*)(bufferPtr + Packet.InnerPacketRouteRouteIdLocation); - } - - packInfo = InnerPackInfo.Create(Network); - packInfo.RpcId = RpcId; - packInfo.RouteId = RouteId; - packInfo.ProtocolCode = ProtocolCode; - packInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, count).Write(buffer, 0, count); - return true; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, ref routeId, message) : Pack(ref rpcId, ref routeId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream) - { - fixed (byte* bufferPtr = memoryStream.GetBuffer()) - { - *(uint*)(bufferPtr + Packet.InnerPacketRpcIdLocation) = rpcId; - *(long*)(bufferPtr + Packet.InnerPacketRouteRouteIdLocation) = routeId; - } - - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.Pack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.InnerPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > Packet.PacketBodyMaxLength) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {Packet.PacketBodyMaxLength} bytes"); - } - - fixed (byte* bufferPtr = memoryStream.GetBuffer()) - { - *(int*)bufferPtr = packetBodyCount; - *(uint*)(bufferPtr + Packet.PacketLength) = opCode; - *(uint*)(bufferPtr + Packet.InnerPacketRpcIdLocation) = rpcId; - *(long*)(bufferPtr + Packet.InnerPacketRouteRouteIdLocation) = routeId; - } - - return memoryStream; - } - } -#endif - /// - /// 客户端和服务器之间专用的BufferPacketParser消息格式化器 - /// - public sealed class OuterBufferPacketParser : BufferPacketParser - { - /// - /// - /// - /// - /// - /// - /// - /// - public override unsafe bool UnPack(byte[] buffer, ref int count, out APackInfo packInfo) - { - packInfo = null; - - if (buffer.Length < count) - { - throw new ScanException($"The buffer length is less than the specified count. buffer.Length={buffer.Length} count={count}"); - } - - if (count < Packet.OuterPacketHeadLength) - { - // 如果内存资源中的数据长度小于内部消息头的长度,无法解析 - return false; - } - - fixed (byte* bufferPtr = buffer) - { - MessagePacketLength = *(int*)bufferPtr; - - if (MessagePacketLength > Packet.PacketBodyMaxLength || count < MessagePacketLength) - { - // 检查消息体长度是否超出限制 - throw new ScanException($"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - ProtocolCode = *(uint*)(bufferPtr + Packet.PacketLength); - RpcId = *(uint*)(bufferPtr + Packet.OuterPacketRpcIdLocation); - } - - packInfo = OuterPackInfo.Create(Network); - packInfo.RpcId = RpcId; - packInfo.ProtocolCode = ProtocolCode; - packInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, count).Write(buffer, 0, count); - return true; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, message) : Pack(ref rpcId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe MemoryStreamBuffer Pack(ref uint rpcId, MemoryStreamBuffer memoryStream) - { - fixed (byte* bufferPtr = memoryStream.GetBuffer()) - { - *(uint*)(bufferPtr + Packet.InnerPacketRpcIdLocation) = rpcId; - } - - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe MemoryStreamBuffer Pack(ref uint rpcId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.Pack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.OuterPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > Packet.PacketBodyMaxLength) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {Packet.PacketBodyMaxLength} bytes"); - } - - fixed (byte* bufferPtr = memoryStream.GetBuffer()) - { - *(int*)bufferPtr = packetBodyCount; - *(uint*)(bufferPtr + Packet.PacketLength) = opCode; - *(uint*)(bufferPtr + Packet.OuterPacketRpcIdLocation) = rpcId; - } - - return memoryStream; - } - } - /// - /// Webgl专用的客户端和服务器之间专用的BufferPacketParser消息格式化器 - /// - public sealed class OuterWebglBufferPacketParser : BufferPacketParser - { - /// - /// - /// - /// - /// - /// - /// - /// - public override bool UnPack(byte[] buffer, ref int count, out APackInfo packInfo) - { - packInfo = null; - - if (buffer.Length < count) - { - throw new ScanException($"The buffer length is less than the specified count. buffer.Length={buffer.Length} count={count}"); - } - - if (count < Packet.OuterPacketHeadLength) - { - // 如果内存资源中的数据长度小于内部消息头的长度,无法解析 - return false; - } - - MessagePacketLength = BitConverter.ToInt32(buffer, 0); - - if (MessagePacketLength > Packet.PacketBodyMaxLength || count < MessagePacketLength) - { - // 检查消息体长度是否超出限制 - throw new ScanException($"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - ProtocolCode = BitConverter.ToUInt32(buffer, Packet.PacketLength); - RpcId = BitConverter.ToUInt32(buffer, Packet.OuterPacketRpcIdLocation); - - packInfo = OuterPackInfo.Create(Network); - packInfo.RpcId = RpcId; - packInfo.ProtocolCode = ProtocolCode; - packInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, count).Write(buffer, 0, count); - return true; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, message) : Pack(ref rpcId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, MemoryStreamBuffer memoryStream) - { - var buffer = memoryStream.GetBuffer().AsSpan(); -#if FANTASY_NET - MemoryMarshal.Write(buffer.Slice(Packet.OuterPacketRpcIdLocation, sizeof(uint)), in rpcId); -#endif -#if FANTASY_UNITY - MemoryMarshal.Write(buffer.Slice(Packet.OuterPacketRpcIdLocation, sizeof(uint)), ref rpcId); -#endif - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private MemoryStreamBuffer Pack(ref uint rpcId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.UnPack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.OuterPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > Packet.PacketBodyMaxLength) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {Packet.PacketBodyMaxLength} bytes"); - } - - var buffer = memoryStream.GetBuffer().AsSpan(); -#if FANTASY_NET - MemoryMarshal.Write(buffer, in packetBodyCount); - MemoryMarshal.Write(buffer.Slice(Packet.PacketLength, sizeof(uint)), in opCode); - MemoryMarshal.Write(buffer.Slice(Packet.OuterPacketRpcIdLocation, sizeof(uint)), in rpcId); -#endif -#if FANTASY_UNITY - MemoryMarshal.Write(buffer, ref packetBodyCount); - MemoryMarshal.Write(buffer.Slice(Packet.PacketLength, sizeof(uint)), ref opCode); - MemoryMarshal.Write(buffer.Slice(Packet.OuterPacketRpcIdLocation, sizeof(uint)), ref rpcId); -#endif - return memoryStream; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/CircularBufferPacketParser.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/CircularBufferPacketParser.cs deleted file mode 100644 index 24c368b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/CircularBufferPacketParser.cs +++ /dev/null @@ -1,170 +0,0 @@ -// using System.Runtime.CompilerServices; -// // ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// -// namespace Fantasy -// { -// // 这个对处理分包和粘包逻辑不完整、考虑现在没有任何地方使用了、就先不修改了。 -// // 后面用到了再修改、现在这个只是留做备份、万一以后用到了呢。 -// public abstract class CircularBufferPacketParser : APacketParser -// { -// protected uint RpcId; -// protected long RouteId; -// protected uint ProtocolCode; -// protected int MessagePacketLength; -// protected bool IsUnPackHead = true; -// protected readonly byte[] MessageHead = new byte[Packet.InnerPacketHeadLength]; -// public abstract bool UnPack(CircularBuffer buffer, out APackInfo packInfo); -// } -// -// #if FANTASY_NET -// public sealed class InnerCircularBufferPacketParser : CircularBufferPacketParser, IInnerPacketParser -// { -// public override bool UnPack(CircularBuffer buffer, out APackInfo packInfo) -// { -// packInfo = null; -// -// // 在对象没有被释放的情况下循环解析数据 -// while (!IsDisposed) -// { -// if (IsUnPackHead) -// { -// // 如果缓冲区中的数据长度小于内部消息头的长度,无法解析 -// if (buffer.Length < Packet.InnerPacketHeadLength) -// { -// return false; -// } -// -// // 从缓冲区中读取内部消息头的数据 -// _ = buffer.Read(MessageHead, 0, Packet.InnerPacketHeadLength); -// MessagePacketLength = BitConverter.ToInt32(MessageHead, 0); -// -// // 检查消息体长度是否超出限制 -// if (MessagePacketLength > Packet.PacketBodyMaxLength) -// { -// throw new ScanException( -// $"The received information exceeds the maximum limit = {MessagePacketLength}"); -// } -// -// // 解析协议编号、RPC ID 和 Route ID -// ProtocolCode = BitConverter.ToUInt32(MessageHead, Packet.PacketLength); -// RpcId = BitConverter.ToUInt32(MessageHead, Packet.InnerPacketRpcIdLocation); -// RouteId = BitConverter.ToInt64(MessageHead, Packet.InnerPacketRouteRouteIdLocation); -// IsUnPackHead = false; -// } -// -// try -// { -// // 如果缓冲区中的数据长度小于消息体的长度,无法解析 -// if (MessagePacketLength < 0 || buffer.Length < MessagePacketLength) -// { -// return false; -// } -// -// IsUnPackHead = true; -// packInfo = InnerPackInfo.Create(Network); -// var memoryStream = packInfo.RentMemoryStream(MessagePacketLength); -// memoryStream.SetLength(MessagePacketLength); -// buffer.Read(memoryStream, MessagePacketLength); -// packInfo.RpcId = RpcId; -// packInfo.RouteId = RouteId; -// packInfo.ProtocolCode = ProtocolCode; -// packInfo.MessagePacketLength = MessagePacketLength; -// return true; -// } -// catch (Exception e) -// { -// // 在发生异常时,释放 packInfo 并记录日志 -// packInfo?.Dispose(); -// Log.Error(e); -// return false; -// } -// } -// -// return false; -// } -// -// public override MemoryStream Pack(ref uint rpcId, ref long routeTypeOpCode, ref long routeId, -// MemoryStream memoryStream, object message) -// { -// return memoryStream == null -// ? Pack(ref rpcId, ref routeId, message) -// : Pack(ref rpcId, ref routeId, memoryStream); -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private unsafe MemoryStream Pack(ref uint rpcId, ref long routeId, MemoryStream memoryStream) -// { -// var buffer = memoryStream.GetBuffer(); -// -// fixed (byte* bufferPtr = buffer) -// { -// var rpcIdPtr = bufferPtr + Packet.InnerPacketRpcIdLocation; -// var routeIdPtr = bufferPtr + Packet.InnerPacketRouteRouteIdLocation; -// *(uint*)rpcIdPtr = rpcId; -// *(long*)routeIdPtr = routeId; -// } -// -// memoryStream.Seek(0, SeekOrigin.Begin); -// return memoryStream; -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private unsafe MemoryStream Pack(ref uint rpcId, ref long routeId, object message) -// { -// var memoryStream = Network.RentMemoryStream(); -// memoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); -// -// switch (message) -// { -// case IBsonMessage: -// { -// MongoHelper.SerializeTo(message, memoryStream); -// break; -// } -// default: -// { -// ProtoBuffHelper.ToStream(message, memoryStream); -// break; -// } -// } -// -// var opCode = Scene.MessageDispatcherComponent.GetOpCode(message.GetType()); -// var packetBodyCount = (int)(memoryStream.Position - Packet.InnerPacketHeadLength); -// -// if (packetBodyCount == 0) -// { -// // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 -// // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 -// packetBodyCount = -1; -// } -// -// // 检查消息体长度是否超出限制 -// if (packetBodyCount > Packet.PacketBodyMaxLength) -// { -// throw new Exception($"Message content exceeds {Packet.PacketBodyMaxLength} bytes"); -// } -// -// var buffer = memoryStream.GetBuffer(); -// -// fixed (byte* bufferPtr = buffer) -// { -// var opCodePtr = bufferPtr + Packet.PacketLength; -// var rpcIdPtr = bufferPtr + Packet.InnerPacketRpcIdLocation; -// var routeIdPtr = bufferPtr + Packet.InnerPacketRouteRouteIdLocation; -// *(int*)bufferPtr = packetBodyCount; -// *(uint*)opCodePtr = opCode; -// *(uint*)rpcIdPtr = rpcId; -// *(long*)routeIdPtr = routeId; -// } -// -// memoryStream.Seek(0, SeekOrigin.Begin); -// return memoryStream; -// } -// } -// #endif -// } -// -// -// -// diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/OuterBufferPacketParserHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/OuterBufferPacketParserHelper.cs deleted file mode 100644 index a6e66ca..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/OuterBufferPacketParserHelper.cs +++ /dev/null @@ -1,72 +0,0 @@ -#if FANTASY_NET -using System.Runtime.CompilerServices; -using Fantasy.Helper; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Serialize; - -namespace Fantasy.PacketParser -{ - /// - /// 打包Outer消息的帮助类 - /// - public static class OuterBufferPacketParserHelper - { - /// - /// 打包一个网络消息 - /// - /// scene - /// 如果是RPC消息需要传递一个rpcId - /// 打包的网络消息 - /// 序列化后流的长度 - /// 打包完成会返回一个MemoryStreamBuffer - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe MemoryStreamBuffer Pack(Scene scene, uint rpcId, IMessage message, out int memoryStreamLength) - { - memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = new MemoryStreamBuffer(); - memoryStream.MemoryStreamBufferSource = MemoryStreamBufferSource.Pack; - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.OuterPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > Packet.PacketBodyMaxLength) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {Packet.PacketBodyMaxLength} bytes"); - } - - fixed (byte* bufferPtr = memoryStream.GetBuffer()) - { - *(int*)bufferPtr = packetBodyCount; - *(uint*)(bufferPtr + Packet.PacketLength) = opCode; - *(uint*)(bufferPtr + Packet.OuterPacketRpcIdLocation) = rpcId; - } - - return memoryStream; - } - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/ReadOnlyMemoryPacketParser.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/ReadOnlyMemoryPacketParser.cs deleted file mode 100644 index 758ec17..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Handler/ReadOnlyMemoryPacketParser.cs +++ /dev/null @@ -1,357 +0,0 @@ -using System; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Helper; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.PacketParser -{ - internal abstract class ReadOnlyMemoryPacketParser : APacketParser - { - /// - /// 一个网络消息包 - /// - protected APackInfo PackInfo; - - protected int Offset; - protected int MessageHeadOffset; - protected int MessageBodyOffset; - protected int MessagePacketLength; - protected bool IsUnPackHead = true; - protected readonly byte[] MessageHead = new byte[20]; - public ReadOnlyMemoryPacketParser() { } - - public abstract bool UnPack(ref ReadOnlyMemory buffer, out APackInfo packInfo); - - public override void Dispose() - { - Offset = 0; - MessageHeadOffset = 0; - MessageBodyOffset = 0; - MessagePacketLength = 0; - IsUnPackHead = true; - PackInfo = null; - Array.Clear(MessageHead, 0, 20); - base.Dispose(); - } - } - -#if FANTASY_NET - internal sealed class InnerReadOnlyMemoryPacketParser : ReadOnlyMemoryPacketParser - { - public override unsafe bool UnPack(ref ReadOnlyMemory buffer, out APackInfo packInfo) - { - packInfo = null; - var readOnlySpan = buffer.Span; - var bufferLength = buffer.Length - Offset; - - if (bufferLength == 0) - { - // 没有剩余的数据需要处理、等待下一个包再处理。 - Offset = 0; - return false; - } - - if (IsUnPackHead) - { - fixed (byte* bufferPtr = readOnlySpan) - fixed (byte* messagePtr = MessageHead) - { - // 在当前buffer中拿到包头的数据 - var innerPacketHeadLength = Packet.InnerPacketHeadLength - MessageHeadOffset; - var copyLength = Math.Min(bufferLength, innerPacketHeadLength); - Buffer.MemoryCopy(bufferPtr + Offset, messagePtr + MessageHeadOffset, innerPacketHeadLength, copyLength); - Offset += copyLength; - MessageHeadOffset += copyLength; - // 检查是否有完整包头 - if (MessageHeadOffset == Packet.InnerPacketHeadLength) - { - // 通过指针直接读取协议编号、messagePacketLength protocolCode rpcId routeId - MessagePacketLength = *(int*)messagePtr; - // 检查消息体长度是否超出限制 - if (MessagePacketLength > Packet.PacketBodyMaxLength) - { - throw new ScanException($"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - PackInfo = InnerPackInfo.Create(Network); - var memoryStream = PackInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, Packet.InnerPacketHeadLength + MessagePacketLength); - PackInfo.RpcId = *(uint*)(messagePtr + Packet.InnerPacketRpcIdLocation); - PackInfo.ProtocolCode = *(uint*)(messagePtr + Packet.PacketLength); - PackInfo.RouteId = *(long*)(messagePtr + Packet.InnerPacketRouteRouteIdLocation); - memoryStream.Write(MessageHead); - IsUnPackHead = false; - bufferLength -= copyLength; - MessageHeadOffset = 0; - } - else - { - Offset = 0; - return false; - } - } - } - - if (MessagePacketLength == -1) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packInfo = PackInfo; - PackInfo = null; - IsUnPackHead = true; - return true; - } - - if (bufferLength == 0) - { - // 没有剩余的数据需要处理、等待下一个包再处理。 - Offset = 0; - return false; - } - - // 处理包消息体 - var innerPacketBodyLength = MessagePacketLength - MessageBodyOffset; - var copyBodyLength = Math.Min(bufferLength, innerPacketBodyLength); - // 写入数据到消息体中 - PackInfo.MemoryStream.Write(readOnlySpan.Slice(Offset, copyBodyLength)); - Offset += copyBodyLength; - MessageBodyOffset += copyBodyLength; - // 检查是否是完整的消息体 - if (MessageBodyOffset == MessagePacketLength) - { - packInfo = PackInfo; - PackInfo = null; - IsUnPackHead = true; - MessageBodyOffset = 0; - return true; - } - Offset = 0; - return false; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, ref routeId, message) : Pack(ref rpcId, ref routeId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream) - { - fixed (byte* bufferPtr = memoryStream.GetBuffer()) - { - *(uint*)(bufferPtr + Packet.InnerPacketRpcIdLocation) = rpcId; - *(long*)(bufferPtr + Packet.InnerPacketRouteRouteIdLocation) = routeId; - } - - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.Pack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.InnerPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - // 其实可以不用设置-1、解包的时候判断如果是0也可以、但我仔细想了下,还是用-1代表更加清晰。 - packetBodyCount = -1; - } - - if (packetBodyCount > Packet.PacketBodyMaxLength) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {Packet.PacketBodyMaxLength} bytes"); - } - - fixed (byte* bufferPtr = memoryStream.GetBuffer()) - { - *(int*)bufferPtr = packetBodyCount; - *(uint*)(bufferPtr + Packet.PacketLength) = opCode; - *(uint*)(bufferPtr + Packet.InnerPacketRpcIdLocation) = rpcId; - *(long*)(bufferPtr + Packet.InnerPacketRouteRouteIdLocation) = routeId; - } - - return memoryStream; - } - } -#endif - internal sealed class OuterReadOnlyMemoryPacketParser : ReadOnlyMemoryPacketParser - { - public override unsafe bool UnPack(ref ReadOnlyMemory buffer, out APackInfo packInfo) - { - packInfo = null; - var readOnlySpan = buffer.Span; - var bufferLength = buffer.Length - Offset; - - if (bufferLength == 0) - { - // 没有剩余的数据需要处理、等待下一个包再处理。 - Offset = 0; - return false; - } - - if (IsUnPackHead) - { - fixed (byte* bufferPtr = readOnlySpan) - fixed (byte* messagePtr = MessageHead) - { - // 在当前buffer中拿到包头的数据 - var outerPacketHeadLength = Packet.OuterPacketHeadLength - MessageHeadOffset; - var copyLength = Math.Min(bufferLength, outerPacketHeadLength); - Buffer.MemoryCopy(bufferPtr + Offset, messagePtr + MessageHeadOffset, outerPacketHeadLength, copyLength); - Offset += copyLength; - MessageHeadOffset += copyLength; - // 检查是否有完整包头 - if (MessageHeadOffset == Packet.OuterPacketHeadLength) - { - // 通过指针直接读取协议编号、messagePacketLength protocolCode rpcId routeId - MessagePacketLength = *(int*)messagePtr; - // 检查消息体长度是否超出限制 - if (MessagePacketLength > Packet.PacketBodyMaxLength) - { - throw new ScanException($"The received information exceeds the maximum limit = {MessagePacketLength}"); - } - - PackInfo = OuterPackInfo.Create(Network); - PackInfo.ProtocolCode = *(uint*)(messagePtr + Packet.PacketLength); - PackInfo.RpcId = *(uint*)(messagePtr + Packet.OuterPacketRpcIdLocation); - var memoryStream = PackInfo.RentMemoryStream(MemoryStreamBufferSource.UnPack, Packet.OuterPacketHeadLength + MessagePacketLength); - memoryStream.Write(MessageHead); - IsUnPackHead = false; - bufferLength -= copyLength; - MessageHeadOffset = 0; - } - else - { - Offset = 0; - return false; - } - } - } - - if (MessagePacketLength == -1) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packInfo = PackInfo; - PackInfo = null; - IsUnPackHead = true; - return true; - } - - if (bufferLength == 0) - { - // 没有剩余的数据需要处理、等待下一个包再处理。 - Offset = 0; - return false; - } - // 处理包消息体 - var outerPacketBodyLength = MessagePacketLength - MessageBodyOffset; - var copyBodyLength = Math.Min(bufferLength, outerPacketBodyLength); - // 写入数据到消息体中 - PackInfo.MemoryStream.Write(readOnlySpan.Slice(Offset, copyBodyLength)); - Offset += copyBodyLength; - MessageBodyOffset += copyBodyLength; - // 检查是否是完整的消息体 - if (MessageBodyOffset == MessagePacketLength) - { - packInfo = PackInfo; - PackInfo = null; - IsUnPackHead = true; - MessageBodyOffset = 0; - return true; - } - - Offset = 0; - return false; - } - - public override MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - return memoryStream == null ? Pack(ref rpcId, message) : Pack(ref rpcId, memoryStream); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe MemoryStreamBuffer Pack(ref uint rpcId, MemoryStreamBuffer memoryStream) - { - fixed (byte* bufferPtr = memoryStream.GetBuffer()) - { - *(uint*)(bufferPtr + Packet.OuterPacketRpcIdLocation) = rpcId; - } - - return memoryStream; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe MemoryStreamBuffer Pack(ref uint rpcId, IMessage message) - { - var memoryStreamLength = 0; - var messageType = message.GetType(); - var memoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.Pack); - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{messageType} Does not support processing protocol"); - } - - var opCode = Scene.MessageDispatcherComponent.GetOpCode(messageType); - var packetBodyCount = memoryStreamLength - Packet.OuterPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > Packet.PacketBodyMaxLength) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {Packet.PacketBodyMaxLength} bytes"); - } - - fixed (byte* bufferPtr = memoryStream.GetBuffer()) - { - *(int*)bufferPtr = packetBodyCount; - *(uint*)(bufferPtr + Packet.PacketLength) = opCode; - *(uint*)(bufferPtr + Packet.OuterPacketRpcIdLocation) = rpcId; - } - - return memoryStream; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Interface/APackInfo.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Interface/APackInfo.cs deleted file mode 100644 index 1ea6d6b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Interface/APackInfo.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.IO; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.PacketParser.Interface -{ - public abstract class APackInfo : IDisposable - { - internal ANetwork Network; - - public uint RpcId; - public long RouteId; - public long PackInfoId; - public bool IsDisposed; - private uint _protocolCode; - - public uint ProtocolCode - { - get => _protocolCode; - set - { - _protocolCode = value; - OpCodeIdStruct = value; - } - } - public OpCodeIdStruct OpCodeIdStruct { get; private set; } - public MemoryStreamBuffer MemoryStream { get; protected set; } - public abstract object Deserialize(Type messageType); - public abstract MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0); - public virtual void Dispose() - { - if (IsDisposed) - { - return; - } - - RpcId = 0; - RouteId = 0; - PackInfoId = 0; - ProtocolCode = 0; - _protocolCode = 0; - OpCodeIdStruct = default; - - if (MemoryStream != null) - { - Network.MemoryStreamBufferPool.ReturnMemoryStream(MemoryStream); - MemoryStream = null; - } - - IsDisposed = true; - Network = null; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Interface/APacketParser.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Interface/APacketParser.cs deleted file mode 100644 index 579cf6f..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Interface/APacketParser.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using Fantasy.Network.Interface; -using Fantasy.Serialize; - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.PacketParser.Interface -{ - /// - /// 抽象的包解析器基类,用于解析网络通信数据包。 - /// - public abstract class APacketParser : IDisposable - { - internal Scene Scene; - internal ANetwork Network; - internal MessageDispatcherComponent MessageDispatcherComponent; - protected bool IsDisposed { get; private set; } - public abstract MemoryStreamBuffer Pack(ref uint rpcId, ref long routeId, MemoryStreamBuffer memoryStream, IMessage message); - public virtual void Dispose() - { - IsDisposed = true; - Scene = null; - MessageDispatcherComponent = null; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/OpCode.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/OpCode.cs deleted file mode 100644 index 27c5dbb..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/OpCode.cs +++ /dev/null @@ -1,125 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network -{ - public struct OpCodeIdStruct - { - // OpCodeIdStruct:5 + 4 + 23 = 32 - // +-------------------------+-------------------------------------------+-----------------------------+ - // | protocol(5) 最多31种类型 | OpCodeProtocolType(4) 最多15种不同的网络协议 | Index(23) 最多8388607个协议 | - // +-------------------------+-------------------------------------------+-----------------------------+ - public uint OpCodeProtocolType { get; private set; } - public uint Protocol { get; private set; } - public uint Index { get; private set; } - - public OpCodeIdStruct(uint opCodeProtocolType, uint protocol, uint index) - { - OpCodeProtocolType = opCodeProtocolType; - Protocol = protocol; - Index = index; - } - - public static implicit operator uint(OpCodeIdStruct opCodeIdStruct) - { - var result = opCodeIdStruct.Index; - result |= opCodeIdStruct.OpCodeProtocolType << 23; - result |= opCodeIdStruct.Protocol << 27; - return result; - } - - public static implicit operator OpCodeIdStruct(uint opCodeId) - { - var opCodeIdStruct = new OpCodeIdStruct() - { - Index = opCodeId & 0x7FFFFF - }; - opCodeId >>= 23; - opCodeIdStruct.OpCodeProtocolType = opCodeId & 0xF; - opCodeId >>= 4; - opCodeIdStruct.Protocol = opCodeId & 0x1F; - return opCodeIdStruct; - } - } - - public static class OpCodeProtocolType - { - public const uint Bson = 1; - public const uint ProtoBuf = 0; - } - - public static class OpCodeType - { - public const uint OuterMessage = 1; - public const uint OuterRequest = 2; - public const uint OuterResponse = 3; - - public const uint InnerMessage = 4; - public const uint InnerRequest = 5; - public const uint InnerResponse = 6; - - public const uint InnerRouteMessage = 7; - public const uint InnerRouteRequest = 8; - public const uint InnerRouteResponse = 9; - - public const uint OuterAddressableMessage = 10; - public const uint OuterAddressableRequest = 11; - public const uint OuterAddressableResponse = 12; - - public const uint InnerAddressableMessage = 13; - public const uint InnerAddressableRequest = 14; - public const uint InnerAddressableResponse = 15; - - public const uint OuterCustomRouteMessage = 16; - public const uint OuterCustomRouteRequest = 17; - public const uint OuterCustomRouteResponse = 18; - - public const uint OuterRoamingMessage = 19; - public const uint OuterRoamingRequest = 20; - public const uint OuterRoamingResponse = 21; - - public const uint InnerRoamingMessage = 22; - public const uint InnerRoamingRequest = 23; - public const uint InnerRoamingResponse = 24; - - public const uint OuterPingRequest = 30; - public const uint OuterPingResponse = 31; - } - - public static class OpCode - { - public static readonly uint BenchmarkMessage = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterMessage, 8388607); - public static readonly uint BenchmarkRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterRequest, 8388607); - public static readonly uint BenchmarkResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterResponse, 8388607); - public static readonly uint PingRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterPingRequest, 1); - public static readonly uint PingResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterPingResponse, 1); - public static readonly uint DefaultResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerResponse, 1); - public static readonly uint DefaultRouteResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 7); - public static readonly uint AddressableAddRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 1); - public static readonly uint AddressableAddResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 1); - public static readonly uint AddressableGetRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 2); - public static readonly uint AddressableGetResponse = Create(OpCodeProtocolType.ProtoBuf,OpCodeType.InnerRouteResponse,2); - public static readonly uint AddressableRemoveRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 3); - public static readonly uint AddressableRemoveResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 3); - public static readonly uint AddressableLockRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 4); - public static readonly uint AddressableLockResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 4); - public static readonly uint AddressableUnLockRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 5); - public static readonly uint AddressableUnLockResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 5); - public static readonly uint LinkRoamingRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 6); - public static readonly uint LinkRoamingResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 6); - public static readonly uint UnLinkRoamingRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 8); - public static readonly uint UnLinkRoamingResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 8); - public static readonly uint LockTerminusIdRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 9); - public static readonly uint LockTerminusIdResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 9); - public static readonly uint UnLockTerminusIdRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 10); - public static readonly uint UnLockTerminusIdResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 10); - public static readonly uint GetTerminusIdRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 11); - public static readonly uint GetTerminusIdResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 11); - - public static readonly uint TransferTerminusRequest = Create(OpCodeProtocolType.Bson, OpCodeType.InnerRouteRequest, 1); - public static readonly uint TransferTerminusResponse = Create(OpCodeProtocolType.Bson, OpCodeType.InnerRouteResponse, 1); - - public static uint Create(uint opCodeProtocolType, uint protocol, uint index) - { - return new OpCodeIdStruct(opCodeProtocolType, protocol, index); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Pack/InnerPackInfo.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Pack/InnerPackInfo.cs deleted file mode 100644 index e9870e7..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Pack/InnerPackInfo.cs +++ /dev/null @@ -1,79 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Pool; -using Fantasy.Serialize; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. -#if FANTASY_NET -namespace Fantasy.PacketParser -{ - public sealed class InnerPackInfo : APackInfo - { - private readonly Dictionary> _createInstances = new Dictionary>(); - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - var network = Network; - base.Dispose(); - network.ReturnInnerPackInfo(this); - } - - public static InnerPackInfo Create(ANetwork network) - { - var innerPackInfo = network.RentInnerPackInfo(); - innerPackInfo.Network = network; - innerPackInfo.IsDisposed = false; - return innerPackInfo; - } - - public override MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0) - { - return MemoryStream ??= Network.MemoryStreamBufferPool.RentMemoryStream(memoryStreamBufferSource, size); - } - - public override object Deserialize(Type messageType) - { - if (MemoryStream == null) - { - Log.Debug("Deserialize MemoryStream is null"); - return null; - } - - MemoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (MemoryStream.Length == 0) - { - if (_createInstances.TryGetValue(messageType, out var createInstance)) - { - return createInstance(); - } - - createInstance = CreateInstance.CreateObject(messageType); - _createInstances.Add(messageType, createInstance); - return createInstance(); - } - - if (SerializerManager.TryGetSerializer(OpCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - var obj = serializer.Deserialize(messageType, MemoryStream); - MemoryStream.Seek(0, SeekOrigin.Begin); - return obj; - } - - MemoryStream.Seek(0, SeekOrigin.Begin); - Log.Error($"protocolCode:{ProtocolCode} Does not support processing protocol"); - return null; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Pack/OuterPackInfo.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Pack/OuterPackInfo.cs deleted file mode 100644 index 8ce08b7..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Pack/OuterPackInfo.cs +++ /dev/null @@ -1,73 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using System; -using System.IO; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Serialize; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -namespace Fantasy.PacketParser -{ - public sealed class OuterPackInfo : APackInfo - { - public override void Dispose() - { - if (IsDisposed) - { - return; - } - var network = Network; - base.Dispose(); - network.ReturnOuterPackInfo(this); - } - - public static OuterPackInfo Create(ANetwork network) - { - var outerPackInfo = network.RentOuterPackInfo(); - outerPackInfo.Network = network; - outerPackInfo.IsDisposed = false; - return outerPackInfo; - } - - public override MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0) - { - if (MemoryStream == null) - { - MemoryStream = Network.MemoryStreamBufferPool.RentMemoryStream(memoryStreamBufferSource, size); - } - - return MemoryStream; - } - - /// - /// 将消息数据从内存反序列化为指定的消息类型实例。 - /// - /// 目标消息类型。 - /// 反序列化后的消息类型实例。 - public override object Deserialize(Type messageType) - { - if (MemoryStream == null) - { - Log.Debug("Deserialize MemoryStream is null"); - return null; - } - - MemoryStream.Seek(Packet.OuterPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(OpCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - var obj = serializer.Deserialize(messageType, MemoryStream); - MemoryStream.Seek(0, SeekOrigin.Begin); - return obj; - } - - MemoryStream.Seek(0, SeekOrigin.Begin); - Log.Error($"protocolCode:{ProtocolCode} Does not support processing protocol"); - return null; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Pack/ProcessPackInfo.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Pack/ProcessPackInfo.cs deleted file mode 100644 index f010858..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Pack/ProcessPackInfo.cs +++ /dev/null @@ -1,160 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Pool; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. -namespace Fantasy.PacketParser -{ - public sealed class ProcessPackInfo : APackInfo - { - private int _disposeCount; - public Type MessageType { get; private set; } - private static readonly ConcurrentQueue Caches = new ConcurrentQueue(); - private readonly ConcurrentDictionary> _createInstances = new ConcurrentDictionary>(); - - public override void Dispose() - { - if (--_disposeCount > 0 || IsDisposed) - { - return; - } - - _disposeCount = 0; - MessageType = null; - base.Dispose(); - - if (Caches.Count > 2000) - { - return; - } - - Caches.Enqueue(this); - } - - public static unsafe ProcessPackInfo Create(Scene scene, T message, int disposeCount, uint rpcId = 0, long routeId = 0) where T : IRouteMessage - { - if (!Caches.TryDequeue(out var packInfo)) - { - packInfo = new ProcessPackInfo(); - } - - var type = typeof(T); - var memoryStreamLength = 0; - packInfo._disposeCount = disposeCount; - packInfo.MessageType = type; - packInfo.IsDisposed = false; - var memoryStream = new MemoryStreamBuffer(); - memoryStream.MemoryStreamBufferSource = MemoryStreamBufferSource.Pack; - OpCodeIdStruct opCodeIdStruct = message.OpCode(); - memoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(type, message, memoryStream); - memoryStreamLength = (int)memoryStream.Position; - } - else - { - Log.Error($"type:{type} Does not support processing protocol"); - } - - var opCode = scene.MessageDispatcherComponent.GetOpCode(packInfo.MessageType); - var packetBodyCount = memoryStreamLength - Packet.InnerPacketHeadLength; - - if (packetBodyCount == 0) - { - // protoBuf做了一个优化、就是当序列化的对象里的属性和字段都为默认值的时候就不会序列化任何东西。 - // 为了TCP的分包和粘包、需要判定下是当前包数据不完整还是本应该如此、所以用-1代表。 - packetBodyCount = -1; - } - - if (packetBodyCount > Packet.PacketBodyMaxLength) - { - // 检查消息体长度是否超出限制 - throw new Exception($"Message content exceeds {Packet.PacketBodyMaxLength} bytes"); - } - - var buffer = memoryStream.GetBuffer(); - - fixed (byte* bufferPtr = buffer) - { - var opCodePtr = bufferPtr + Packet.PacketLength; - var rpcIdPtr = bufferPtr + Packet.InnerPacketRpcIdLocation; - var routeIdPtr = bufferPtr + Packet.InnerPacketRouteRouteIdLocation; - *(int*)bufferPtr = packetBodyCount; - *(uint*)opCodePtr = opCode; - *(uint*)rpcIdPtr = rpcId; - *(long*)routeIdPtr = routeId; - } - - memoryStream.Seek(0, SeekOrigin.Begin); - packInfo.MemoryStream = memoryStream; - return packInfo; - } - - public unsafe void Set(uint rpcId, long routeId) - { - var buffer = MemoryStream.GetBuffer(); - - fixed (byte* bufferPtr = buffer) - { - var rpcIdPtr = bufferPtr + Packet.InnerPacketRpcIdLocation; - var routeIdPtr = bufferPtr + Packet.InnerPacketRouteRouteIdLocation; - *(uint*)rpcIdPtr = rpcId; - *(long*)routeIdPtr = routeId; - } - - MemoryStream.Seek(0, SeekOrigin.Begin); - } - - public override MemoryStreamBuffer RentMemoryStream(MemoryStreamBufferSource memoryStreamBufferSource, int size = 0) - { - throw new NotImplementedException(); - } - - public override object Deserialize(Type messageType) - { - if (MemoryStream == null) - { - Log.Debug("Deserialize MemoryStream is null"); - return null; - } - - object obj = null; - MemoryStream.Seek(Packet.InnerPacketHeadLength, SeekOrigin.Begin); - - if (MemoryStream.Length == 0) - { - if (_createInstances.TryGetValue(messageType, out var createInstance)) - { - return createInstance(); - } - - createInstance = CreateInstance.CreateObject(messageType); - _createInstances.TryAdd(messageType, createInstance); - return createInstance(); - } - - if (SerializerManager.TryGetSerializer(OpCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - obj = serializer.Deserialize(messageType, MemoryStream); - MemoryStream.Seek(0, SeekOrigin.Begin); - return obj; - } - - MemoryStream.Seek(0, SeekOrigin.Begin); - Log.Error($"protocolCode:{ProtocolCode} Does not support processing protocol"); - return null; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Packet.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Packet.cs deleted file mode 100644 index 7198af7..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/Packet.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace Fantasy.PacketParser -{ - /// - /// 提供关于消息包的常量定义。 - /// - public struct Packet - { - /// - /// 消息体最大长度 - /// - public const int PacketBodyMaxLength = ushort.MaxValue * 16; - /// - /// 消息体长度在消息头占用的长度 - /// - public const int PacketLength = sizeof(int); - /// - /// 协议编号在消息头占用的长度 - /// - public const int ProtocolCodeLength = sizeof(uint); - /// - /// RouteId长度 - /// - public const int PacketRouteIdLength = sizeof(long); - /// - /// RpcId在消息头占用的长度 - /// - public const int RpcIdLength = sizeof(uint); - /// - /// OuterRPCId所在的位置 - /// - public const int OuterPacketRpcIdLocation = PacketLength + ProtocolCodeLength; - /// - /// InnerRPCId所在的位置 - /// - public const int InnerPacketRpcIdLocation = PacketLength + ProtocolCodeLength; - /// - /// RouteId所在的位置 - /// - public const int InnerPacketRouteRouteIdLocation = PacketLength + ProtocolCodeLength + RpcIdLength; - /// - /// 外网消息头长度(消息体长度在消息头占用的长度 + 协议编号在消息头占用的长度 + RPCId长度 + RouteId长度) - /// - public const int OuterPacketHeadLength = PacketLength + ProtocolCodeLength + RpcIdLength + PacketRouteIdLength; - /// - /// 内网消息头长度(消息体长度在消息头占用的长度 + 协议编号在消息头占用的长度 + RPCId长度 + RouteId长度) - /// - public const int InnerPacketHeadLength = PacketLength + ProtocolCodeLength + RpcIdLength + PacketRouteIdLength; - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/PacketParserFactory.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/PacketParserFactory.cs deleted file mode 100644 index 679f95d..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/PacketParser/PacketParserFactory.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; - -// ReSharper disable PossibleNullReferenceException -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. -namespace Fantasy.PacketParser -{ - internal static class PacketParserFactory - { -#if FANTASY_NET - internal static ReadOnlyMemoryPacketParser CreateServerReadOnlyMemoryPacket(ANetwork network) - { - ReadOnlyMemoryPacketParser readOnlyMemoryPacketParser = null; - - switch (network.NetworkTarget) - { - case NetworkTarget.Inner: - { - readOnlyMemoryPacketParser = new InnerReadOnlyMemoryPacketParser(); - break; - } - case NetworkTarget.Outer: - { - readOnlyMemoryPacketParser = new OuterReadOnlyMemoryPacketParser(); - break; - } - } - - readOnlyMemoryPacketParser.Scene = network.Scene; - readOnlyMemoryPacketParser.Network = network; - readOnlyMemoryPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return readOnlyMemoryPacketParser; - } - - public static BufferPacketParser CreateServerBufferPacket(ANetwork network) - { - BufferPacketParser bufferPacketParser = null; - - switch (network.NetworkTarget) - { - case NetworkTarget.Inner: - { - bufferPacketParser = new InnerBufferPacketParser(); - break; - } - case NetworkTarget.Outer: - { - bufferPacketParser = new OuterBufferPacketParser(); - break; - } - } - - bufferPacketParser.Scene = network.Scene; - bufferPacketParser.Network = network; - bufferPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return bufferPacketParser; - } -#endif - internal static ReadOnlyMemoryPacketParser CreateClientReadOnlyMemoryPacket(ANetwork network) - { - ReadOnlyMemoryPacketParser readOnlyMemoryPacketParser = null; - - switch (network.NetworkTarget) - { -#if FANTASY_NET - case NetworkTarget.Inner: - { - readOnlyMemoryPacketParser = new InnerReadOnlyMemoryPacketParser(); - break; - } -#endif - case NetworkTarget.Outer: - { - readOnlyMemoryPacketParser = new OuterReadOnlyMemoryPacketParser(); - break; - } - } - - readOnlyMemoryPacketParser.Scene = network.Scene; - readOnlyMemoryPacketParser.Network = network; - readOnlyMemoryPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return readOnlyMemoryPacketParser; - } - -#if !FANTASY_WEBGL - public static BufferPacketParser CreateClientBufferPacket(ANetwork network) - { - BufferPacketParser bufferPacketParser = null; - - switch (network.NetworkTarget) - { -#if FANTASY_NET - case NetworkTarget.Inner: - { - bufferPacketParser = new InnerBufferPacketParser(); - break; - } -#endif - case NetworkTarget.Outer: - { - bufferPacketParser = new OuterBufferPacketParser(); - break; - } - } - - bufferPacketParser.Scene = network.Scene; - bufferPacketParser.Network = network; - bufferPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return bufferPacketParser; - } -#endif - public static T CreateClient(ANetwork network) where T : APacketParser - { - var packetParserType = typeof(T); - - switch (network.NetworkTarget) - { -#if FANTASY_NET - case NetworkTarget.Inner: - { - APacketParser innerPacketParser = null; - - if (packetParserType == typeof(ReadOnlyMemoryPacketParser)) - { - innerPacketParser = new InnerReadOnlyMemoryPacketParser(); - } - else if (packetParserType == typeof(BufferPacketParser)) - { - innerPacketParser = new InnerBufferPacketParser(); - } - // else if(packetParserType == typeof(CircularBufferPacketParser)) - // { - // innerPacketParser = new InnerCircularBufferPacketParser(); - // } - - innerPacketParser.Scene = network.Scene; - innerPacketParser.Network = network; - innerPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return (T)innerPacketParser; - } -#endif - case NetworkTarget.Outer: - { - APacketParser outerPacketParser = null; - - if (packetParserType == typeof(ReadOnlyMemoryPacketParser)) - { - outerPacketParser = new OuterReadOnlyMemoryPacketParser(); - } - else if (packetParserType == typeof(BufferPacketParser)) - { -#if FANTASY_WEBGL - outerPacketParser = new OuterWebglBufferPacketParser(); -#else - outerPacketParser = new OuterBufferPacketParser(); -#endif - } - outerPacketParser.Scene = network.Scene; - outerPacketParser.Network = network; - outerPacketParser.MessageDispatcherComponent = network.Scene.MessageDispatcherComponent; - return (T)outerPacketParser; - } - default: - throw new ArgumentOutOfRangeException(); - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/ClientMessageScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/ClientMessageScheduler.cs deleted file mode 100644 index baf981a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/ClientMessageScheduler.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Scheduler -{ -#if FANTASY_UNITY || FANTASY_CONSOLE - /// - /// 提供了一个用于客户端网络消息调度和处理的抽象基类。 - /// - public sealed class ClientMessageScheduler : ANetworkMessageScheduler - { - public ClientMessageScheduler(Scene scene) : base(scene) { } - - public override async FTask Scheduler(Session session, APackInfo packInfo) - { - await FTask.CompletedTask; - switch (packInfo.OpCodeIdStruct.Protocol) - { - case OpCodeType.OuterMessage: - case OpCodeType.OuterRequest: - case OpCodeType.OuterAddressableMessage: - case OpCodeType.OuterAddressableRequest: - case OpCodeType.OuterCustomRouteMessage: - case OpCodeType.OuterCustomRouteRequest: - case OpCodeType.OuterRoamingMessage: - case OpCodeType.OuterRoamingRequest: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var message = packInfo.Deserialize(messageType); - MessageDispatcherComponent.MessageHandler(session, messageType, message, packInfo.RpcId, packInfo.ProtocolCode); - } - - return; - } - case OpCodeType.OuterResponse: - case OpCodeType.OuterPingResponse: - case OpCodeType.OuterAddressableResponse: - case OpCodeType.OuterCustomRouteResponse: - case OpCodeType.OuterRoamingResponse: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - // 这个一般是客户端Session.Call发送时使用的、目前这个逻辑只有Unity客户端时使用 - - var aResponse = (IResponse)packInfo.Deserialize(messageType); - - if (!session.RequestCallback.Remove(packInfo.RpcId, out var action)) - { - Log.Error($"not found rpc {packInfo.RpcId}, response message: {aResponse.GetType().Name}"); - return; - } - - action.SetResult(aResponse); - } - - return; - } - default: - { - packInfo.Dispose(); - throw new NotSupportedException($"Received unsupported message protocolCode:{packInfo.ProtocolCode}"); - } - } - } - } -#endif -#if FANTASY_NET - internal sealed class ClientMessageScheduler(Scene scene) : ANetworkMessageScheduler(scene) - { - public override FTask Scheduler(Session session, APackInfo packInfo) - { - throw new NotSupportedException($"ClientMessageScheduler Received unsupported message protocolCode:{packInfo.ProtocolCode}"); - } - } -#endif -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/InnerMessageScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/InnerMessageScheduler.cs deleted file mode 100644 index b1b55f6..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/InnerMessageScheduler.cs +++ /dev/null @@ -1,211 +0,0 @@ -#if FANTASY_NET -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using System.Runtime.CompilerServices; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.PacketParser.Interface; -#pragma warning disable CS8604 // Possible null reference argument. - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Scheduler -{ - /// - /// 提供了一个机制来调度和处理内部网络消息。 - /// - internal sealed class InnerMessageScheduler(Scene scene) : ANetworkMessageScheduler(scene) - { - public override async FTask Scheduler(Session session, APackInfo packInfo) - { - var protocol = packInfo.OpCodeIdStruct.Protocol; - - switch (protocol) - { - case OpCodeType.InnerMessage: - case OpCodeType.InnerRequest: - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - try - { - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var message = packInfo.Deserialize(messageType); - MessageDispatcherComponent.MessageHandler(session, messageType, message, packInfo.RpcId, packInfo.ProtocolCode); - } - catch (Exception e) - { - Log.Error($"ANetworkMessageScheduler OuterResponse error messageProtocolCode:{packInfo.ProtocolCode} messageType:{messageType} SessionId {session.Id} IsDispose {session.IsDisposed} {e}"); - } - finally - { - packInfo.Dispose(); - } - - return; - } - case OpCodeType.InnerResponse: - case OpCodeType.InnerRouteResponse: - case OpCodeType.InnerAddressableResponse: - case OpCodeType.InnerRoamingResponse: - case OpCodeType.OuterAddressableResponse: - case OpCodeType.OuterCustomRouteResponse: - case OpCodeType.OuterRoamingResponse: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - NetworkMessagingComponent.ResponseHandler(packInfo.RpcId, (IResponse)packInfo.Deserialize(messageType)); - } - - return; - } - case OpCodeType.InnerRouteMessage: - case OpCodeType.InnerAddressableMessage: - case OpCodeType.InnerRoamingMessage: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"InnerMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - if (!Scene.TryGetEntity(packInfo.RouteId, out var entity)) - { - Scene.MessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, packInfo.RpcId); - return; - } - - var obj = packInfo.Deserialize(messageType); - await Scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, (IMessage)obj, packInfo.RpcId); - } - - return; - } - case OpCodeType.InnerRouteRequest: - case OpCodeType.InnerAddressableRequest: - case OpCodeType.InnerRoamingRequest: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"InnerMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - if (!Scene.TryGetEntity(packInfo.RouteId, out var entity)) - { - Scene.MessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, packInfo.RpcId); - return; - } - - var obj = packInfo.Deserialize(messageType); - await Scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, (IMessage)obj, packInfo.RpcId); - } - - return; - } - case OpCodeType.OuterCustomRouteRequest: - case OpCodeType.OuterAddressableRequest: - case OpCodeType.OuterAddressableMessage: - case OpCodeType.OuterCustomRouteMessage: - case OpCodeType.OuterRoamingMessage: - case OpCodeType.OuterRoamingRequest: - { - var entity = Scene.GetEntity(packInfo.RouteId); - - switch (entity) - { - case null: - { - // 执行到这里有两种情况: - using (packInfo) - { - switch (Scene.SceneConfig.SceneTypeString) - { - case "Gate": - { - // 1、当前是Gate进行,需要转发消息给客户端,但当前这个Session已经断开了。 - // 这种情况不需要做任何处理。 - return; - } - default: - { - // 2、当前是其他Scene、消息通过Gate发送到这个Scene上面,但这个Scene上面没有这个Entity。 - // 因为这个是Gate转发消息到这个Scene的,如果没有找到Entity要返回错误给Gate。 - // 出现这个情况一定要打印日志,因为出现这个问题肯定是上层逻辑导致的,不应该出现这样的问题。 - var packInfoRouteId = packInfo.RouteId; - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - switch (protocol) - { - case OpCodeType.OuterCustomRouteRequest: - case OpCodeType.OuterAddressableRequest: - case OpCodeType.OuterAddressableMessage: - { - Scene.MessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, packInfo.RpcId); - return; - } - } - - throw new Exception($"The Entity associated with RouteId = {packInfoRouteId} was not found! messageType = {messageType.FullName} protocol = {protocol}"); - } - } - } - } - case Session gateSession: - { - using (packInfo) - { - // 这里如果是Session只可能是Gate的Session、如果是的话、肯定是转发消息 - gateSession.Send(packInfo.MemoryStream, packInfo.RpcId); - } - - return; - } - default: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"InnerMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var obj = packInfo.Deserialize(messageType); - await Scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, (IMessage)obj, packInfo.RpcId); - } - - return; - } - } - } - default: - { - var infoProtocolCode = packInfo.ProtocolCode; - packInfo.Dispose(); - throw new NotSupportedException($"InnerMessageScheduler Received unsupported message protocolCode:{infoProtocolCode}"); - } - } - } - } -} -#endif - diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/Interface/ANetworkMessageScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/Interface/ANetworkMessageScheduler.cs deleted file mode 100644 index b296cff..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/Interface/ANetworkMessageScheduler.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.IO; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -// ReSharper disable UnassignedField.Global -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -namespace Fantasy.Scheduler -{ - public abstract class ANetworkMessageScheduler - { - protected readonly Scene Scene; - protected readonly MessageDispatcherComponent MessageDispatcherComponent; -#if FANTASY_NET - protected readonly NetworkMessagingComponent NetworkMessagingComponent; -#endif - protected ANetworkMessageScheduler(Scene scene) - { - Scene = scene; - MessageDispatcherComponent = scene.MessageDispatcherComponent; -#if FANTASY_NET - NetworkMessagingComponent = scene.NetworkMessagingComponent; -#endif - } - public abstract FTask Scheduler(Session session, APackInfo packInfo); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/MessageHelper/MessageSender.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/MessageHelper/MessageSender.cs deleted file mode 100644 index c645183..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/MessageHelper/MessageSender.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Network.Interface; - -#pragma warning disable CS8625 -#pragma warning disable CS8618 - -namespace Fantasy.Scheduler -{ - /// - /// 网络消息发送者的类。 - /// - public struct MessageSender : IDisposable - { - /// - /// 获取或设置 RPC ID。 - /// - public uint RpcId { get; private set; } - /// - /// 获取或设置路由 ID。 - /// - public long RouteId { get; private set; } - /// - /// 获取或设置创建时间。 - /// - public long CreateTime { get; private set; } - /// - /// 获取或设置消息类型。 - /// - public Type MessageType { get; private set; } - /// - /// 获取或设置请求消息。 - /// - public IMessage Request { get; private set; } - /// - /// 获取或设置任务。 - /// - public FTask Tcs { get; private set; } - - /// - /// 释放资源。 - /// - public void Dispose() - { - RpcId = 0; - RouteId = 0; - CreateTime = 0; - Tcs = null; - Request = null; - MessageType = null; - } - - /// - /// 创建一个 实例。 - /// - /// RPC ID。 - /// 请求消息类型。 - /// 任务。 - /// 创建的 实例。 - public static MessageSender Create(uint rpcId, Type requestType, FTask tcs) - { - var routeMessageSender = new MessageSender(); - routeMessageSender.Tcs = tcs; - routeMessageSender.RpcId = rpcId; - routeMessageSender.MessageType = requestType; - routeMessageSender.CreateTime = TimeHelper.Now; - return routeMessageSender; - } - - /// - /// 创建一个 实例。 - /// - /// RPC ID。 - /// 请求消息。 - /// 任务。 - /// 创建的 实例。 - public static MessageSender Create(uint rpcId, IRequest request, FTask tcs) - { - var routeMessageSender = new MessageSender(); - routeMessageSender.Tcs = tcs; - routeMessageSender.RpcId = rpcId; - routeMessageSender.Request = request; - routeMessageSender.CreateTime = TimeHelper.Now; - return routeMessageSender; - } - - /// - /// 创建一个 实例。 - /// - /// RPC ID。 - /// 路由 ID。 - /// 路由消息请求。 - /// 任务。 - /// 创建的 实例。 - public static MessageSender Create(uint rpcId, long routeId, IRouteMessage request, FTask tcs) - { - var routeMessageSender = new MessageSender(); - routeMessageSender.Tcs = tcs; - routeMessageSender.RpcId = rpcId; - routeMessageSender.RouteId = routeId; - routeMessageSender.Request = request; - routeMessageSender.CreateTime = TimeHelper.Now; - return routeMessageSender; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/MessageHelper/NetworkMessagingComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/MessageHelper/NetworkMessagingComponent.cs deleted file mode 100644 index 7580dd9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/MessageHelper/NetworkMessagingComponent.cs +++ /dev/null @@ -1,273 +0,0 @@ -#if FANTASY_NET -using Fantasy.Entitas; -using System.Runtime.CompilerServices; -using Fantasy.Async; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Network.Route; -using Fantasy.PacketParser; -using Fantasy.PacketParser.Interface; -using Fantasy.Timer; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Scheduler -{ - public struct NetworkMessageUpdate - { - public NetworkMessagingComponent NetworkMessagingComponent; - } - - public class NetworkMessagingComponentAwakeSystem : AwakeSystem - { - protected override void Awake(NetworkMessagingComponent self) - { - var selfScene = self.Scene; - self.TimerComponent = selfScene.TimerComponent; - self.MessageDispatcherComponent = selfScene.MessageDispatcherComponent; - self.AddressableRouteMessageLock = selfScene.CoroutineLockComponent.Create(self.GetType().TypeHandle.Value.ToInt64()); - - self.TimerId = self.TimerComponent.Net.RepeatedTimer(10000, new NetworkMessageUpdate() - { - NetworkMessagingComponent = self - }); - } - } - - public class NetworkMessagingComponentDestroySystem : DestroySystem - { - protected override void Destroy(NetworkMessagingComponent self) - { - if (self.TimerId != 0) - { - self.TimerComponent.Net.Remove(ref self.TimerId); - } - - foreach (var (rpcId, messageSender) in self.RequestCallback.ToDictionary()) - { - self.ReturnMessageSender(rpcId, messageSender); - } - - self.AddressableRouteMessageLock.Dispose(); - - self.RequestCallback.Clear(); - self.TimeoutRouteMessageSenders.Clear(); - self.TimerComponent = null; - self.MessageDispatcherComponent = null; - self.AddressableRouteMessageLock = null; - } - } - public sealed class NetworkMessagingComponent : Entity - { - public long TimerId; - private uint _rpcId; - public CoroutineLock AddressableRouteMessageLock; - public TimerComponent TimerComponent; - public MessageDispatcherComponent MessageDispatcherComponent; - public readonly SortedDictionary RequestCallback = new(); - public readonly Dictionary TimeoutRouteMessageSenders = new(); - - public void SendInnerRoute(long routeId, IRouteMessage message) - { - if (routeId == 0) - { - Log.Error($"SendInnerRoute appId == 0"); - return; - } - - Scene.GetSession(routeId).Send(message, 0, routeId); - } - - internal void SendInnerRoute(long routeId, Type messageType, APackInfo packInfo) - { - if (routeId == 0) - { - Log.Error($"SendInnerRoute routeId == 0"); - return; - } - - Scene.GetSession(routeId).Send(0, routeId, messageType, packInfo); - } - - public void SendInnerRoute(ICollection routeIdCollection, IRouteMessage message) - { - if (routeIdCollection.Count <= 0) - { - Log.Error("SendInnerRoute routeIdCollection.Count <= 0"); - return; - } - - using var processPackInfo = ProcessPackInfo.Create(Scene, message, routeIdCollection.Count); - foreach (var routeId in routeIdCollection) - { - processPackInfo.Set(0, routeId); - Scene.GetSession(routeId).Send(processPackInfo, 0, routeId); - } - } - - public async FTask SendAddressable(long addressableId, IRouteMessage message) - { - await CallAddressable(addressableId, message); - } - - internal async FTask CallInnerRoute(long routeId, Type requestType, APackInfo packInfo) - { - if (routeId == 0) - { - Log.Error($"CallInnerRoute routeId == 0"); - return null; - } - - var rpcId = ++_rpcId; - var session = Scene.GetSession(routeId); - var requestCallback = FTask.Create(false); - RequestCallback.Add(rpcId, MessageSender.Create(rpcId, requestType, requestCallback)); - session.Send(rpcId, routeId, requestType, packInfo); - return await requestCallback; - } - - public async FTask CallInnerRouteBySession(Session session, long routeId, IRouteMessage request) - { - var rpcId = ++_rpcId; - var requestCallback = FTask.Create(false); - RequestCallback.Add(rpcId, MessageSender.Create(rpcId, request, requestCallback)); - session.Send(request, rpcId, routeId); - return await requestCallback; - } - - public async FTask CallInnerRoute(long routeId, IRouteMessage request) - { - if (routeId == 0) - { - Log.Error($"CallInnerRoute routeId == 0"); - return null; - } - - var rpcId = ++_rpcId; - var session = Scene.GetSession(routeId); - var requestCallback = FTask.Create(false); - RequestCallback.Add(rpcId, MessageSender.Create(rpcId, request, requestCallback)); - session.Send(request, rpcId, routeId); - return await requestCallback; - } - - public async FTask CallAddressable(long addressableId, IRouteMessage request) - { - var failCount = 0; - - using (await AddressableRouteMessageLock.Wait(addressableId, "CallAddressable")) - { - var addressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, addressableId); - - while (true) - { - if (addressableRouteId == 0) - { - addressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, addressableId); - } - - if (addressableRouteId == 0) - { - return MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoute); - } - - var iRouteResponse = await CallInnerRoute(addressableRouteId, request); - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrNotFoundRoute: - { - if (++failCount > 20) - { - Log.Error($"AddressableComponent.Call failCount > 20 route send message fail, routeId: {addressableRouteId} AddressableMessageComponent:{addressableId}"); - return iRouteResponse; - } - - await TimerComponent.Net.WaitAsync(500); - addressableRouteId = 0; - continue; - } - case InnerErrorCode.ErrRouteTimeout: - { - Log.Error($"CallAddressableRoute ErrorCode.ErrRouteTimeout Error:{iRouteResponse.ErrorCode} Message:{request}"); - return iRouteResponse; - } - default: - { - return iRouteResponse; - } - } - } - } - } - - public void ResponseHandler(uint rpcId, IResponse response) - { - if (!RequestCallback.Remove(rpcId, out var routeMessageSender)) - { - throw new Exception($"not found rpc, response.RpcId:{rpcId} response message: {response.GetType().Name} Process:{Scene.Process.Id} Scene:{Scene.SceneConfigId}"); - } - - ResponseHandler(routeMessageSender, response); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void ResponseHandler(MessageSender messageSender, IResponse response) - { - if (response.ErrorCode == InnerErrorCode.ErrRouteTimeout) - { -#if FANTASY_DEVELOP - messageSender.Tcs.SetException(new Exception($"Rpc error: request, 注意RouteId消息超时,请注意查看是否死锁或者没有reply: RouteId: {messageSender.RouteId} {messageSender.Request.ToJson()}, response: {response}")); -#else - messageSender.Tcs.SetException(new Exception($"Rpc error: request, 注意RouteId消息超时,请注意查看是否死锁或者没有reply: RouteId: {messageSender.RouteId} {messageSender.Request}, response: {response}")); -#endif - messageSender.Dispose(); - return; - } - - messageSender.Tcs.SetResult(response); - messageSender.Dispose(); - } - - public void ReturnMessageSender(uint rpcId, MessageSender messageSender) - { - try - { - switch (messageSender.Request) - { - case IRouteMessage iRouteMessage: - { - // IRouteMessage是个特殊的RPC协议、这里不处理就可以了。 - break; - } - case IRequest iRequest: - { - var response = MessageDispatcherComponent.CreateResponse(iRequest.GetType(), InnerErrorCode.ErrRpcFail); - var responseRpcId = messageSender.RpcId; - ResponseHandler(responseRpcId, response); - Log.Warning($"timeout rpcId:{rpcId} responseRpcId:{responseRpcId} {iRequest.ToJson()}"); - break; - } - default: - { - Log.Error(messageSender.Request != null - ? $"Unsupported protocol type {messageSender.Request.GetType()} rpcId:{rpcId} messageSender.Request != null" - : $"Unsupported protocol type:{messageSender.MessageType.FullName} rpcId:{rpcId}"); - RequestCallback.Remove(rpcId); - break; - } - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/MessageHelper/OnNetworkMessageUpdateCheckTimeout.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/MessageHelper/OnNetworkMessageUpdateCheckTimeout.cs deleted file mode 100644 index 7dd2ea3..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/MessageHelper/OnNetworkMessageUpdateCheckTimeout.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Fantasy.Helper; -using Fantasy.Timer; - -#if FANTASY_NET -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -namespace Fantasy.Scheduler -{ - /// - /// 网络消息更新检查超时。 - /// - public sealed class OnNetworkMessageUpdateCheckTimeout : TimerHandler - { - /// - /// 超时时间(毫秒)。 - /// - private const long Timeout = 40000; - - /// - /// 处理网络消息更新检查超时。 - /// - /// - /// - protected override void Handler(NetworkMessageUpdate self) - { - var timeNow = TimeHelper.Now; - var selfNetworkMessagingComponent = self.NetworkMessagingComponent; - - // 遍历请求回调字典,检查是否有超时的请求,将超时请求添加到超时消息发送列表中。 - - foreach (var (rpcId, value) in selfNetworkMessagingComponent.RequestCallback) - { - if (timeNow < value.CreateTime + Timeout) - { - break; - } - - selfNetworkMessagingComponent.TimeoutRouteMessageSenders.Add(rpcId, value); - } - - // 如果没有超时的请求,直接返回。 - - if (selfNetworkMessagingComponent.TimeoutRouteMessageSenders.Count == 0) - { - return; - } - - // 处理超时的请求,根据请求类型生成相应的响应消息,并进行处理。 - - foreach (var (rpcId, routeMessageSender) in selfNetworkMessagingComponent.TimeoutRouteMessageSenders) - { - selfNetworkMessagingComponent.ReturnMessageSender(rpcId, routeMessageSender); - } - - // 清空超时消息发送列表。 - - selfNetworkMessagingComponent.TimeoutRouteMessageSenders.Clear(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/OuterMessageScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/OuterMessageScheduler.cs deleted file mode 100644 index 2c963ff..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Message/Scheduler/OuterMessageScheduler.cs +++ /dev/null @@ -1,366 +0,0 @@ -using System; -using Fantasy.Async; -using Fantasy.Network; -using Fantasy.PacketParser.Interface; -#if FANTASY_NET -using System.Text; -using Fantasy.Network.Interface; -using Fantasy.Network.Route; -using Fantasy.PacketParser; -using Fantasy.Helper; -using Fantasy.InnerMessage; -using Fantasy.Roaming; -#endif - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -namespace Fantasy.Scheduler -{ - /// - /// 提供了一个机制来调度和处理外部网络消息。 - /// -#if FANTASY_UNITY - public sealed class OuterMessageScheduler : ANetworkMessageScheduler - { - public OuterMessageScheduler(Scene scene) : base(scene) { } - - /// - /// 在Unity环境下,处理外部消息的方法。 - /// - /// 网络会话。 - /// 消息封包信息。 - public override FTask Scheduler(Session session, APackInfo packInfo) - { - throw new NotSupportedException($"Received unsupported message protocolCode:{packInfo.ProtocolCode}"); - } - } -#endif -#if FANTASY_NET - internal sealed class OuterMessageScheduler(Scene scene) : ANetworkMessageScheduler(scene) - { - private readonly PingResponse _pingResponse = new PingResponse(); - public override async FTask Scheduler(Session session, APackInfo packInfo) - { - if (session.IsDisposed) - { - return; - } - - switch (packInfo.OpCodeIdStruct.Protocol) - { - case OpCodeType.OuterPingRequest: - { - // 注意心跳目前只有外网才才会有、内网之间不需要心跳。 - - session.LastReceiveTime = TimeHelper.Now; - _pingResponse.Now = session.LastReceiveTime; - - using (packInfo) - { - session.Send(_pingResponse, packInfo.RpcId); - } - - return; - } - case OpCodeType.OuterMessage: - case OpCodeType.OuterRequest: - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - try - { - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var message = packInfo.Deserialize(messageType); - MessageDispatcherComponent.MessageHandler(session, messageType, message, packInfo.RpcId, packInfo.ProtocolCode); - } - catch (Exception e) - { - Log.Error($"ANetworkMessageScheduler OuterResponse error messageProtocolCode:{packInfo.ProtocolCode} messageType:{messageType} SessionId {session.Id} IsDispose {session.IsDisposed} {e}"); - } - finally - { - packInfo.Dispose(); - } - - return; - } - case OpCodeType.OuterResponse: - { - using (packInfo) - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - NetworkMessagingComponent.ResponseHandler(packInfo.RpcId, (IResponse)packInfo.Deserialize(messageType)); - } - - return; - } - case OpCodeType.OuterAddressableMessage: - { - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var addressableRouteComponent = session.AddressableRouteComponent; - - if (addressableRouteComponent == null) - { - throw new Exception("OuterMessageScheduler error session does not have an AddressableRouteComponent component"); - } - - await addressableRouteComponent.Send(messageType, packInfo); - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterAddressableRequest: - { - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var addressableRouteComponent = session.AddressableRouteComponent; - - if (addressableRouteComponent == null) - { - throw new Exception("OuterMessageScheduler error session does not have an AddressableRouteComponent component"); - } - - var rpcId = packInfo.RpcId; - var runtimeId = session.RuntimeId; - var response = await addressableRouteComponent.Call(messageType, packInfo); - // session可能已经断开了,所以这里需要判断 - if (session.RuntimeId == runtimeId) - { - session.Send(response, rpcId); - } - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterCustomRouteMessage: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - if (!MessageDispatcherComponent.GetCustomRouteType(packInfoProtocolCode, out var routeType)) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var routeComponent = session.RouteComponent; - - if (routeComponent == null) - { - throw new Exception($"OuterMessageScheduler CustomRouteType session does not have an routeComponent component messageType:{messageType.FullName} ProtocolCode:{packInfo.ProtocolCode}"); - } - - if (!routeComponent.TryGetRouteId(routeType, out var routeId)) - { - throw new Exception($"OuterMessageScheduler RouteComponent cannot find RouteId with RouteType {routeType}"); - } - - NetworkMessagingComponent.SendInnerRoute(routeId, messageType, packInfo); - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterCustomRouteRequest: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - if (!MessageDispatcherComponent.GetCustomRouteType(packInfoProtocolCode, out var routeType)) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var routeComponent = session.RouteComponent; - - if (routeComponent == null) - { - throw new Exception("OuterMessageScheduler CustomRouteType session does not have an routeComponent component"); - } - - if (!routeComponent.TryGetRouteId(routeType, out var routeId)) - { - throw new Exception($"OuterMessageScheduler RouteComponent cannot find RouteId with RouteType {routeType}"); - } - - var rpcId = packInfo.RpcId; - var runtimeId = session.RuntimeId; - var response = await NetworkMessagingComponent.CallInnerRoute(routeId, messageType, packInfo); - // session可能已经断开了,所以这里需要判断 - if (session.RuntimeId == runtimeId) - { - session.Send(response, rpcId); - } - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterRoamingMessage: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - if (!MessageDispatcherComponent.GetCustomRouteType(packInfoProtocolCode, out var routeType)) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var sessionRoamingComponent = session.SessionRoamingComponent; - - if (sessionRoamingComponent == null) - { - throw new Exception($"OuterMessageScheduler Roaming session does not have an sessionRoamingComponent component messageType:{messageType.FullName} ProtocolCode:{packInfo.ProtocolCode}"); - } - - await sessionRoamingComponent.Send(routeType, messageType, packInfo); - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - case OpCodeType.OuterRoamingRequest: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - var packInfoPackInfoId = packInfo.PackInfoId; - - try - { - if (!MessageDispatcherComponent.GetCustomRouteType(packInfoProtocolCode, out var routeType)) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var messageType = MessageDispatcherComponent.GetOpCodeType(packInfo.ProtocolCode); - - if (messageType == null) - { - throw new Exception($"OuterMessageScheduler error 可能遭受到恶意发包或没有协议定义ProtocolCode ProtocolCode:{packInfo.ProtocolCode}"); - } - - var sessionRoamingComponent = session.SessionRoamingComponent; - - if (sessionRoamingComponent == null) - { - throw new Exception("OuterMessageScheduler Roaming session does not have an sessionRoamingComponent component"); - } - - var rpcId = packInfo.RpcId; - var runtimeId = session.RuntimeId; - var response = await sessionRoamingComponent.Call(routeType, messageType, packInfo); - // session可能已经断开了,所以这里需要判断 - if (session.RuntimeId == runtimeId) - { - session.Send(response, rpcId); - } - } - finally - { - if (packInfo.PackInfoId == packInfoPackInfoId) - { - packInfo.Dispose(); - } - } - - return; - } - default: - { - var ipAddress = session.IsDisposed ? "null" : session.RemoteEndPoint.ToString(); - packInfo.Dispose(); - throw new NotSupportedException($"OuterMessageScheduler Received unsupported message protocolCode:{packInfo.ProtocolCode}\n1、请检查该协议所在的程序集是否在框架初始化的时候添加到框架中。\n2、如果看到这个消息表示你有可能用的老版本的导出工具,请更换为最新的导出工具。\n IP地址:{ipAddress}"); - } - } - } - } -#endif -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Exception/ScanException.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Exception/ScanException.cs deleted file mode 100644 index 43c695a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Exception/ScanException.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace Fantasy.Network -{ - /// - /// 在扫描过程中发生的异常。 - /// - public class ScanException : Exception - { - /// - /// 初始化 类的新实例。 - /// - public ScanException() { } - - /// - /// 使用指定的错误消息初始化 类的新实例。 - /// - /// 错误消息。 - public ScanException(string msg) : base(msg) { } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/HTTP/HTTPServerNetwork.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/HTTP/HTTPServerNetwork.cs deleted file mode 100644 index 9ca4eba..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/HTTP/HTTPServerNetwork.cs +++ /dev/null @@ -1,128 +0,0 @@ -#if FANTASY_NET -using System.IO; -using System.Net; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.Network.Interface; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; - -#pragma warning disable CS8604 // Possible null reference argument. - -// ReSharper disable PossibleMultipleEnumeration - -namespace Fantasy.Network.HTTP -{ - /// - /// HTTP服务器 - /// - public sealed class HTTPServerNetwork : ANetwork - { - /// - /// 初始化入口 - /// - /// - /// - /// - public void Initialize(NetworkTarget networkTarget, string bindIp, int port) - { - base.Initialize(NetworkType.Server, NetworkProtocolType.HTTP, networkTarget); - - try - { - StartAsync(bindIp, port); - } - catch (HttpListenerException e) - { - if (e.ErrorCode == 5) - { - var sb = new StringBuilder(); - sb.AppendLine("CMD管理员中输入下面其中一个命令,具体根据您是HTTPS或HTTP决定:"); - sb.AppendLine($"HTTP请输入如下:netsh http add urlacl url=http://{bindIp}:{port}/ user=Everyone"); - sb.AppendLine($"HTTPS请输入如下:netsh http add urlacl url=https://{bindIp}:{port}/ user=Everyone"); - throw new Exception(sb.ToString(), e); - } - - Log.Error(e); - } - catch (Exception e) - { - Log.Error(e); - } - } - - private void StartAsync(string bindIp, int port) - { - var builder = WebApplication.CreateBuilder(); - // 配置日志级别为 Warning 或更高 - builder.Logging.ClearProviders(); - builder.Logging.AddConsole(); - builder.Logging.SetMinimumLevel(LogLevel.Warning); - // 将Scene注册到 DI 容器中,传递给控制器 - builder.Services.AddSingleton(Scene); - // 注册Scene同步过滤器 - builder.Services.AddScoped(); - // 注册控制器服务 - var addControllers = builder.Services.AddControllers() - .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = null; }); - foreach (var assembly in AssemblySystem.ForEachAssembly) - { - addControllers.AddApplicationPart(assembly); - } - var listenUrl = ""; - var app = builder.Build(); - // 检测当前路径下是否有证书文件 - var certificatePath = Path.Combine(AppContext.BaseDirectory, $"certificate{bindIp}{port}"); - if (Directory.Exists(certificatePath)) - { - // 加载包含证书链的 PEM 文件 - var pemCertChain = File.ReadAllText(Path.Combine(certificatePath, "chain.pem")); - var pemPrivateKey = File.ReadAllText(Path.Combine(certificatePath, "private-key.pem")); - // 配置 HTTPS 监听并使用证书 - builder.WebHost.ConfigureKestrel(kestrelServerOptions => - { - kestrelServerOptions.ConfigureHttpsDefaults(https => - { - https.ServerCertificate = X509Certificate2.CreateFromPem(pemCertChain, pemPrivateKey); - }); - }); - listenUrl = $"https://{bindIp}:{port}/"; - app.Urls.Add(listenUrl); - app.UseHttpsRedirection(); - } - else - { - // 不安全的HTTP地址 - listenUrl = $"http://{bindIp}:{port}/"; - app.Urls.Add(listenUrl); - } - // 启用开发者工具 - if (app.Environment.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - // 路由注册 - app.MapControllers(); - // 开启监听 - app.RunAsync(); - Log.Info($"SceneConfigId = {Scene.SceneConfigId} HTTPServer Listen {listenUrl}"); - } - - /// - /// 移除Channel - /// - /// - /// - public override void RemoveChannel(uint channelId) - { - throw new NotImplementedException(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/HTTP/SceneContextFilter.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/HTTP/SceneContextFilter.cs deleted file mode 100644 index 2688bdc..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/HTTP/SceneContextFilter.cs +++ /dev/null @@ -1,54 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Microsoft.AspNetCore.Mvc.Filters; - -namespace Fantasy.Network.HTTP; - -/// -/// 让所有实现SceneContextFilter的控制器,都在执行的Scene下执行 -/// -public sealed class SceneContextFilter : IAsyncActionFilter -{ - private readonly Scene _scene; - - /// - /// 构造函数 - /// - /// - public SceneContextFilter(Scene scene) - { - _scene = scene; - } - - /// - /// OnActionExecutionAsync - /// - /// - /// - /// - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) - { - var tcs = FTask.Create(); - - _scene.ThreadSynchronizationContext.Post(() => - { - Action().Coroutine(); - }); - - await tcs; - return; - - async FTask Action() - { - try - { - await next(); - } - finally - { - tcs.SetResult(); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/AClientNetwork.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/AClientNetwork.cs deleted file mode 100644 index 322c811..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/AClientNetwork.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.IO; -using Fantasy.Serialize; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.Interface -{ - /// - /// 抽象客户端网络基类。 - /// - public abstract class AClientNetwork : ANetwork, INetworkChannel - { - protected bool IsInit; - public Session Session { get; protected set; } - public abstract Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000); - public abstract void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message); - public override void Dispose() - { - IsInit = false; - - if (Session != null) - { - if (!Session.IsDisposed) - { - Session.Dispose(); - } - - Session = null; - } - - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/ANetwork.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/ANetwork.cs deleted file mode 100644 index fdb85f2..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/ANetwork.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using Fantasy.Entitas; -using Fantasy.PacketParser; -using Fantasy.Scheduler; -using Fantasy.Serialize; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.Interface -{ - /// - /// 抽象网络基类。 - /// - public abstract class ANetwork : Entity - { - private long _outerPackInfoId; - private Queue _outerPackInfoPool; - public readonly MemoryStreamBufferPool MemoryStreamBufferPool = new MemoryStreamBufferPool(); - - public NetworkType NetworkType { get; private set; } - public NetworkTarget NetworkTarget { get; private set; } - public NetworkProtocolType NetworkProtocolType { get; private set; } - public ANetworkMessageScheduler NetworkMessageScheduler { get; private set; } - - protected void Initialize(NetworkType networkType, NetworkProtocolType networkProtocolType, NetworkTarget networkTarget) - { - NetworkType = networkType; - NetworkTarget = networkTarget; - NetworkProtocolType = networkProtocolType; -#if FANTASY_NET - if (networkProtocolType == NetworkProtocolType.HTTP) - { - return; - } - if (networkTarget == NetworkTarget.Inner) - { - _innerPackInfoPool = new Queue(); - NetworkMessageScheduler = new InnerMessageScheduler(Scene); - return; - } -#endif - switch (networkType) - { - case NetworkType.Client: - { - _outerPackInfoPool = new Queue(); - NetworkMessageScheduler = new ClientMessageScheduler(Scene); - break; - } -#if FANTASY_NET - case NetworkType.Server: - { - _outerPackInfoPool = new Queue(); - NetworkMessageScheduler = new OuterMessageScheduler(Scene); - break; - } -#endif - } - } - - public abstract void RemoveChannel(uint channelId); - public OuterPackInfo RentOuterPackInfo() - { - if (_outerPackInfoPool.Count == 0) - { - return new OuterPackInfo() - { - PackInfoId = ++_outerPackInfoId - }; - } - - if (!_outerPackInfoPool.TryDequeue(out var outerPackInfo)) - { - return new OuterPackInfo() - { - PackInfoId = ++_outerPackInfoId - }; - } - - outerPackInfo.PackInfoId = ++_outerPackInfoId; - return outerPackInfo; - } - - public void ReturnOuterPackInfo(OuterPackInfo outerPackInfo) - { - if (_outerPackInfoPool.Count > 512) - { - // 池子里最多缓存256个、其实这样设置有点多了、其实用不了512个。 - // 反而设置越大内存会占用越多。 - return; - } - - _outerPackInfoPool.Enqueue(outerPackInfo); - } -#if FANTASY_NET - private long _innerPackInfoId; - private Queue _innerPackInfoPool; - public InnerPackInfo RentInnerPackInfo() - { - if (_innerPackInfoPool.Count == 0) - { - return new InnerPackInfo() - { - PackInfoId = ++_innerPackInfoId - }; - } - - if (!_innerPackInfoPool.TryDequeue(out var innerPackInfo)) - { - return new InnerPackInfo() - { - PackInfoId = ++_innerPackInfoId - }; - } - - innerPackInfo.PackInfoId = ++_innerPackInfoId; - return innerPackInfo; - } - - public void ReturnInnerPackInfo(InnerPackInfo innerPackInfo) - { - if (_innerPackInfoPool.Count > 256) - { - // 池子里最多缓存256个、其实这样设置有点多了、其实用不了256个。 - // 反而设置越大内存会占用越多。 - return; - } - - _innerPackInfoPool.Enqueue(innerPackInfo); - } -#endif - public override void Dispose() - { - NetworkType = NetworkType.None; - NetworkTarget = NetworkTarget.None; - NetworkProtocolType = NetworkProtocolType.None; - MemoryStreamBufferPool.Dispose(); - _outerPackInfoPool?.Clear(); -#if FANTASY_NET - _innerPackInfoPool?.Clear(); -#endif - base.Dispose(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/ANetworkServerChannel.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/ANetworkServerChannel.cs deleted file mode 100644 index 788a235..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/ANetworkServerChannel.cs +++ /dev/null @@ -1,55 +0,0 @@ -#if FANTASY_NET -using System.IO; -using System.Net; -using Fantasy.Serialize; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.Interface -{ - public abstract class ANetworkServerChannel : INetworkChannel - { - /// - /// 获取通道的唯一标识 ID。 - /// - public readonly uint Id; - /// - /// 获取通道的远程终端点。 - /// - public readonly EndPoint RemoteEndPoint; - /// - /// 获取或设置通道所属的场景。 - /// - public Scene Scene { get; protected set; } - /// - /// 获取或设置通道所属的会话。 - /// - public Session Session { get; protected set; } - /// - /// 获取通道是否已经被释放。 - /// - public bool IsDisposed { get; protected set; } - - protected ANetworkServerChannel(ANetwork network, uint id, EndPoint remoteEndPoint) - { - Id = id; - Scene = network.Scene; - RemoteEndPoint = remoteEndPoint; - Session = Session.Create(network.NetworkMessageScheduler, this, network.NetworkTarget); - } - - public virtual void Dispose() - { - IsDisposed = true; - - if (!Session.IsDisposed) - { - Session.Dispose(); - } - } - - public abstract void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/INetworkChannel.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/INetworkChannel.cs deleted file mode 100644 index 52f341a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/Interface/INetworkChannel.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.IO; -using Fantasy.Serialize; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Network.Interface -{ - public interface INetworkChannel : IDisposable - { - public Session Session { get;} - public bool IsDisposed { get;} - public void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/Kcp.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/Kcp.cs deleted file mode 100644 index aa1947d..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/Kcp.cs +++ /dev/null @@ -1,451 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Threading; -using kcp; -using static kcp.KCP; - -#pragma warning disable CS8601 -#pragma warning disable CS8602 -#pragma warning disable CS8625 - -// ReSharper disable ALL - -namespace KCP -{ - /// - /// Kcp callback - /// - /// KCP output destination - /// KCP output size (excluding reserved) - public delegate void KcpCallback(byte[] buffer, int length); - - /// - /// Kcp - /// - public sealed unsafe class Kcp : IDisposable - { - /// - /// Kcp - /// - private IKCPCB* _kcp; - - /// - /// Output function - /// - private KcpCallback _output; - - /// - /// Buffer - /// - private byte[] _buffer; - - /// - /// Reserved overhead - /// - private int _reserved; - - /// - /// Disposed - /// - private int _disposed; - - /// - /// Structure - /// - /// ConversationId - /// Output - /// Reserved overhead - public Kcp(uint conv, KcpCallback output, int reserved) - { - _kcp = ikcp_create(conv, reserved, ref _buffer); - _output = output; - _reserved = reserved; - } - - /// - /// Set - /// - public bool IsSet => _kcp != null; - - /// - /// Conversation id - /// - public uint ConversationId => _kcp->conv; - - /// - /// Maximum transmission unit - /// - public uint MaximumTransmissionUnit => _kcp->mtu; - - /// - /// Maximum segment size - /// - public uint MaximumSegmentSize => _kcp->mss; - - /// - /// Connection state - /// - public uint State => _kcp->state; - - /// - /// The sequence number of the first unacknowledged packet - /// - public uint SendUna => _kcp->snd_una; - - /// - /// The sequence number for the next packet to be sent - /// - public uint SendNext => _kcp->snd_nxt; - - /// - /// The sequence number for the next packet expected to be received - /// - public uint ReceiveNext => _kcp->rcv_nxt; - - /// - /// Slow start threshold for congestion control - /// - public uint SlowStartThreshold => _kcp->ssthresh; - - /// - /// Round-trip time variance - /// - public int RxRttval => _kcp->rx_rttval; - - /// - /// Smoothed round-trip time - /// - public int RxSrtt => _kcp->rx_srtt; - - /// - /// Retransmission timeout - /// - public int RxRto => _kcp->rx_rto; - - /// - /// Minimum retransmission timeout - /// - public int RxMinrto => _kcp->rx_minrto; - - /// - /// Send window size - /// - public uint SendWindowSize => _kcp->snd_wnd; - - /// - /// Receive window size - /// - public uint ReceiveWindowSize => _kcp->rcv_wnd; - - /// - /// Remote window size - /// - public uint RemoteWindowSize => _kcp->rmt_wnd; - - /// - /// Congestion window size - /// - public uint CongestionWindowSize => _kcp->cwnd; - - /// - /// Probe variable for fast recovery - /// - public uint Probe => _kcp->probe; - - /// - /// Current timestamp - /// - public uint Current => _kcp->current; - - /// - /// Flush interval - /// - public uint Interval => _kcp->interval; - - /// - /// Timestamp for the next flush - /// - public uint TimestampFlush => _kcp->ts_flush; - - /// - /// Number of retransmissions - /// - public uint Transmissions => _kcp->xmit; - - /// - /// Number of packets in the receive buffer - /// - public uint ReceiveBufferCount => _kcp->nrcv_buf; - - /// - /// Number of packets in the receive queue - /// - public uint ReceiveQueueCount => _kcp->nrcv_que; - - /// - /// Number of packets wait to receive - /// - public uint WaitReceiveCount => _kcp->nrcv_buf + _kcp->nrcv_que; - - /// - /// Number of packets in the send buffer - /// - public uint SendBufferCount => _kcp->nsnd_buf; - - /// - /// Number of packets in the send queue - /// - public uint SendQueueCount => _kcp->nsnd_que; - - /// - /// Number of packets wait to send - /// - public uint WaitSendCount => _kcp->nsnd_buf + _kcp->nsnd_que; - - /// - /// Whether Nagle's algorithm is disabled - /// - public uint NoDelay => _kcp->nodelay; - - /// - /// Whether the KCP connection has been updated - /// - public uint Updated => _kcp->updated; - - /// - /// Timestamp for the next probe - /// - public uint TimestampProbe => _kcp->ts_probe; - - /// - /// Probe wait time - /// - public uint ProbeWait => _kcp->probe_wait; - - /// - /// Incremental increase - /// - public uint Increment => _kcp->incr; - - /// - /// Pointer to the acknowledge list - /// - public uint* AckList => _kcp->acklist; - - /// - /// Count of acknowledges - /// - public uint AckCount => _kcp->ackcount; - - /// - /// Number of acknowledge blocks - /// - public uint AckBlock => _kcp->ackblock; - - /// - /// Buffer - /// - public byte[] Buffer => _buffer; - - /// - /// Fast resend trigger count - /// - public int FastResend => _kcp->fastresend; - - /// - /// Fast resend limit - /// - public int FastResendLimit => _kcp->fastlimit; - - /// - /// Whether congestion control is disabled - /// - public int NoCongestionWindow => _kcp->nocwnd; - - /// - /// Whether stream mode is enabled - /// - public int StreamMode => _kcp->stream; - - /// - /// Output function pointer - /// - public KcpCallback Output => _output; - - /// - /// Reserved overhead - /// - public int Reserved => _reserved; - - /// - /// Dispose - /// - public void Dispose() - { - if (Interlocked.CompareExchange(ref _disposed, 1, 0) != 0) - return; - ikcp_release(_kcp); - _kcp = null; - _output = null; - _buffer = null; - GC.SuppressFinalize(this); - } - - /// - /// Set output - /// - /// Output - public void SetOutput(KcpCallback output) => _output = output; - - /// - /// Destructure - /// - ~Kcp() => Dispose(); - - /// - /// Send - /// - /// Buffer - /// Sent bytes - public int Send(ReadOnlySpan buffer) - { - fixed (byte* pinnedBuffer = &MemoryMarshal.GetReference(buffer)) - { - return ikcp_send(_kcp, pinnedBuffer, buffer.Length); - } - } - - /// - /// Send - /// - /// Buffer - /// Length - /// Sent bytes - public int Send(byte* buffer, int length) => ikcp_send(_kcp, buffer, length); - - /// - /// Input - /// - /// Buffer - /// Input bytes - public int Input(ReadOnlySpan buffer) - { - fixed (byte* pinnedBuffer = &MemoryMarshal.GetReference(buffer)) - { - return ikcp_input(_kcp, pinnedBuffer, buffer.Length); - } - } - - /// - /// Input - /// - /// Buffer - /// Length - /// Input bytes - public int Input(byte* buffer, int length) => ikcp_input(_kcp, buffer, length); - - /// - /// Peek size - /// - /// Peeked size - public int PeekSize() => ikcp_peeksize(_kcp); - - /// - /// Receive - /// - /// Buffer - /// Received bytes - public int Receive(Span buffer) - { - fixed (byte* pinnedBuffer = &MemoryMarshal.GetReference(buffer)) - { - return ikcp_recv(_kcp, pinnedBuffer, buffer.Length); - } - } - - /// - /// Receive - /// - /// Buffer - /// Length - /// Received bytes - public int Receive(byte* buffer, int length) => ikcp_recv(_kcp, buffer, length); - - /// - /// Update - /// - /// Timestamp - public void Update(uint current) - { - fixed (byte* ptr = &_buffer[_reserved]) - { - ikcp_update(_kcp, current, ptr, _buffer, _output); - } - } - - /// - /// Check - /// - /// Timestamp - /// Next flush timestamp - public uint Check(uint current) => ikcp_check(_kcp, current); - - /// - /// Flush - /// - public void Flush() - { - fixed (byte* ptr = &_buffer[_reserved]) - { - ikcp_flush(_kcp, ptr, _buffer, _output); - } - } - - /// - /// Set maximum transmission unit - /// - /// Maximum transmission unit - /// Set - public int SetMtu(int mtu) => ikcp_setmtu(_kcp, mtu, _reserved, ref _buffer); - - /// - /// Set flush interval - /// - /// Flush interval - public void SetInterval(int interval) => ikcp_interval(_kcp, interval); - - /// - /// Set no delay - /// - /// Whether Nagle's algorithm is disabled - /// Flush interval - /// Fast resend trigger count - /// No congestion window - public void SetNoDelay(int nodelay, int interval, int resend, int nc) => ikcp_nodelay(_kcp, nodelay, interval, resend, nc); - - /// - /// Set window size - /// - /// Send window size - /// Receive window size - public void SetWindowSize(int sndwnd, int rcvwnd) => ikcp_wndsize(_kcp, sndwnd, rcvwnd); - - /// - /// Set fast resend limit - /// - /// Fast resend limit - public void SetFastResendLimit(int fastlimit) => _kcp->fastlimit = Math.Clamp(fastlimit, 0, 5); - - /// - /// Set whether stream mode is enabled - /// - /// Whether stream mode is enabled - public void SetStreamMode(int stream) => _kcp->stream = stream == 1 ? 1 : 0; - - /// - /// Set minimum retransmission timeout - /// - /// Minimum retransmission timeout - public void SetMinrto(int minrto) => _kcp->rx_minrto = (int)Math.Clamp(minrto, 1, IKCP_RTO_MAX); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/c/kcp.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/c/kcp.cs deleted file mode 100644 index a202cfd..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/c/kcp.cs +++ /dev/null @@ -1,1367 +0,0 @@ -#if NET6_0_OR_GREATER -using System.Numerics; -#endif -using System.Runtime.CompilerServices; -using KCP; - -#pragma warning disable CA2211 -#pragma warning disable CS1591 -#pragma warning disable CS8602 -#pragma warning disable CS8632 - -// ReSharper disable ALL - -namespace kcp -{ - /// - /// https://github.com/skywind3000/kcp - /// - public static unsafe partial class KCP - { - //===================================================================== - // KCP BASIC - //===================================================================== - public const uint IKCP_RTO_NDL = 30; // no delay min rto - public const uint IKCP_RTO_MIN = 100; // normal min rto - public const uint IKCP_RTO_DEF = 200; - public const uint IKCP_RTO_MAX = 60000; - public const uint IKCP_CMD_PUSH = 81; // cmd: push data - public const uint IKCP_CMD_ACK = 82; // cmd: ack - public const uint IKCP_CMD_WASK = 83; // cmd: window probe (ask) - public const uint IKCP_CMD_WINS = 84; // cmd: window size (tell) - public const uint IKCP_ASK_SEND = 1; // need to send IKCP_CMD_WASK - public const uint IKCP_ASK_TELL = 2; // need to send IKCP_CMD_WINS - public const uint IKCP_WND_SND = 32; - public const uint IKCP_WND_RCV = 128; // must >= max fragment size - public const uint IKCP_MTU_DEF = 1400; - public const uint IKCP_ACK_FAST = 3; - public const uint IKCP_INTERVAL = 100; - public const uint IKCP_OVERHEAD = 24; - public const uint IKCP_DEADLINK = 20; - public const uint IKCP_THRESH_INIT = 2; - public const uint IKCP_THRESH_MIN = 2; - public const uint IKCP_PROBE_INIT = 7000; // 7 secs to probe window size - public const uint IKCP_PROBE_LIMIT = 120000; // up to 120 secs to probe window - public const uint IKCP_FASTACK_LIMIT = 5; // max times to trigger fastack - - //--------------------------------------------------------------------- - // encode / decode - //--------------------------------------------------------------------- - - /* encode 8 bits unsigned int */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_encode8u(byte* p, byte c) - { - *(byte*)p++ = c; - return p; - } - - /* decode 8 bits unsigned int */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_decode8u(byte* p, byte* c) - { - *c = *(byte*)p++; - return p; - } - - /* encode 16 bits unsigned int (lsb) */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_encode16u(byte* p, ushort w) - { -#if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN - *(byte*)(p + 0) = (byte)(w & 255); - *(byte*)(p + 1) = (byte)(w >> 8); -#else - memcpy(p, &w, (nuint)2); -#endif - p += 2; - return p; - } - - /* decode 16 bits unsigned int (lsb) */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_decode16u(byte* p, ushort* w) - { -#if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN - *w = *(byte*)(p + 1); - *w = (ushort)(*(byte*)(p + 0) + (*w << 8)); -#else - memcpy(w, p, (nuint)2); -#endif - p += 2; - return p; - } - - /* encode 32 bits unsigned int (lsb) */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_encode32u(byte* p, uint l) - { -#if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN - *(byte*)(p + 0) = (byte)((l >> 0) & 0xff); - *(byte*)(p + 1) = (byte)((l >> 8) & 0xff); - *(byte*)(p + 2) = (byte)((l >> 16) & 0xff); - *(byte*)(p + 3) = (byte)((l >> 24) & 0xff); -#else - memcpy(p, &l, (nuint)4); -#endif - p += 4; - return p; - } - - /* decode 32 bits unsigned int (lsb) */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte* ikcp_decode32u(byte* p, uint* l) - { -#if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN - *l = *(byte*)(p + 3); - *l = *(byte*)(p + 2) + (*l << 8); - *l = *(byte*)(p + 1) + (*l << 8); - *l = *(byte*)(p + 0) + (*l << 8); -#else - memcpy(l, p, (nuint)4); -#endif - p += 4; - return p; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint _imin_(uint a, uint b) - { - return a <= b ? a : b; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint _imax_(uint a, uint b) - { - return a >= b ? a : b; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint _ibound_(uint lower, uint middle, uint upper) - { - return _imin_(_imax_(lower, middle), upper); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint _iceilpow2_(uint x) - { -#if NET6_0_OR_GREATER - return BitOperations.RoundUpToPowerOf2(x); -#else - --x; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - ++x; - return x; -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long _itimediff(uint later, uint earlier) - { - return ((int)(later - earlier)); - } - - //--------------------------------------------------------------------- - // manage segment - //--------------------------------------------------------------------- - public static delegate* managed ikcp_malloc_hook = null; - public static delegate* managed ikcp_free_hook = null; - - // internal malloc - public static void* ikcp_malloc(nuint size) - { - if (ikcp_malloc_hook != null) - return ikcp_malloc_hook(size); - return malloc(size); - } - - // internal free - public static void ikcp_free(void* ptr) - { - if (ikcp_free_hook != null) - { - ikcp_free_hook(ptr); - } - else - { - free(ptr); - } - } - - // redefine allocator - public static void ikcp_allocator(delegate* managed new_malloc, delegate* managed new_free) - { - ikcp_malloc_hook = new_malloc; - ikcp_free_hook = new_free; - } - - // allocate a new kcp segment - public static IKCPSEG* ikcp_segment_new(IKCPCB* kcp, int size) - { - return (IKCPSEG*)ikcp_malloc((nuint)(sizeof(IKCPSEG) + size)); - } - - // delete a segment - public static void ikcp_segment_delete(IKCPCB* kcp, IKCPSEG* seg) - { - ikcp_free(seg); - } - - // output segment - public static void ikcp_output(IKCPCB* kcp, int size, byte[] destination, KcpCallback output) - { - assert(kcp != null); - assert(output != null); - - if (size == 0) return; - output(destination, size); - } - - //--------------------------------------------------------------------- - // create a new kcpcb - //--------------------------------------------------------------------- - public static IKCPCB* ikcp_create(uint conv, int reserved, ref byte[] buffer) - { - IKCPCB* kcp = (IKCPCB*)ikcp_malloc((nuint)sizeof(IKCPCB)); - if (kcp == null) return null; - kcp->conv = conv; - kcp->snd_una = 0; - kcp->snd_nxt = 0; - kcp->rcv_nxt = 0; - kcp->ts_recent = 0; - kcp->ts_lastack = 0; - kcp->ts_probe = 0; - kcp->probe_wait = 0; - kcp->snd_wnd = IKCP_WND_SND; - kcp->rcv_wnd = IKCP_WND_RCV; - kcp->rmt_wnd = IKCP_WND_RCV; - kcp->cwnd = 0; - kcp->incr = 0; - kcp->probe = 0; - kcp->mtu = IKCP_MTU_DEF; - kcp->mss = kcp->mtu - IKCP_OVERHEAD; - kcp->stream = 0; - - buffer = new byte[(reserved + kcp->mtu + IKCP_OVERHEAD) * 3]; - - iqueue_init(&kcp->snd_queue); - iqueue_init(&kcp->rcv_queue); - iqueue_init(&kcp->snd_buf); - iqueue_init(&kcp->rcv_buf); - kcp->nrcv_buf = 0; - kcp->nsnd_buf = 0; - kcp->nrcv_que = 0; - kcp->nsnd_que = 0; - kcp->state = 0; - kcp->acklist = null; - kcp->ackblock = 0; - kcp->ackcount = 0; - kcp->rx_srtt = 0; - kcp->rx_rttval = 0; - kcp->rx_rto = (int)IKCP_RTO_DEF; - kcp->rx_minrto = (int)IKCP_RTO_MIN; - kcp->current = 0; - kcp->interval = IKCP_INTERVAL; - kcp->ts_flush = IKCP_INTERVAL; - kcp->nodelay = 0; - kcp->updated = 0; - kcp->ssthresh = IKCP_THRESH_INIT; - kcp->fastresend = 0; - kcp->fastlimit = (int)IKCP_FASTACK_LIMIT; - kcp->nocwnd = 0; - kcp->xmit = 0; - kcp->dead_link = IKCP_DEADLINK; - - return kcp; - } - - //--------------------------------------------------------------------- - // release a new kcpcb - //--------------------------------------------------------------------- - public static void ikcp_release(IKCPCB* kcp) - { - assert(kcp != null); - if (kcp != null) - { - IKCPSEG* seg; - while (!iqueue_is_empty(&kcp->snd_buf)) - { - seg = iqueue_entry(kcp->snd_buf.next); - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - } - - while (!iqueue_is_empty(&kcp->rcv_buf)) - { - seg = iqueue_entry(kcp->rcv_buf.next); - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - } - - while (!iqueue_is_empty(&kcp->snd_queue)) - { - seg = iqueue_entry(kcp->snd_queue.next); - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - } - - while (!iqueue_is_empty(&kcp->rcv_queue)) - { - seg = iqueue_entry(kcp->rcv_queue.next); - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - } - - if (kcp->acklist != null) - { - ikcp_free(kcp->acklist); - } - - kcp->nrcv_buf = 0; - kcp->nsnd_buf = 0; - kcp->nrcv_que = 0; - kcp->nsnd_que = 0; - kcp->ackcount = 0; - kcp->acklist = null; - ikcp_free(kcp); - } - } - - //--------------------------------------------------------------------- - // user/upper level recv: returns size, returns below zero for EAGAIN - //--------------------------------------------------------------------- - public static int ikcp_recv(IKCPCB* kcp, byte* buffer, int len) - { - IQUEUEHEAD* p; - int ispeek = (len < 0) ? 1 : 0; - int peeksize; - int recover = 0; - IKCPSEG* seg; - assert(kcp != null); - - if (iqueue_is_empty(&kcp->rcv_queue)) - return -1; - - if (len < 0) len = -len; - - peeksize = ikcp_peeksize(kcp); - - if (peeksize < 0) - return -2; - - if (peeksize > len) - return -3; - - if (kcp->nrcv_que >= kcp->rcv_wnd) - recover = 1; - - // merge fragment - for (len = 0, p = kcp->rcv_queue.next; p != &kcp->rcv_queue;) - { - int fragment; - seg = iqueue_entry(p); - p = p->next; - - if (buffer != null) - { - memcpy(buffer, seg->data, (nuint)seg->len); - buffer += seg->len; - } - - len += (int)seg->len; - fragment = (int)seg->frg; - - if (ispeek == 0) - { - iqueue_del(&seg->node); - ikcp_segment_delete(kcp, seg); - kcp->nrcv_que--; - } - - if (fragment == 0) - break; - } - - assert(len == peeksize); - - // move available data from rcv_buf -> rcv_queue - while (!iqueue_is_empty(&kcp->rcv_buf)) - { - seg = iqueue_entry(kcp->rcv_buf.next); - if (seg->sn == kcp->rcv_nxt && kcp->nrcv_que < kcp->rcv_wnd) - { - iqueue_del(&seg->node); - kcp->nrcv_buf--; - iqueue_add_tail(&seg->node, &kcp->rcv_queue); - kcp->nrcv_que++; - kcp->rcv_nxt++; - } - else - { - break; - } - } - - // fast recover - if (kcp->nrcv_que < kcp->rcv_wnd && (recover != 0)) - { - // ready to send back IKCP_CMD_WINS in ikcp_flush - // tell remote my window size - kcp->probe |= IKCP_ASK_TELL; - } - - return len; - } - - //--------------------------------------------------------------------- - // peek data size - //--------------------------------------------------------------------- - public static int ikcp_peeksize(IKCPCB* kcp) - { - IQUEUEHEAD* p; - IKCPSEG* seg; - int length = 0; - - assert(kcp != null); - - if (iqueue_is_empty(&kcp->rcv_queue)) return -1; - - seg = iqueue_entry(kcp->rcv_queue.next); - if (seg->frg == 0) return (int)seg->len; - - if (kcp->nrcv_que < seg->frg + 1) return -1; - - for (p = kcp->rcv_queue.next; p != &kcp->rcv_queue; p = p->next) - { - seg = iqueue_entry(p); - length += (int)seg->len; - if (seg->frg == 0) break; - } - - return length; - } - - //--------------------------------------------------------------------- - // user/upper level send, returns below zero for error - //--------------------------------------------------------------------- - public static int ikcp_send(IKCPCB* kcp, byte* buffer, int len) - { - IKCPSEG* seg; - int count, i; - int sent = 0; - - assert(kcp->mss > 0); - if (len < 0) return -1; - - // append to previous segment in streaming mode (if possible) - if (kcp->stream != 0) - { - if (!iqueue_is_empty(&kcp->snd_queue)) - { - IKCPSEG* old = iqueue_entry(kcp->snd_queue.prev); - if (old->len < kcp->mss) - { - int capacity = (int)(kcp->mss - old->len); - int extend = (len < capacity) ? len : capacity; - seg = ikcp_segment_new(kcp, (int)(old->len + extend)); - assert(seg != null); - if (seg == null) - { - return -2; - } - - iqueue_add_tail(&seg->node, &kcp->snd_queue); - memcpy(seg->data, old->data, (nuint)old->len); - if (buffer != null) - { - memcpy(seg->data + old->len, buffer, (nuint)extend); - buffer += extend; - } - - seg->len = (uint)(old->len + extend); - seg->frg = 0; - len -= extend; - iqueue_del_init(&old->node); - ikcp_segment_delete(kcp, old); - sent = extend; - } - } - - if (len <= 0) - { - return sent; - } - } - - if (len <= (int)kcp->mss) count = 1; - else count = (int)((len + kcp->mss - 1) / kcp->mss); - - if (kcp->stream == 0 && count > 255) return -2; - - if (count >= (int)kcp->rcv_wnd) - { - if (kcp->stream != 0 && sent > 0) - return sent; - return -2; - } - - if (count == 0) count = 1; - - // fragment - for (i = 0; i < count; i++) - { - int size = len > (int)kcp->mss ? (int)kcp->mss : len; - seg = ikcp_segment_new(kcp, size); - assert(seg != null); - if (seg == null) - { - return -2; - } - - if ((buffer != null) && len > 0) - { - memcpy(seg->data, buffer, (nuint)size); - } - - seg->len = (uint)size; - seg->frg = (uint)((kcp->stream == 0) ? (count - i - 1) : 0); - iqueue_init(&seg->node); - iqueue_add_tail(&seg->node, &kcp->snd_queue); - kcp->nsnd_que++; - if (buffer != null) - { - buffer += size; - } - - len -= size; - sent += size; - } - - return sent; - } - - //--------------------------------------------------------------------- - // parse ack - //--------------------------------------------------------------------- - public static void ikcp_update_ack(IKCPCB* kcp, int rtt) - { - int rto = 0; - if (kcp->rx_srtt == 0) - { - kcp->rx_srtt = rtt; - kcp->rx_rttval = rtt / 2; - } - else - { - long delta = rtt - kcp->rx_srtt; - if (delta < 0) delta = -delta; - kcp->rx_rttval = (int)((3 * kcp->rx_rttval + delta) / 4); - kcp->rx_srtt = (7 * kcp->rx_srtt + rtt) / 8; - if (kcp->rx_srtt < 1) kcp->rx_srtt = 1; - } - - rto = (int)(kcp->rx_srtt + _imax_(kcp->interval, (uint)(4 * kcp->rx_rttval))); - kcp->rx_rto = (int)_ibound_((uint)kcp->rx_minrto, (uint)rto, IKCP_RTO_MAX); - } - - public static void ikcp_shrink_buf(IKCPCB* kcp) - { - IQUEUEHEAD* p = kcp->snd_buf.next; - if (p != &kcp->snd_buf) - { - IKCPSEG* seg = iqueue_entry(p); - kcp->snd_una = seg->sn; - } - else - { - kcp->snd_una = kcp->snd_nxt; - } - } - - public static void ikcp_parse_ack(IKCPCB* kcp, uint sn) - { - IQUEUEHEAD* p, next; - - if (_itimediff(sn, kcp->snd_una) < 0 || _itimediff(sn, kcp->snd_nxt) >= 0) - return; - - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) - { - IKCPSEG* seg = iqueue_entry(p); - next = p->next; - if (sn == seg->sn) - { - iqueue_del(p); - ikcp_segment_delete(kcp, seg); - kcp->nsnd_buf--; - break; - } - - if (_itimediff(sn, seg->sn) < 0) - { - break; - } - } - } - - public static void ikcp_parse_una(IKCPCB* kcp, uint una) - { - IQUEUEHEAD* p, next; - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) - { - IKCPSEG* seg = iqueue_entry(p); - next = p->next; - if (_itimediff(una, seg->sn) > 0) - { - iqueue_del(p); - ikcp_segment_delete(kcp, seg); - kcp->nsnd_buf--; - } - else - { - break; - } - } - } - - public static void ikcp_parse_fastack(IKCPCB* kcp, uint sn, uint ts) - { - IQUEUEHEAD* p, next; - - if (_itimediff(sn, kcp->snd_una) < 0 || _itimediff(sn, kcp->snd_nxt) >= 0) - return; - - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) - { - IKCPSEG* seg = iqueue_entry(p); - next = p->next; - if (_itimediff(sn, seg->sn) < 0) - { - break; - } - else if (sn != seg->sn) - { -#if !IKCP_FASTACK_CONSERVE - seg->fastack++; -#else - if (_itimediff(ts, seg->ts) >= 0) - seg->fastack++; -#endif - } - } - } - - //--------------------------------------------------------------------- - // ack append - //--------------------------------------------------------------------- - public static void ikcp_ack_push(IKCPCB* kcp, uint sn, uint ts) - { - uint newsize = kcp->ackcount + 1; - uint* ptr; - - if (newsize > kcp->ackblock) - { - uint* acklist; - uint newblock; - - newblock = newsize <= 8 ? 8 : _iceilpow2_(newsize); - acklist = (uint*)ikcp_malloc((nuint)(newblock * sizeof(uint) * 2)); - - if (acklist == null) - { - assert(acklist != null); - abort(); - } - - if (kcp->acklist != null) - { - uint x; - for (x = 0; x < kcp->ackcount; x++) - { - acklist[x * 2 + 0] = kcp->acklist[x * 2 + 0]; - acklist[x * 2 + 1] = kcp->acklist[x * 2 + 1]; - } - - ikcp_free(kcp->acklist); - } - - kcp->acklist = acklist; - kcp->ackblock = newblock; - } - - ptr = &kcp->acklist[kcp->ackcount * 2]; - ptr[0] = sn; - ptr[1] = ts; - kcp->ackcount++; - } - - public static void ikcp_ack_get(IKCPCB* kcp, int p, uint* sn, uint* ts) - { - if (sn != null) sn[0] = kcp->acklist[p * 2 + 0]; - if (ts != null) ts[0] = kcp->acklist[p * 2 + 1]; - } - - //--------------------------------------------------------------------- - // parse data - //--------------------------------------------------------------------- - public static void ikcp_parse_data(IKCPCB* kcp, IKCPSEG* newseg) - { - IQUEUEHEAD* p, prev; - uint sn = newseg->sn; - int repeat = 0; - - if (_itimediff(sn, kcp->rcv_nxt + kcp->rcv_wnd) >= 0 || - _itimediff(sn, kcp->rcv_nxt) < 0) - { - ikcp_segment_delete(kcp, newseg); - return; - } - - for (p = kcp->rcv_buf.prev; p != &kcp->rcv_buf; p = prev) - { - IKCPSEG* seg = iqueue_entry(p); - prev = p->prev; - if (seg->sn == sn) - { - repeat = 1; - break; - } - - if (_itimediff(sn, seg->sn) > 0) - { - break; - } - } - - if (repeat == 0) - { - iqueue_init(&newseg->node); - iqueue_add(&newseg->node, p); - kcp->nrcv_buf++; - } - else - { - ikcp_segment_delete(kcp, newseg); - } - - // move available data from rcv_buf -> rcv_queue - while (!iqueue_is_empty(&kcp->rcv_buf)) - { - IKCPSEG* seg = iqueue_entry(kcp->rcv_buf.next); - if (seg->sn == kcp->rcv_nxt && kcp->nrcv_que < kcp->rcv_wnd) - { - iqueue_del(&seg->node); - kcp->nrcv_buf--; - iqueue_add_tail(&seg->node, &kcp->rcv_queue); - kcp->nrcv_que++; - kcp->rcv_nxt++; - } - else - { - break; - } - } - } - - //--------------------------------------------------------------------- - // input data - //--------------------------------------------------------------------- - public static int ikcp_input(IKCPCB* kcp, byte* data, long size) - { - uint prev_una = kcp->snd_una; - uint maxack = 0, latest_ts = 0; - int flag = 0; - - if (data == null || (int)size < (int)IKCP_OVERHEAD) return -1; - - while (true) - { - uint ts, sn, len, una, conv; - ushort wnd; - byte cmd, frg; - IKCPSEG* seg; - - if (size < (int)IKCP_OVERHEAD) break; - - data = ikcp_decode32u(data, &conv); - if (conv != kcp->conv) return -1; - - data = ikcp_decode8u(data, &cmd); - data = ikcp_decode8u(data, &frg); - data = ikcp_decode16u(data, &wnd); - data = ikcp_decode32u(data, &ts); - data = ikcp_decode32u(data, &sn); - data = ikcp_decode32u(data, &una); - data = ikcp_decode32u(data, &len); - - size -= IKCP_OVERHEAD; - - if ((long)size < (long)len || (int)len < 0) return -2; - - if (cmd != IKCP_CMD_PUSH && cmd != IKCP_CMD_ACK && - cmd != IKCP_CMD_WASK && cmd != IKCP_CMD_WINS) - return -3; - - kcp->rmt_wnd = wnd; - ikcp_parse_una(kcp, una); - ikcp_shrink_buf(kcp); - - if (cmd == IKCP_CMD_ACK) - { - if (_itimediff(kcp->current, ts) >= 0) - { - ikcp_update_ack(kcp, (int)_itimediff(kcp->current, ts)); - } - - ikcp_parse_ack(kcp, sn); - ikcp_shrink_buf(kcp); - if (flag == 0) - { - flag = 1; - maxack = sn; - latest_ts = ts; - } - else - { - if (_itimediff(sn, maxack) > 0) - { -#if !IKCP_FASTACK_CONSERVE - maxack = sn; - latest_ts = ts; -#else - if (_itimediff(ts, latest_ts) > 0) - { - maxack = sn; - latest_ts = ts; - } -#endif - } - } - } - else if (cmd == IKCP_CMD_PUSH) - { - if (_itimediff(sn, kcp->rcv_nxt + kcp->rcv_wnd) < 0) - { - ikcp_ack_push(kcp, sn, ts); - if (_itimediff(sn, kcp->rcv_nxt) >= 0) - { - seg = ikcp_segment_new(kcp, (int)len); - seg->conv = conv; - seg->cmd = cmd; - seg->frg = frg; - seg->wnd = wnd; - seg->ts = ts; - seg->sn = sn; - seg->una = una; - seg->len = len; - - if (len > 0) - { - memcpy(seg->data, data, (nuint)len); - } - - ikcp_parse_data(kcp, seg); - } - } - } - else if (cmd == IKCP_CMD_WASK) - { - // ready to send back IKCP_CMD_WINS in ikcp_flush - // tell remote my window size - kcp->probe |= IKCP_ASK_TELL; - } - else if (cmd == IKCP_CMD_WINS) - { - // do nothing - } - else - { - return -3; - } - - data += len; - size -= len; - } - - if (flag != 0) - { - ikcp_parse_fastack(kcp, maxack, latest_ts); - } - - if (_itimediff(kcp->snd_una, prev_una) > 0) - { - if (kcp->cwnd < kcp->rmt_wnd) - { - uint mss = kcp->mss; - if (kcp->cwnd < kcp->ssthresh) - { - kcp->cwnd++; - kcp->incr += mss; - } - else - { - if (kcp->incr < mss) kcp->incr = mss; - kcp->incr += (mss * mss) / kcp->incr + (mss / 16); - if ((kcp->cwnd + 1) * mss <= kcp->incr) - { - kcp->cwnd = (kcp->incr + mss - 1) / ((mss > 0) ? mss : 1); - } - } - - if (kcp->cwnd > kcp->rmt_wnd) - { - kcp->cwnd = kcp->rmt_wnd; - kcp->incr = kcp->rmt_wnd * mss; - } - } - } - - return 0; - } - - //--------------------------------------------------------------------- - // ikcp_encode_seg - //--------------------------------------------------------------------- - public static byte* ikcp_encode_seg(byte* ptr, IKCPSEG* seg) - { - ptr = ikcp_encode32u(ptr, seg->conv); - ptr = ikcp_encode8u(ptr, (byte)seg->cmd); - ptr = ikcp_encode8u(ptr, (byte)seg->frg); - ptr = ikcp_encode16u(ptr, (ushort)seg->wnd); - ptr = ikcp_encode32u(ptr, seg->ts); - ptr = ikcp_encode32u(ptr, seg->sn); - ptr = ikcp_encode32u(ptr, seg->una); - ptr = ikcp_encode32u(ptr, seg->len); - return ptr; - } - - public static int ikcp_wnd_unused(IKCPCB* kcp) - { - if (kcp->nrcv_que < kcp->rcv_wnd) - { - return (int)(kcp->rcv_wnd - kcp->nrcv_que); - } - - return 0; - } - - //--------------------------------------------------------------------- - // ikcp_flush - //--------------------------------------------------------------------- - public static void ikcp_flush(IKCPCB* kcp, byte* buffer, byte[] destination, KcpCallback output) - { - uint current = kcp->current; - byte* ptr = buffer; - int count, size, i; - uint resent, cwnd; - uint rtomin; - IQUEUEHEAD* p; - int change = 0; - int lost = 0; - IKCPSEG seg; - - // 'ikcp_update' haven't been called. - if (kcp->updated == 0) return; - - seg.conv = kcp->conv; - seg.cmd = IKCP_CMD_ACK; - seg.frg = 0; - seg.wnd = (uint)ikcp_wnd_unused(kcp); - seg.una = kcp->rcv_nxt; - seg.len = 0; - seg.sn = 0; - seg.ts = 0; - - // flush acknowledges - count = (int)kcp->ackcount; - for (i = 0; i < count; i++) - { - size = (int)(ptr - buffer); - if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) - { - ikcp_output(kcp, size, destination, output); - ptr = buffer; - } - - ikcp_ack_get(kcp, i, &seg.sn, &seg.ts); - ptr = ikcp_encode_seg(ptr, &seg); - } - - kcp->ackcount = 0; - - // probe window size (if remote window size equals zero) - if (kcp->rmt_wnd == 0) - { - if (kcp->probe_wait == 0) - { - kcp->probe_wait = IKCP_PROBE_INIT; - kcp->ts_probe = kcp->current + kcp->probe_wait; - } - else - { - if (_itimediff(kcp->current, kcp->ts_probe) >= 0) - { - if (kcp->probe_wait < IKCP_PROBE_INIT) - kcp->probe_wait = IKCP_PROBE_INIT; - kcp->probe_wait += kcp->probe_wait / 2; - if (kcp->probe_wait > IKCP_PROBE_LIMIT) - kcp->probe_wait = IKCP_PROBE_LIMIT; - kcp->ts_probe = kcp->current + kcp->probe_wait; - kcp->probe |= IKCP_ASK_SEND; - } - } - } - else - { - kcp->ts_probe = 0; - kcp->probe_wait = 0; - } - - // flush window probing commands - if ((kcp->probe & IKCP_ASK_SEND) != 0) - { - seg.cmd = IKCP_CMD_WASK; - size = (int)(ptr - buffer); - if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) - { - ikcp_output(kcp, size, destination, output); - ptr = buffer; - } - - ptr = ikcp_encode_seg(ptr, &seg); - } - - // flush window probing commands - if ((kcp->probe & IKCP_ASK_TELL) != 0) - { - seg.cmd = IKCP_CMD_WINS; - size = (int)(ptr - buffer); - if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) - { - ikcp_output(kcp, size, destination, output); - ptr = buffer; - } - - ptr = ikcp_encode_seg(ptr, &seg); - } - - kcp->probe = 0; - - // calculate window size - cwnd = _imin_(kcp->snd_wnd, kcp->rmt_wnd); - if (kcp->nocwnd == 0) cwnd = _imin_(kcp->cwnd, cwnd); - - // move data from snd_queue to snd_buf - while (_itimediff(kcp->snd_nxt, kcp->snd_una + cwnd) < 0) - { - IKCPSEG* newseg; - if (iqueue_is_empty(&kcp->snd_queue)) break; - - newseg = iqueue_entry(kcp->snd_queue.next); - - iqueue_del(&newseg->node); - iqueue_add_tail(&newseg->node, &kcp->snd_buf); - kcp->nsnd_que--; - kcp->nsnd_buf++; - - newseg->conv = kcp->conv; - newseg->cmd = IKCP_CMD_PUSH; - newseg->wnd = seg.wnd; - newseg->ts = current; - newseg->sn = kcp->snd_nxt++; - newseg->una = kcp->rcv_nxt; - newseg->resendts = current; - newseg->rto = (uint)kcp->rx_rto; - newseg->fastack = 0; - newseg->xmit = 0; - } - - // calculate resent - resent = (kcp->fastresend > 0) ? (uint)kcp->fastresend : 0xffffffff; - rtomin = (uint)((kcp->nodelay == 0) ? (kcp->rx_rto >> 3) : 0); - - // flush data segments - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = p->next) - { - IKCPSEG* segment = iqueue_entry(p); - int needsend = 0; - if (segment->xmit == 0) - { - needsend = 1; - segment->xmit++; - segment->rto = (uint)kcp->rx_rto; - segment->resendts = current + segment->rto + rtomin; - } - else if (_itimediff(current, segment->resendts) >= 0) - { - needsend = 1; - segment->xmit++; - kcp->xmit++; - if (kcp->nodelay == 0) - { - segment->rto += _imax_(segment->rto, (uint)kcp->rx_rto); - } - else - { - int step = (kcp->nodelay < 2) ? ((int)(segment->rto)) : kcp->rx_rto; - segment->rto += (uint)(step / 2); - } - - segment->resendts = current + segment->rto; - lost = 1; - } - else if (segment->fastack >= resent) - { - if ((int)segment->xmit <= kcp->fastlimit || - kcp->fastlimit <= 0) - { - needsend = 1; - segment->xmit++; - segment->fastack = 0; - segment->resendts = current + segment->rto; - change++; - } - } - - if (needsend != 0) - { - int need; - segment->ts = current; - segment->wnd = seg.wnd; - segment->una = kcp->rcv_nxt; - - size = (int)(ptr - buffer); - need = (int)(IKCP_OVERHEAD + segment->len); - - if (size + need > (int)kcp->mtu) - { - ikcp_output(kcp, size, destination, output); - ptr = buffer; - } - - ptr = ikcp_encode_seg(ptr, segment); - - if (segment->len > 0) - { - memcpy(ptr, segment->data, (nuint)segment->len); - ptr += segment->len; - } - - if (segment->xmit >= kcp->dead_link) - { - kcp->state = unchecked((uint)(-1)); - } - } - } - - // flash remain segments - size = (int)(ptr - buffer); - if (size > 0) - { - ikcp_output(kcp, size, destination, output); - } - - // update ssthresh - if (change != 0) - { - uint inflight = kcp->snd_nxt - kcp->snd_una; - kcp->ssthresh = inflight / 2; - if (kcp->ssthresh < IKCP_THRESH_MIN) - kcp->ssthresh = IKCP_THRESH_MIN; - kcp->cwnd = kcp->ssthresh + resent; - kcp->incr = kcp->cwnd * kcp->mss; - } - - if (lost != 0) - { - kcp->ssthresh = cwnd / 2; - if (kcp->ssthresh < IKCP_THRESH_MIN) - kcp->ssthresh = IKCP_THRESH_MIN; - kcp->cwnd = 1; - kcp->incr = kcp->mss; - } - - if (kcp->cwnd < 1) - { - kcp->cwnd = 1; - kcp->incr = kcp->mss; - } - } - - public static void ikcp_update(IKCPCB* kcp, uint current, byte* buffer, byte[] destination, KcpCallback output) - { - int slap; - - kcp->current = current; - - if (kcp->updated == 0) - { - kcp->updated = 1; - kcp->ts_flush = kcp->current; - } - - slap = (int)_itimediff(kcp->current, kcp->ts_flush); - - if (slap >= 10000 || slap < -10000) - { - kcp->ts_flush = kcp->current; - slap = 0; - } - - if (slap >= 0) - { - kcp->ts_flush += kcp->interval; - if (_itimediff(kcp->current, kcp->ts_flush) >= 0) - { - kcp->ts_flush = kcp->current + kcp->interval; - } - - ikcp_flush(kcp, buffer, destination, output); - } - } - - //--------------------------------------------------------------------- - // Determine when should you invoke ikcp_update: - // returns when you should invoke ikcp_update in millisec, if there - // is no ikcp_input/_send calling. you can call ikcp_update in that - // time, instead of call update repeatly. - // Important to reduce unnacessary ikcp_update invoking. use it to - // schedule ikcp_update (eg. implementing an epoll-like mechanism, - // or optimize ikcp_update when handling massive kcp connections) - //--------------------------------------------------------------------- - public static uint ikcp_check(IKCPCB* kcp, uint current) - { - uint ts_flush = kcp->ts_flush; - int tm_flush = 0x7fffffff; - int tm_packet = 0x7fffffff; - uint minimal = 0; - IQUEUEHEAD* p; - - if (kcp->updated == 0) - { - return current; - } - - if (_itimediff(current, ts_flush) >= 10000 || - _itimediff(current, ts_flush) < -10000) - { - ts_flush = current; - } - - if (_itimediff(current, ts_flush) >= 0) - { - return current; - } - - tm_flush = (int)_itimediff(ts_flush, current); - - for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = p->next) - { - IKCPSEG* seg = iqueue_entry(p); - int diff = (int)_itimediff(seg->resendts, current); - if (diff <= 0) - { - return current; - } - - if (diff < tm_packet) tm_packet = diff; - } - - minimal = (uint)(tm_packet < tm_flush ? tm_packet : tm_flush); - if (minimal >= kcp->interval) minimal = kcp->interval; - - return current + minimal; - } - - public static int ikcp_setmtu(IKCPCB* kcp, int mtu, int reserved, ref byte[] buffer) - { - if (mtu < 50 || mtu < (int)IKCP_OVERHEAD) - return -1; - buffer = new byte[(reserved + mtu + IKCP_OVERHEAD) * 3]; - if (buffer == null) - return -2; - kcp->mtu = (uint)mtu; - kcp->mss = kcp->mtu - IKCP_OVERHEAD; - return 0; - } - - public static int ikcp_interval(IKCPCB* kcp, int interval) - { - if (interval > 5000) interval = 5000; - else if (interval < 10) interval = 10; - kcp->interval = (uint)interval; - return 0; - } - - public static int ikcp_nodelay(IKCPCB* kcp, int nodelay, int interval, int resend, int nc) - { - if (nodelay >= 0) - { - kcp->nodelay = (uint)nodelay; - if (nodelay != 0) - { - kcp->rx_minrto = (int)IKCP_RTO_NDL; - } - else - { - kcp->rx_minrto = (int)IKCP_RTO_MIN; - } - } - - if (interval >= 0) - { - if (interval > 5000) interval = 5000; - else if (interval < 10) interval = 10; - kcp->interval = (uint)interval; - } - - if (resend >= 0) - { - kcp->fastresend = resend; - } - - if (nc >= 0) - { - kcp->nocwnd = nc; - } - - return 0; - } - - public static int ikcp_wndsize(IKCPCB* kcp, int sndwnd, int rcvwnd) - { - if (kcp != null) - { - if (sndwnd > 0) - { - kcp->snd_wnd = (uint)sndwnd; - } - - if (rcvwnd > 0) - { - // must >= max fragment size - kcp->rcv_wnd = _imax_((uint)rcvwnd, IKCP_WND_RCV); - } - } - - return 0; - } - - public static int ikcp_waitsnd(IKCPCB* kcp) - { - return (int)(kcp->nsnd_buf + kcp->nsnd_que); - } - - // read conv - public static uint ikcp_getconv(void* ptr) - { - uint conv; - ikcp_decode32u((byte*)ptr, &conv); - return conv; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/define/system.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/define/system.cs deleted file mode 100644 index 053b8c5..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/define/system.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -#pragma warning disable CS1591 - -// ReSharper disable ALL - -namespace kcp -{ - public static unsafe partial class KCP - { - public static void* malloc(nuint size) - { -#if NET6_0_OR_GREATER - return NativeMemory.Alloc((nuint)size); -#else - return (void*)Marshal.AllocHGlobal((nint)size); -#endif - } - - public static void free(void* memory) - { -#if NET6_0_OR_GREATER - NativeMemory.Free(memory); -#else - Marshal.FreeHGlobal((nint)memory); -#endif - } - - public static void memcpy(void* dst, void* src, nuint size) => Unsafe.CopyBlockUnaligned(dst, src, (uint)size); - - public static void memset(void* dst, byte val, nuint size) => Unsafe.InitBlockUnaligned(dst, val, (uint)size); - - [Conditional("DEBUG")] - public static void assert(bool condition) => Debug.Assert(condition); - - public static void abort() => Environment.Exit(-1); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/include/kcp.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/include/kcp.cs deleted file mode 100644 index 98a83d9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Base/include/kcp.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -#pragma warning disable CS1591 - -// ReSharper disable ALL - -namespace kcp -{ - [StructLayout(LayoutKind.Sequential)] - public unsafe struct IQUEUEHEAD - { - public IQUEUEHEAD* next; - public IQUEUEHEAD* prev; - } - - public static unsafe partial class KCP - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_init(IQUEUEHEAD* head) - { - head->next = head; - head->prev = head; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T* iqueue_entry(IQUEUEHEAD* ptr) where T : unmanaged => ((T*)(((byte*)((T*)ptr)))); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_add(IQUEUEHEAD* node, IQUEUEHEAD* head) - { - node->prev = head; - node->next = head->next; - head->next->prev = node; - head->next = node; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_add_tail(IQUEUEHEAD* node, IQUEUEHEAD* head) - { - node->prev = head->prev; - node->next = head; - head->prev->next = node; - head->prev = node; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_del(IQUEUEHEAD* entry) - { - entry->next->prev = entry->prev; - entry->prev->next = entry->next; - entry->next = (IQUEUEHEAD*)0; - entry->prev = (IQUEUEHEAD*)0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void iqueue_del_init(IQUEUEHEAD* entry) - { - iqueue_del(entry); - iqueue_init(entry); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool iqueue_is_empty(IQUEUEHEAD* entry) => entry == entry->next; - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe struct IKCPSEG - { - public IQUEUEHEAD node; - public uint conv; - public uint cmd; - public uint frg; - public uint wnd; - public uint ts; - public uint sn; - public uint una; - public uint len; - public uint resendts; - public uint rto; - public uint fastack; - public uint xmit; - public fixed byte data[1]; - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe struct IKCPCB - { - public uint conv, mtu, mss, state; - public uint snd_una, snd_nxt, rcv_nxt; - public uint ts_recent, ts_lastack, ssthresh; - public int rx_rttval, rx_srtt, rx_rto, rx_minrto; - public uint snd_wnd, rcv_wnd, rmt_wnd, cwnd, probe; - public uint current, interval, ts_flush, xmit; - public uint nrcv_buf, nsnd_buf; - public uint nrcv_que, nsnd_que; - public uint nodelay, updated; - public uint ts_probe, probe_wait; - public uint dead_link, incr; - public IQUEUEHEAD snd_queue; - public IQUEUEHEAD rcv_queue; - public IQUEUEHEAD snd_buf; - public IQUEUEHEAD rcv_buf; - public uint* acklist; - public uint ackcount; - public uint ackblock; - public int fastresend; - public int fastlimit; - public int nocwnd, stream; - } - - public static partial class KCP - { - public const uint IKCP_LOG_OUTPUT = 1; - public const uint IKCP_LOG_INPUT = 2; - public const uint IKCP_LOG_SEND = 4; - public const uint IKCP_LOG_RECV = 8; - public const uint IKCP_LOG_IN_DATA = 16; - public const uint IKCP_LOG_IN_ACK = 32; - public const uint IKCP_LOG_IN_PROBE = 64; - public const uint IKCP_LOG_IN_WINS = 128; - public const uint IKCP_LOG_OUT_DATA = 256; - public const uint IKCP_LOG_OUT_ACK = 512; - public const uint IKCP_LOG_OUT_PROBE = 1024; - public const uint IKCP_LOG_OUT_WINS = 2048; - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Client/KCPClientNetwork.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Client/KCPClientNetwork.cs deleted file mode 100644 index a400c34..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Client/KCPClientNetwork.cs +++ /dev/null @@ -1,697 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Buffers; -using System.Collections.Generic; -using System.IO; -using System.IO.Pipelines; -using System.Net; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Threading; -using Fantasy.Async; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -using KCP; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable PossibleNullReferenceException -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). - -#pragma warning disable CS8602 // Dereference of a possibly null reference. -namespace Fantasy.Network.KCP -{ - public sealed class KCPClientNetworkUpdateSystem : UpdateSystem - { - protected override void Update(KCPClientNetwork self) - { - self.CheckUpdate(); - } - } - public sealed class KCPClientNetwork : AClientNetwork - { - private Kcp _kcp; - private Socket _socket; - private int _maxSndWnd; - private long _startTime; - private bool _isConnected; - private bool _isDisconnect; - private uint _updateMinTime; - private bool _isInnerDispose; - private long _connectTimeoutId; - private bool _allowWraparound = true; - private IPEndPoint _remoteAddress; - private BufferPacketParser _packetParser; - private readonly Pipe _pipe = new Pipe(); - private readonly byte[] _sendBuff = new byte[5]; - private readonly byte[] _receiveBuffer = new byte[Packet.PacketBodyMaxLength + 20]; - private readonly List _updateTimeOutTime = new List(); - private readonly SortedSet _updateTimer = new SortedSet(); - private readonly SocketAsyncEventArgs _connectEventArgs = new SocketAsyncEventArgs(); - private readonly Queue _messageCache = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); -#if FANTASY_UNITY - private readonly EndPoint _ipEndPoint = new IPEndPoint(IPAddress.Any, 0); -#endif - private event Action OnConnectFail; - private event Action OnConnectComplete; - private event Action OnConnectDisconnect; - public uint ChannelId { get; private set; } - private uint TimeNow => (uint) (TimeHelper.Now - _startTime); - - public void Initialize(NetworkTarget networkTarget) - { - base.Initialize(NetworkType.Client, NetworkProtocolType.KCP, networkTarget); - _packetParser = PacketParserFactory.CreateClientBufferPacket(this); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isInnerDispose = true; - - if (!_isDisconnect) - { - SendDisconnect(); - } - - ClearConnectTimeout(); - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - OnConnectDisconnect?.Invoke(); - _kcp.Dispose(); - - if (_socket.Connected) - { - _socket.Close(); - } - - _packetParser.Dispose(); - ChannelId = 0; - _isConnected = false; - _messageCache.Clear(); - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - #region Connect - - public override Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - if (IsInit) - { - throw new NotSupportedException($"KCPClientNetwork Has already been initialized. If you want to call Connect again, please re instantiate it."); - } - - IsInit = true; - _startTime = TimeHelper.Now; - ChannelId = CreateChannelId(); - _remoteAddress = NetworkHelper.GetIPEndPoint(remoteAddress); - OnConnectFail = onConnectFail; - OnConnectComplete = onConnectComplete; - OnConnectDisconnect = onConnectDisconnect; - _connectEventArgs.Completed += OnConnectSocketCompleted; - _connectTimeoutId = Scene.TimerComponent.Net.OnceTimer(connectTimeout, () => - { - OnConnectFail?.Invoke(); - Dispose(); - }); - _connectEventArgs.RemoteEndPoint = _remoteAddress; - _socket = new Socket(_remoteAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp); - _socket.Blocking = false; - _socket.SetSocketBufferToOsLimit(); - _socket.SetSioUdpConnReset(); - _socket.Bind(new IPEndPoint(IPAddress.Any, 0)); - _kcp = KCPFactory.Create(NetworkTarget, ChannelId, KcpSpanCallback, out var kcpSettings); - _maxSndWnd = kcpSettings.MaxSendWindowSize; - - if (!_socket.ConnectAsync(_connectEventArgs)) - { - try - { - OnReceiveSocketComplete(); - } - catch (Exception e) - { - Log.Error(e); - OnConnectFail?.Invoke(); - } - } - - Session = Session.Create(this, _remoteAddress); - return Session; - } - - private void OnConnectSocketCompleted(object sender, SocketAsyncEventArgs asyncEventArgs) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - if (asyncEventArgs.LastOperation == SocketAsyncOperation.Connect) - { - if (asyncEventArgs.SocketError == SocketError.Success) - { - Scene.ThreadSynchronizationContext.Post(OnReceiveSocketComplete); - } - else - { - Scene.ThreadSynchronizationContext.Post(() => - { - OnConnectFail?.Invoke(); - Dispose(); - }); - } - } - } - - private void OnReceiveSocketComplete() - { - SendRequestConnection(); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - } - - #endregion - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); -#if FANTASY_UNITY - MemoryMarshal.TryGetArray(memory, out ArraySegment arraySegment); - var result = await _socket.ReceiveFromAsync(arraySegment, SocketFlags.None, _ipEndPoint); - _pipe.Writer.Advance(result.ReceivedBytes); - await _pipe.Writer.FlushAsync(); -#else - var result = await _socket.ReceiveAsync(memory, SocketFlags.None, _cancellationTokenSource.Token); - _pipe.Writer.Advance(result); - await _pipe.Writer.FlushAsync(); -#endif - } - catch (SocketException) - { - Dispose(); - break; - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (Exception ex) - { - Log.Error($"Unexpected exception: {ex.Message}"); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var header, out var channelId, out var message)) - { - ReceiveData(ref header, ref channelId, ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - } - - private unsafe bool TryReadMessage(ref ReadOnlySequence buffer, out KcpHeader header, out uint channelId, out ReadOnlyMemory message) - { - if (buffer.Length < 5) - { - channelId = 0; - message = default; - header = KcpHeader.None; - if (buffer.Length > 0) - { - buffer = buffer.Slice(buffer.Length); - } - return false; - } - - var readOnlyMemory = buffer.First; - - if (MemoryMarshal.TryGetArray(readOnlyMemory, out var arraySegment)) - { - fixed (byte* bytePointer = &arraySegment.Array[arraySegment.Offset]) - { - header = (KcpHeader)bytePointer[0]; - channelId = Unsafe.ReadUnaligned(ref bytePointer[1]); - } - } - else - { - // 如果无法获取数组段,回退到安全代码来执行。这种情况几乎不会发生、为了保险还是写一下了。 - var firstSpan = readOnlyMemory.Span; - header = (KcpHeader)firstSpan[0]; - channelId = MemoryMarshal.Read(firstSpan.Slice(1, 4)); - - } - - message = readOnlyMemory.Slice(5); - buffer = buffer.Slice(readOnlyMemory.Length); - return true; - } - - private void ReceiveData(ref KcpHeader header, ref uint channelId, ref ReadOnlyMemory buffer) - { - switch (header) - { - // 发送握手给服务器 - case KcpHeader.RepeatChannelId: - { - // 到这里是客户端的channelId再服务器上已经存在、需要重新生成一个再次尝试连接 - ChannelId = CreateChannelId(); - SendRequestConnection(); - break; - } - // 收到服务器发送会来的确认握手 - case KcpHeader.WaitConfirmConnection: - { - if (channelId != ChannelId) - { - break; - } - - ClearConnectTimeout(); - SendConfirmConnection(); - OnConnectComplete?.Invoke(); - _isConnected = true; - while (_messageCache.TryDequeue(out var memoryStream)) - { - SendMemoryStream(memoryStream); - } - break; - } - // 收到服务器发送的消息 - case KcpHeader.ReceiveData: - { - if (buffer.Length == 5) - { - Log.Warning($"KCP Server KcpHeader.Data buffer.Length == 5"); - break; - } - - if (channelId != ChannelId) - { - break; - } - - Input(buffer); - break; - } - // 接收到服务器的断开连接消息 - case KcpHeader.Disconnect: - { - if (channelId != ChannelId) - { - break; - } - - _isDisconnect = true; - Dispose(); - break; - } - } - } - - private void Input(ReadOnlyMemory buffer) - { - _kcp.Input(buffer.Span); - AddToUpdate(0); - - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var peekSize = _kcp.PeekSize(); - - if (peekSize < 0) - { - return; - } - - var receiveCount = _kcp.Receive(_receiveBuffer.AsSpan(0, peekSize)); - - if (receiveCount != peekSize) - { - return; - } - - if (!_packetParser.UnPack(_receiveBuffer, ref receiveCount, out var packInfo)) - { - continue; - } - - Session.Receive(packInfo); - } - catch (ScanException e) - { - Log.Debug($"RemoteAddress:{_remoteAddress} \n{e}"); - Dispose(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - #endregion - - #region Update - - public void CheckUpdate() - { - var nowTime = TimeNow; - _allowWraparound = nowTime < _updateMinTime; - - if (IsTimeGreaterThan(nowTime, _updateMinTime) && _updateTimer.Count > 0) - { - foreach (var timeId in _updateTimer) - { - if (IsTimeGreaterThan(timeId, nowTime)) - { - _updateMinTime = timeId; - break; - } - - _updateTimeOutTime.Add(timeId); - } - - foreach (var timeId in _updateTimeOutTime) - { - _updateTimer.Remove(timeId); - KcpUpdate(); - } - - _updateTimeOutTime.Clear(); - } - - _allowWraparound = true; - } - - private void AddToUpdate(uint tillTime) - { - if (tillTime == 0) - { - KcpUpdate(); - return; - } - - if (IsTimeGreaterThan(_updateMinTime, tillTime) || _updateMinTime == 0) - { - _updateMinTime = tillTime; - } - - _updateTimer.Add(tillTime); - } - - private void KcpUpdate() - { - var nowTime = TimeNow; - - try - { - _kcp.Update(nowTime); - } - catch (Exception e) - { - Log.Error(e); - } - - AddToUpdate(_kcp.Check(nowTime)); - } - - private const uint HalfMaxUint = uint.MaxValue / 2; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool IsTimeGreaterThan(uint timeId, uint nowTime) - { - if (!_allowWraparound) - { - return timeId > nowTime; - } - var diff = timeId - nowTime; - // 如果 diff 的值在 [0, HalfMaxUint] 范围内,说明 timeId 是在 nowTime 之后或相等。 - // 如果 diff 的值在 (HalfMaxUint, uint.MaxValue] 范围内,说明 timeId 是在 nowTime 之前(时间回绕的情况)。 - return diff < HalfMaxUint || diff == HalfMaxUint; - } - - #endregion - - #region Send - - private const byte KcpHeaderDisconnect = (byte)KcpHeader.Disconnect; - private const byte KcpHeaderReceiveData = (byte)KcpHeader.ReceiveData; - private const byte KcpHeaderRequestConnection = (byte)KcpHeader.RequestConnection; - private const byte KcpHeaderConfirmConnection = (byte)KcpHeader.ConfirmConnection; - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - var buffer = _packetParser.Pack(ref rpcId, ref routeId, memoryStream, message); - - if (!_isConnected) - { - _messageCache.Enqueue(buffer); - return; - } - - SendMemoryStream(buffer); - } - - private void SendMemoryStream(MemoryStreamBuffer memoryStream) - { - if (_kcp.WaitSendCount > _maxSndWnd) - { - // 检查等待发送的消息,如果超出两倍窗口大小,KCP作者给的建议是要断开连接 - Log.Warning($"ERR_KcpWaitSendSizeTooLarge {_kcp.WaitSendCount} > {_maxSndWnd}"); - Dispose(); - return; - } - - try - { - _kcp.Send(memoryStream.GetBuffer().AsSpan(0, (int)memoryStream.Position)); - AddToUpdate(0); - } - finally - { - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - } - - private unsafe void SendRequestConnection() - { - try - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderRequestConnection; - *(uint*)(p + 1) = ChannelId; - } - - SendAsync(_sendBuff, 0, 5); - } - catch (Exception e) - { - Log.Error(e); - } - } - - private unsafe void SendConfirmConnection() - { - try - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderConfirmConnection; - *(uint*)(p + 1) = ChannelId; - } - - SendAsync(_sendBuff, 0, 5); - } - catch (Exception e) - { - Log.Error(e); - } - } - - private unsafe void SendDisconnect() - { - try - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderDisconnect; - *(uint*)(p + 1) = ChannelId; - } - - SendAsync(_sendBuff, 0, 5); - } - catch (Exception e) - { - Log.Error(e); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SendAsync(byte[] buffer, int offset, int count) - { - try - { - _socket.Send(new ArraySegment(buffer, offset, count), SocketFlags.None); - } - catch (ArgumentException ex) - { - Log.Error($"ArgumentException: {ex.Message}"); // 处理参数错误 - } - catch (SocketException) - { - //Log.Error($"SocketException: {ex.Message}"); // 处理网络错误 - Dispose(); - } - catch (ObjectDisposedException ex) - { - Log.Error($"ObjectDisposedException: {ex.Message}"); // 处理套接字已关闭的情况 - Dispose(); - } - catch (InvalidOperationException ex) - { - Log.Error($"InvalidOperationException: {ex.Message}"); // 处理无效操作 - } - catch (Exception ex) - { - Log.Error($"Exception: {ex.Message}"); // 捕获其他异常 - } - } - - private unsafe void KcpSpanCallback(byte[] buffer, int count) - { - if (IsDisposed) - { - return; - } - - if (count == 0) - { - throw new Exception("KcpOutput count 0"); - } - - fixed (byte* p = buffer) - { - p[0] = KcpHeaderReceiveData; - *(uint*)(p + 1) = ChannelId; - } - - SendAsync(buffer, 0, count + 5); - } - - #endregion - - public override void RemoveChannel(uint channelId) - { - Dispose(); - } - - private void ClearConnectTimeout() - { - if (_connectTimeoutId == 0) - { - return; - } - - Scene?.TimerComponent?.Net.Remove(ref _connectTimeoutId); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe uint CreateChannelId() - { - uint value; - RandomNumberGenerator.Fill(MemoryMarshal.CreateSpan(ref *(byte*)&value, 4)); - return 0xC0000000 | (value & int.MaxValue); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/KCPSettings.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/KCPSettings.cs deleted file mode 100644 index 2a070a9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/KCPSettings.cs +++ /dev/null @@ -1,91 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using KCP; - -#pragma warning disable CS1591 -namespace Fantasy.Network.KCP -{ - public class KCPSettings - { - public int Mtu { get; private set; } - public int SendWindowSize { get; private set; } - public int ReceiveWindowSize { get; private set; } - public int MaxSendWindowSize { get; private set; } - - public static KCPSettings Create(NetworkTarget networkTarget) - { - var settings = new KCPSettings(); - - switch (networkTarget) - { - case NetworkTarget.Outer: - { - // 外网设置470的原因: - // 1、mtu设置过大有可能路由器过滤掉 - // 2、降低 mtu 到 470,同样数据虽然会发更多的包,但是小包在路由层优先级更高 - settings.Mtu = 470; -#if FANTASY_NET - settings.SendWindowSize = 8192; - settings.ReceiveWindowSize = 8192; - settings.MaxSendWindowSize = 8192 * 8192 * 7; -#endif -#if FANTASY_UNITY || FANTASY_CONSOLE - settings.SendWindowSize = 512; - settings.ReceiveWindowSize = 512; - settings.MaxSendWindowSize = 512 * 512 * 7; -#endif - - break; - } -#if FANTASY_NET - case NetworkTarget.Inner: - { - // 内网设置1400的原因 - // 1、一般都是同一台服务器来运行多个进程来处理 - // 2、内网每个进程跟其他进程只有一个通道进行发送、所以发送的数量会比较大 - // 3、如果不把窗口设置大点、会出现消息滞后。 - // 4、因为内网发送的可不只是外网转发数据、还有可能是其他进程的通讯 - settings.Mtu = 1200; - settings.SendWindowSize = 8192; - settings.ReceiveWindowSize = 8192; - settings.MaxSendWindowSize = 8192 * 8192 * 7; - break; - } -#endif - default: - { - throw new NotSupportedException($"KCPServerNetwork NotSupported NetworkType:{networkTarget}"); - } - } - - return settings; - } - } - - public static class KCPFactory - { - public const int FANTASY_KCP_RESERVED_HEAD = 5; - - public static Kcp Create(NetworkTarget networkTarget, uint conv, KcpCallback output, out KCPSettings kcpSettings) - { - var kcp = new Kcp(conv, output, FANTASY_KCP_RESERVED_HEAD); - kcpSettings = KCPSettings.Create(networkTarget); - kcp.SetNoDelay(1, 5, 2, 1); - kcp.SetWindowSize(kcpSettings.SendWindowSize, kcpSettings.ReceiveWindowSize); - kcp.SetMtu(kcpSettings.Mtu); - kcp.SetMinrto(30); - return kcp; - } - - public static Kcp Create(KCPSettings kcpSettings, uint conv, KcpCallback output) - { - var kcp = new Kcp(conv, output, FANTASY_KCP_RESERVED_HEAD); - kcp.SetNoDelay(1, 5, 2, 1); - kcp.SetWindowSize(kcpSettings.SendWindowSize, kcpSettings.ReceiveWindowSize); - kcp.SetMtu(kcpSettings.Mtu); - kcp.SetMinrto(30); - return kcp; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/KcpHeader.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/KcpHeader.cs deleted file mode 100644 index 28ddace..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/KcpHeader.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Fantasy.Network.KCP -#pragma warning disable CS1591 -{ - public enum KcpHeader : byte - { - None = 0x00, - RequestConnection = 0x01, - WaitConfirmConnection = 0x02, - ConfirmConnection = 0x03, - RepeatChannelId = 0x04, - ReceiveData = 0x06, - Disconnect = 0x07 - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByArrayPool.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByArrayPool.cs deleted file mode 100644 index 0fb4e29..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByArrayPool.cs +++ /dev/null @@ -1,575 +0,0 @@ -// #if FANTASY_NET -// using System.Buffers; -// using System.Net; -// using System.Net.Sockets; -// using System.Runtime.CompilerServices; -// using System.Runtime.InteropServices; -// using Fantasy.Async; -// using Fantasy.DataStructure.Collection; -// using Fantasy.Entitas.Interface; -// using Fantasy.Helper; -// using Fantasy.Network.Interface; -// #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -// -// // ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// #pragma warning disable CS8604 // Possible null reference argument. -// #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -// #pragma warning disable CS8602 // Dereference of a possibly null reference. -// -// #pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). -// -// namespace Fantasy.Network.KCP -// { -// public sealed class KCPServerNetworkUpdateSystem : UpdateSystem -// { -// protected override void Update(KCPServerNetwork self) -// { -// self.Update(); -// } -// } -// -// public struct PendingConnection -// { -// public readonly uint ChannelId; -// public readonly uint TimeOutId; -// public readonly IPEndPoint RemoteEndPoint; -// -// public PendingConnection(uint channelId, IPEndPoint remoteEndPoint, uint time) -// { -// ChannelId = channelId; -// RemoteEndPoint = remoteEndPoint; -// TimeOutId = time + 10 * 1000; // 设置10秒超时,如果10秒内没有确认连接则删除。 -// } -// } -// -// public sealed class KCPServerNetwork : ANetwork -// { -// private Socket _socket; -// private Thread _thread; -// private long _startTime; -// private uint _updateMinTime; -// private uint _pendingMinTime; -// private bool _allowWraparound = true; -// -// private readonly byte[] _sendBuff = new byte[5]; -// private readonly List _pendingTimeOutTime = new List(); -// private readonly HashSet _updateChannels = new HashSet(); -// private readonly List _updateTimeOutTime = new List(); -// private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); -// private readonly SortedOneToManyList _updateTimer = new SortedOneToManyList(); -// -// private readonly Dictionary _pendingConnection = new Dictionary(); -// private readonly SortedOneToManyList _pendingConnectionTimeOut = new SortedOneToManyList(); -// private readonly Dictionary _connectionChannel = new Dictionary(); -// -// public KCPSettings Settings { get; private set; } -// -// private uint TimeNow => (uint)(TimeHelper.Now - _startTime); -// -// public void Initialize(NetworkTarget networkTarget, IPEndPoint address) -// { -// _startTime = TimeHelper.Now; -// Settings = KCPSettings.Create(networkTarget); -// base.Initialize(NetworkType.Server, NetworkProtocolType.KCP, networkTarget); -// _socket = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); -// _socket.Blocking = false; -// _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); -// if (address.AddressFamily == AddressFamily.InterNetworkV6) -// { -// _socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); -// } -// -// _socket.Blocking = false; -// _socket.Bind(address); -// _socket.SetSocketBufferToOsLimit(); -// _socket.SetSioUdpConnReset(); -// _thread = new Thread(() => -// { -// ReceiveSocketAsync().Coroutine(); -// }); -// _thread.Start(); -// Log.Info($"SceneConfigId = {Scene.SceneConfigId} networkTarget = {networkTarget.ToString()} KCPServer Listen {address}"); -// } -// -// public override void Dispose() -// { -// if (IsDisposed) -// { -// return; -// } -// -// try -// { -// if (!_cancellationTokenSource.IsCancellationRequested) -// { -// try -// { -// _cancellationTokenSource.Cancel(); -// } -// catch (OperationCanceledException) -// { -// // 通常情况下,此处的异常可以忽略 -// } -// } -// -// foreach (var (_, channel) in _connectionChannel.ToArray()) -// { -// channel.Dispose(); -// } -// -// _connectionChannel.Clear(); -// _pendingConnection.Clear(); -// -// if (_socket != null) -// { -// _socket.Dispose(); -// _socket = null; -// } -// } -// catch (Exception e) -// { -// Log.Error(e); -// } -// finally -// { -// base.Dispose(); -// } -// } -// -// #region ReceiveSocket -// -// private const int BufferSize = 8192; -// private static readonly ArrayPool BufferPool = ArrayPool.Shared; -// private async FTask ReceiveSocketAsync() -// { -// var sceneThreadSynchronizationContext = Scene.ThreadSynchronizationContext; -// var remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); -// -// while (!_cancellationTokenSource.IsCancellationRequested) -// { -// try -// { -// IPEndPoint receiveRemoteEndPoint = null; -// var buffer = BufferPool.Rent(BufferSize); -// var socketReceiveFromResult = await _socket.ReceiveFromAsync(buffer, SocketFlags.None, remoteEndPoint, _cancellationTokenSource.Token); -// var receivedBytes = socketReceiveFromResult.ReceivedBytes; -// -// switch (receivedBytes) -// { -// case 5: -// { -// switch ((KcpHeader)buffer[0]) -// { -// case KcpHeader.RequestConnection: -// case KcpHeader.ConfirmConnection: -// { -// receiveRemoteEndPoint = socketReceiveFromResult.RemoteEndPoint.Clone(); -// break; -// } -// } -// -// break; -// } -// case < 5: -// { -// continue; -// } -// } -// -// sceneThreadSynchronizationContext.Post(() => -// { -// ReceiveDataAsync(buffer, receivedBytes, receiveRemoteEndPoint); -// }); -// } -// catch (SocketException ex) -// { -// Log.Error($"Socket exception: {ex.Message}"); -// Dispose(); -// break; -// } -// catch (OperationCanceledException) -// { -// break; -// } -// catch (ObjectDisposedException) -// { -// Dispose(); -// break; -// } -// catch (Exception ex) -// { -// Log.Error($"Unexpected exception: {ex.Message}"); -// } -// } -// } -// -// #endregion -// -// #region ReceivePipeData -// -// private void ReceiveDataAsync(byte[] buffer, int receivedBytes, IPEndPoint remoteEndPoint) -// { -// try -// { -// var header = (KcpHeader)buffer[0]; -// var channelId = BitConverter.ToUInt32(buffer, 1); -// -// switch (header) -// { -// // 客户端请求建立KCP连接 -// case KcpHeader.RequestConnection: -// { -// if (_pendingConnection.TryGetValue(channelId, out var pendingConnection)) -// { -// if (!remoteEndPoint.IPEndPointEquals(pendingConnection.RemoteEndPoint)) -// { -// // 重复通道ID,向客户端发送重复通道ID消息 -// SendRepeatChannelId(ref channelId, remoteEndPoint); -// } -// -// break; -// } -// -// if (_connectionChannel.ContainsKey(channelId)) -// { -// // 已存在的通道ID,向客户端发送重复通道ID消息 -// SendRepeatChannelId(ref channelId, remoteEndPoint); -// break; -// } -// -// AddPendingConnection(ref channelId, remoteEndPoint); -// break; -// } -// // 客户端确认建立KCP连接 -// case KcpHeader.ConfirmConnection: -// { -// if (!ConfirmPendingConnection(ref channelId, remoteEndPoint)) -// { -// break; -// } -// -// AddConnection(ref channelId, remoteEndPoint); -// break; -// } -// // 接收KCP的数据 -// case KcpHeader.ReceiveData: -// { -// if (buffer.Length == 5) -// { -// Log.Warning($"KCP Server KcpHeader.Data buffer.Length == 5"); -// break; -// } -// -// if (_connectionChannel.TryGetValue(channelId, out var channel)) -// { -// channel.Input(buffer.AsMemory().Slice(5, receivedBytes - 5)); -// } -// -// break; -// } -// // 断开KCP连接 -// case KcpHeader.Disconnect: -// { -// // 断开不需要清楚PendingConnection让ClearPendingConnection自动清楚就可以了,并且不一定有Pending。 -// RemoveChannel(channelId); -// break; -// } -// } -// } -// finally -// { -// BufferPool.Return(buffer); -// } -// } -// -// #endregion -// -// #region Update -// -// public void Update() -// { -// var timeNow = TimeNow; -// _allowWraparound = timeNow < _updateMinTime; -// CheckUpdateTimerOut(ref timeNow); -// UpdateChannel(ref timeNow); -// PendingTimerOut(ref timeNow); -// _allowWraparound = true; -// } -// -// private void CheckUpdateTimerOut(ref uint nowTime) -// { -// if (_updateTimer.Count == 0) -// { -// return; -// } -// -// if (IsTimeGreaterThan(_updateMinTime, nowTime)) -// { -// return; -// } -// -// _updateTimeOutTime.Clear(); -// -// foreach (var kv in _updateTimer) -// { -// var timeId = kv.Key; -// -// if (IsTimeGreaterThan(timeId, nowTime)) -// { -// _updateMinTime = timeId; -// break; -// } -// -// _updateTimeOutTime.Add(timeId); -// } -// -// foreach (var timeId in _updateTimeOutTime) -// { -// foreach (var channelId in _updateTimer[timeId]) -// { -// _updateChannels.Add(channelId); -// } -// -// _updateTimer.RemoveKey(timeId); -// } -// } -// -// private void UpdateChannel(ref uint timeNow) -// { -// foreach (var channelId in _updateChannels) -// { -// if (!_connectionChannel.TryGetValue(channelId, out var channel)) -// { -// continue; -// } -// -// if (channel.IsDisposed) -// { -// _connectionChannel.Remove(channelId); -// continue; -// } -// -// channel.Kcp.Update(timeNow); -// AddUpdateChannel(channelId, channel.Kcp.Check(timeNow)); -// } -// -// _updateChannels.Clear(); -// } -// -// private void PendingTimerOut(ref uint timeNow) -// { -// if (_pendingConnectionTimeOut.Count == 0) -// { -// return; -// } -// -// if (IsTimeGreaterThan(_pendingMinTime, timeNow)) -// { -// return; -// } -// -// _pendingTimeOutTime.Clear(); -// -// foreach (var kv in _pendingConnectionTimeOut) -// { -// var timeId = kv.Key; -// -// if (IsTimeGreaterThan(timeId, timeNow)) -// { -// _pendingMinTime = timeId; -// break; -// } -// -// _pendingTimeOutTime.Add(timeId); -// } -// -// foreach (var timeId in _pendingTimeOutTime) -// { -// foreach (var channelId in _pendingConnectionTimeOut[timeId]) -// { -// _pendingConnection.Remove(channelId); -// } -// -// _pendingConnectionTimeOut.RemoveKey(timeId); -// } -// } -// -// public void AddUpdateChannel(uint channelId, uint tillTime) -// { -// if (tillTime == 0) -// { -// _updateChannels.Add(channelId); -// return; -// } -// -// if (IsTimeGreaterThan(_updateMinTime, tillTime)) -// { -// _updateMinTime = tillTime; -// } -// -// _updateTimer.Add(tillTime, channelId); -// } -// -// private const uint HalfMaxUint = uint.MaxValue / 2; -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private bool IsTimeGreaterThan(uint timeId, uint nowTime) -// { -// if (!_allowWraparound) -// { -// return timeId > nowTime; -// } -// -// var diff = timeId - nowTime; -// // 如果 diff 的值在 [0, HalfMaxUint] 范围内,说明 timeId 是在 nowTime 之后或相等。 -// // 如果 diff 的值在 (HalfMaxUint, uint.MaxValue] 范围内,说明 timeId 是在 nowTime 之前(时间回绕的情况)。 -// return diff < HalfMaxUint || diff == HalfMaxUint; -// } -// -// #endregion -// -// #region Pending -// -// private void AddPendingConnection(ref uint channelId, IPEndPoint ipEndPoint) -// { -// var now = TimeNow; -// var pendingConnection = new PendingConnection(channelId, ipEndPoint, now); -// -// if (IsTimeGreaterThan(_pendingMinTime, pendingConnection.TimeOutId) || _pendingMinTime == 0) -// { -// _pendingMinTime = pendingConnection.TimeOutId; -// } -// -// _pendingConnection.Add(channelId, pendingConnection); -// _pendingConnectionTimeOut.Add(pendingConnection.TimeOutId, channelId); -// SendWaitConfirmConnection(ref channelId, ipEndPoint); -// } -// -// private bool ConfirmPendingConnection(ref uint channelId, EndPoint ipEndPoint) -// { -// if (!_pendingConnection.TryGetValue(channelId, out var pendingConnection)) -// { -// return false; -// } -// -// if (!ipEndPoint.IPEndPointEquals(pendingConnection.RemoteEndPoint)) -// { -// Log.Error($"KCPSocket syn address diff: {channelId} {pendingConnection.RemoteEndPoint} {ipEndPoint}"); -// return false; -// } -// -// _pendingConnection.Remove(channelId); -// _pendingConnectionTimeOut.RemoveValue(pendingConnection.TimeOutId, pendingConnection.ChannelId); -// #if FANTASY_DEVELOP -// Log.Debug($"KCPSocket _pendingConnection:{_pendingConnection.Count} _pendingConnectionTimer:{_pendingConnectionTimeOut.Count}"); -// #endif -// return true; -// } -// -// #endregion -// -// #region Connection -// -// private void AddConnection(ref uint channelId, IPEndPoint ipEndPoint) -// { -// var eventArgs = new KCPServerNetworkChannel(this, channelId, ipEndPoint); -// _connectionChannel.Add(channelId, eventArgs); -// #if FANTASY_DEVELOP -// Log.Debug($"AddConnection _connectionChannel:{_connectionChannel.Count()}"); -// #endif -// } -// -// public override void RemoveChannel(uint channelId) -// { -// if (!_connectionChannel.Remove(channelId, out var channel)) -// { -// return; -// } -// -// if (!channel.IsDisposed) -// { -// SendDisconnect(ref channelId, channel.RemoteEndPoint); -// channel.Dispose(); -// } -// #if FANTASY_DEVELOP -// Log.Debug($"RemoveChannel _connectionChannel:{_connectionChannel.Count()}"); -// #endif -// } -// -// #endregion -// -// #region Send -// -// private const byte KcpHeaderDisconnect = (byte)KcpHeader.Disconnect; -// private const byte KcpHeaderRepeatChannelId = (byte)KcpHeader.RepeatChannelId; -// private const byte KcpHeaderWaitConfirmConnection = (byte)KcpHeader.WaitConfirmConnection; -// -// private unsafe void SendDisconnect(ref uint channelId, EndPoint clientEndPoint) -// { -// fixed (byte* p = _sendBuff) -// { -// p[0] = KcpHeaderDisconnect; -// *(uint*)(p + 1) = channelId; -// } -// -// SendAsync(_sendBuff, 0, 5, clientEndPoint); -// } -// -// private unsafe void SendRepeatChannelId(ref uint channelId, EndPoint clientEndPoint) -// { -// fixed (byte* p = _sendBuff) -// { -// p[0] = KcpHeaderRepeatChannelId; -// *(uint*)(p + 1) = channelId; -// } -// -// SendAsync(_sendBuff, 0, 5, clientEndPoint); -// } -// -// private unsafe void SendWaitConfirmConnection(ref uint channelId, EndPoint clientEndPoint) -// { -// fixed (byte* p = _sendBuff) -// { -// p[0] = KcpHeaderWaitConfirmConnection; -// *(uint*)(p + 1) = channelId; -// } -// -// SendAsync(_sendBuff, 0, 5, clientEndPoint); -// } -// -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// public void SendAsync(byte[] buffer, int offset, int count, EndPoint endPoint) -// { -// try -// { -// _socket.SendTo(new ArraySegment(buffer, offset, count), SocketFlags.None, endPoint); -// } -// catch (ArgumentException ex) -// { -// Log.Error($"ArgumentException: {ex.Message}"); // 处理参数错误 -// } -// catch (SocketException) -// { -// //Log.Error($"SocketException: {ex.Message}"); // 处理网络错误 -// } -// catch (ObjectDisposedException) -// { -// // 处理套接字已关闭的情况 -// } -// catch (InvalidOperationException ex) -// { -// Log.Error($"InvalidOperationException: {ex.Message}"); // 处理无效操作 -// } -// catch (Exception ex) -// { -// Log.Error($"Exception: {ex.Message}"); // 捕获其他异常 -// } -// } -// -// #endregion -// } -// } -// -// #endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByPipe.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByPipe.cs deleted file mode 100644 index 54b550d..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkByPipe.cs +++ /dev/null @@ -1,619 +0,0 @@ -#if FANTASY_NET -using System.Buffers; -using System.IO.Pipelines; -using System.Net; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Fantasy.Async; -using Fantasy.DataStructure.Collection; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8602 // Dereference of a possibly null reference. - -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). - -namespace Fantasy.Network.KCP -{ - public sealed class KCPServerNetworkUpdateSystem : UpdateSystem - { - protected override void Update(KCPServerNetwork self) - { - self.Update(); - } - } - - public struct PendingConnection - { - public readonly uint ChannelId; - public readonly uint TimeOutId; - public readonly IPEndPoint RemoteEndPoint; - - public PendingConnection(uint channelId, IPEndPoint remoteEndPoint, uint time) - { - ChannelId = channelId; - RemoteEndPoint = remoteEndPoint; - TimeOutId = time + 10 * 1000; // 设置10秒超时,如果10秒内没有确认连接则删除。 - } - } - - public sealed class KCPServerNetwork : ANetwork - { - private Socket _socket; - private long _startTime; - private uint _updateMinTime; - private uint _pendingMinTime; - private bool _allowWraparound = true; - private readonly Pipe _pipe = new Pipe(); - private readonly byte[] _sendBuff = new byte[5]; - private readonly List _pendingTimeOutTime = new List(); - private readonly HashSet _updateChannels = new HashSet(); - private readonly List _updateTimeOutTime = new List(); - private readonly Queue _endPoint = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - private readonly SortedOneToManyList _updateTimer = new SortedOneToManyList(); - - private readonly Dictionary _pendingConnection = new Dictionary(); - private readonly SortedOneToManyList _pendingConnectionTimeOut = new SortedOneToManyList(); - private readonly Dictionary _connectionChannel = new Dictionary(); - - public KCPSettings Settings { get; private set; } - - private uint TimeNow => (uint)(TimeHelper.Now - _startTime); - - public void Initialize(NetworkTarget networkTarget, IPEndPoint address) - { - _startTime = TimeHelper.Now; - Settings = KCPSettings.Create(networkTarget); - base.Initialize(NetworkType.Server, NetworkProtocolType.KCP, networkTarget); - _socket = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); - _socket.Blocking = false; - _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); - if (address.AddressFamily == AddressFamily.InterNetworkV6) - { - _socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); - } - - _socket.Blocking = false; - _socket.Bind(address); - _socket.SetSocketBufferToOsLimit(); - _socket.SetSioUdpConnReset(); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - Log.Info($"SceneConfigId = {Scene.SceneConfigId} networkTarget = {networkTarget.ToString()} KCPServer Listen {address}"); - } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - foreach (var (_, channel) in _connectionChannel.ToArray()) - { - channel.Dispose(); - } - - _connectionChannel.Clear(); - _pendingConnection.Clear(); - - if (_socket != null) - { - _socket.Dispose(); - _socket = null; - } - - base.Dispose(); - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); - var socketReceiveFromResult = await _socket.ReceiveFromAsync(memory, SocketFlags.None, remoteEndPoint, _cancellationTokenSource.Token); - var receivedBytes = socketReceiveFromResult.ReceivedBytes; - - if (receivedBytes == 5) - { - switch ((KcpHeader)memory.Span[0]) - { - case KcpHeader.RequestConnection: - case KcpHeader.ConfirmConnection: - { - _endPoint.Enqueue(socketReceiveFromResult.RemoteEndPoint.Clone()); - break; - } - } - } - - _pipe.Writer.Advance(receivedBytes); - await _pipe.Writer.FlushAsync(); - } - catch (SocketException ex) - { - Log.Error($"Socket exception: {ex.Message}"); - Dispose(); - break; - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (Exception ex) - { - Log.Error($"Unexpected exception: {ex.Message}"); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var header, out var channelId, out var message)) - { - ReceiveData(ref header, ref channelId, ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private unsafe bool TryReadMessage(ref ReadOnlySequence buffer, out KcpHeader header, out uint channelId, out ReadOnlyMemory message) - { - if (buffer.Length < 5) - { - channelId = 0; - message = default; - header = KcpHeader.None; - if (buffer.Length > 0) - { - buffer = buffer.Slice(buffer.Length); - } - return false; - } - - var readOnlyMemory = buffer.First; - - if (MemoryMarshal.TryGetArray(readOnlyMemory, out var arraySegment)) - { - fixed (byte* bytePointer = &arraySegment.Array[arraySegment.Offset]) - { - header = (KcpHeader)bytePointer[0]; - channelId = Unsafe.ReadUnaligned(ref bytePointer[1]); - } - } - else - { - // 如果无法获取数组段,回退到安全代码来执行。这种情况几乎不会发生、为了保险还是写一下了。 - var firstSpan = readOnlyMemory.Span; - header = (KcpHeader)firstSpan[0]; - channelId = MemoryMarshal.Read(firstSpan.Slice(1, 4)); - } - - message = readOnlyMemory.Slice(5); - buffer = buffer.Slice(readOnlyMemory.Length); - return true; - } - - private void ReceiveData(ref KcpHeader header, ref uint channelId, ref ReadOnlyMemory buffer) - { - switch (header) - { - // 客户端请求建立KCP连接 - case KcpHeader.RequestConnection: - { - _endPoint.TryDequeue(out var ipEndPoint); - - if (_pendingConnection.TryGetValue(channelId, out var pendingConnection)) - { - if (!ipEndPoint.IPEndPointEquals(pendingConnection.RemoteEndPoint)) - { - // 重复通道ID,向客户端发送重复通道ID消息 - SendRepeatChannelId(ref channelId, ipEndPoint); - } - - break; - } - - if (_connectionChannel.ContainsKey(channelId)) - { - // 已存在的通道ID,向客户端发送重复通道ID消息 - SendRepeatChannelId(ref channelId, ipEndPoint); - break; - } - - AddPendingConnection(ref channelId, ipEndPoint); - break; - } - // 客户端确认建立KCP连接 - case KcpHeader.ConfirmConnection: - { - _endPoint.TryDequeue(out var ipEndPoint); - if (!ConfirmPendingConnection(ref channelId, ipEndPoint)) - { - break; - } - - AddConnection(ref channelId, ipEndPoint.Clone()); - break; - } - // 接收KCP的数据 - case KcpHeader.ReceiveData: - { - if (buffer.Length == 5) - { - Log.Warning($"KCP Server KcpHeader.Data buffer.Length == 5"); - break; - } - - if (_connectionChannel.TryGetValue(channelId, out var channel)) - { - channel.Input(buffer); - } - - break; - } - // 断开KCP连接 - case KcpHeader.Disconnect: - { - // 断开不需要清楚PendingConnection让ClearPendingConnection自动清楚就可以了,并且不一定有Pending。 - RemoveChannel(channelId); - break; - } - } - } - - #endregion - - #region Update - - public void Update() - { - var timeNow = TimeNow; - _allowWraparound = timeNow < _updateMinTime; - CheckUpdateTimerOut(ref timeNow); - UpdateChannel(ref timeNow); - PendingTimerOut(ref timeNow); - _allowWraparound = true; - } - - private void CheckUpdateTimerOut(ref uint nowTime) - { - if (_updateTimer.Count == 0) - { - return; - } - - if (IsTimeGreaterThan(_updateMinTime, nowTime)) - { - return; - } - - _updateTimeOutTime.Clear(); - - foreach (var kv in _updateTimer) - { - var timeId = kv.Key; - - if (IsTimeGreaterThan(timeId, nowTime)) - { - _updateMinTime = timeId; - break; - } - - _updateTimeOutTime.Add(timeId); - } - - foreach (var timeId in _updateTimeOutTime) - { - foreach (var channelId in _updateTimer[timeId]) - { - _updateChannels.Add(channelId); - } - - _updateTimer.RemoveKey(timeId); - } - } - - private void UpdateChannel(ref uint timeNow) - { - foreach (var channelId in _updateChannels) - { - if (!_connectionChannel.TryGetValue(channelId, out var channel)) - { - continue; - } - - if (channel.IsDisposed) - { - _connectionChannel.Remove(channelId); - continue; - } - - channel.Kcp.Update(timeNow); - AddUpdateChannel(channelId, channel.Kcp.Check(timeNow)); - } - - _updateChannels.Clear(); - } - - private void PendingTimerOut(ref uint timeNow) - { - if (_pendingConnectionTimeOut.Count == 0) - { - return; - } - - if (IsTimeGreaterThan(_pendingMinTime, timeNow)) - { - return; - } - - _pendingTimeOutTime.Clear(); - - foreach (var kv in _pendingConnectionTimeOut) - { - var timeId = kv.Key; - - if (IsTimeGreaterThan(timeId, timeNow)) - { - _pendingMinTime = timeId; - break; - } - - _pendingTimeOutTime.Add(timeId); - } - - foreach (var timeId in _pendingTimeOutTime) - { - foreach (var channelId in _pendingConnectionTimeOut[timeId]) - { - _pendingConnection.Remove(channelId); - } - - _pendingConnectionTimeOut.RemoveKey(timeId); - } - } - - public void AddUpdateChannel(uint channelId, uint tillTime) - { - if (tillTime == 0) - { - _updateChannels.Add(channelId); - return; - } - - if (IsTimeGreaterThan(_updateMinTime, tillTime)) - { - _updateMinTime = tillTime; - } - - _updateTimer.Add(tillTime, channelId); - } - - private const uint HalfMaxUint = uint.MaxValue / 2; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool IsTimeGreaterThan(uint timeId, uint nowTime) - { - if (!_allowWraparound) - { - return timeId > nowTime; - } - - var diff = timeId - nowTime; - // 如果 diff 的值在 [0, HalfMaxUint] 范围内,说明 timeId 是在 nowTime 之后或相等。 - // 如果 diff 的值在 (HalfMaxUint, uint.MaxValue] 范围内,说明 timeId 是在 nowTime 之前(时间回绕的情况)。 - return diff < HalfMaxUint || diff == HalfMaxUint; - } - - #endregion - - #region Pending - - private void AddPendingConnection(ref uint channelId, IPEndPoint ipEndPoint) - { - var now = TimeNow; - var pendingConnection = new PendingConnection(channelId, ipEndPoint, now); - - if (IsTimeGreaterThan(_pendingMinTime, pendingConnection.TimeOutId) || _pendingMinTime == 0) - { - _pendingMinTime = pendingConnection.TimeOutId; - } - - _pendingConnection.Add(channelId, pendingConnection); - _pendingConnectionTimeOut.Add(pendingConnection.TimeOutId, channelId); - SendWaitConfirmConnection(ref channelId, ipEndPoint); - } - - private bool ConfirmPendingConnection(ref uint channelId, EndPoint ipEndPoint) - { - if (!_pendingConnection.TryGetValue(channelId, out var pendingConnection)) - { - return false; - } - - if (!ipEndPoint.IPEndPointEquals(pendingConnection.RemoteEndPoint)) - { - Log.Error($"KCPSocket syn address diff: {channelId} {pendingConnection.RemoteEndPoint} {ipEndPoint}"); - return false; - } - - _pendingConnection.Remove(channelId); - _pendingConnectionTimeOut.RemoveValue(pendingConnection.TimeOutId, pendingConnection.ChannelId); -#if FANTASY_DEVELOP - Log.Debug($"KCPSocket _pendingConnection:{_pendingConnection.Count} _pendingConnectionTimer:{_pendingConnectionTimeOut.Count}"); -#endif - return true; - } - - #endregion - - #region Connection - - private void AddConnection(ref uint channelId, IPEndPoint ipEndPoint) - { - var eventArgs = new KCPServerNetworkChannel(this, channelId, ipEndPoint); - _connectionChannel.Add(channelId, eventArgs); -#if FANTASY_DEVELOP - Log.Debug($"AddConnection _connectionChannel:{_connectionChannel.Count()}"); -#endif - } - - public override void RemoveChannel(uint channelId) - { - if (!_connectionChannel.Remove(channelId, out var channel)) - { - return; - } - - if (!channel.IsDisposed) - { - SendDisconnect(ref channelId, channel.RemoteEndPoint); - channel.Dispose(); - } -#if FANTASY_DEVELOP - Log.Debug($"RemoveChannel _connectionChannel:{_connectionChannel.Count()}"); -#endif - } - - #endregion - - #region Send - - private const byte KcpHeaderDisconnect = (byte)KcpHeader.Disconnect; - private const byte KcpHeaderRepeatChannelId = (byte)KcpHeader.RepeatChannelId; - private const byte KcpHeaderWaitConfirmConnection = (byte)KcpHeader.WaitConfirmConnection; - - private unsafe void SendDisconnect(ref uint channelId, EndPoint clientEndPoint) - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderDisconnect; - *(uint*)(p + 1) = channelId; - } - - SendAsync(_sendBuff, 0, 5, clientEndPoint); - } - - private unsafe void SendRepeatChannelId(ref uint channelId, EndPoint clientEndPoint) - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderRepeatChannelId; - *(uint*)(p + 1) = channelId; - } - - SendAsync(_sendBuff, 0, 5, clientEndPoint); - } - - private unsafe void SendWaitConfirmConnection(ref uint channelId, EndPoint clientEndPoint) - { - fixed (byte* p = _sendBuff) - { - p[0] = KcpHeaderWaitConfirmConnection; - *(uint*)(p + 1) = channelId; - } - - SendAsync(_sendBuff, 0, 5, clientEndPoint); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SendAsync(byte[] buffer, int offset, int count, EndPoint endPoint) - { - try - { - _socket.SendTo(new ArraySegment(buffer, offset, count), SocketFlags.None, endPoint); - } - catch (ArgumentException ex) - { - Log.Error($"ArgumentException: {ex.Message}"); // 处理参数错误 - } - catch (SocketException) - { - //Log.Error($"SocketException: {ex.Message}"); // 处理网络错误 - } - catch (ObjectDisposedException) - { - // 处理套接字已关闭的情况 - } - catch (InvalidOperationException ex) - { - Log.Error($"InvalidOperationException: {ex.Message}"); // 处理无效操作 - } - catch (Exception ex) - { - Log.Error($"Exception: {ex.Message}"); // 捕获其他异常 - } - } - - #endregion - } -} - -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkChannel.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkChannel.cs deleted file mode 100644 index 19db7a7..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/KCP/Server/KCPServerNetworkChannel.cs +++ /dev/null @@ -1,165 +0,0 @@ -#if FANTASY_NET -using System.Net; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -using KCP; -// ReSharper disable ParameterHidesMember -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.KCP -{ - /// - /// KCP 服务器网络通道,用于处理服务器与客户端之间的数据通信。 - /// - public class KCPServerNetworkChannel : ANetworkServerChannel - { - private bool _isInnerDispose; - private readonly int _maxSndWnd; - private KCPServerNetwork _kcpServerNetwork; - private readonly BufferPacketParser _packetParser; - private readonly byte[] _receiveBuffer = new byte[Packet.PacketBodyMaxLength + 20]; - public Kcp Kcp { get; private set; } - public uint ChannelId { get; private set; } - - public KCPServerNetworkChannel(KCPServerNetwork network, uint channelId, IPEndPoint ipEndPoint) : base(network, channelId, ipEndPoint) - { - _kcpServerNetwork = network; - ChannelId = channelId; - _maxSndWnd = network.Settings.MaxSendWindowSize; - Kcp = KCPFactory.Create(network.Settings, ChannelId, KcpSpanCallback); - _packetParser = PacketParserFactory.CreateServerBufferPacket(network); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isInnerDispose = true; - _kcpServerNetwork.RemoveChannel(Id); - IsDisposed = true; - Kcp.Dispose(); - Kcp = null; - ChannelId = 0; - _kcpServerNetwork = null; - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - public void Input(ReadOnlyMemory buffer) - { - Kcp.Input(buffer.Span); - _kcpServerNetwork.AddUpdateChannel(ChannelId, 0); - - while (!IsDisposed) - { - try - { - var peekSize = Kcp.PeekSize(); - - if (peekSize < 0) - { - return; - } - - var receiveCount = Kcp.Receive(_receiveBuffer.AsSpan(0, peekSize)); - - if (receiveCount != peekSize) - { - return; - } - - if (!_packetParser.UnPack(_receiveBuffer, ref receiveCount, out var packInfo)) - { - continue; - } - - Session.Receive(packInfo); - } - catch (ScanException e) - { - Log.Debug($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - if (IsDisposed) - { - return; - } - - if (Kcp.WaitSendCount > _maxSndWnd) - { - // 检查等待发送的消息,如果超出两倍窗口大小,KCP作者给的建议是要断开连接 - Log.Warning($"ERR_KcpWaitSendSizeTooLarge {Kcp.WaitSendCount} > {_maxSndWnd}"); - Dispose(); - return; - } - - var buffer = _packetParser.Pack(ref rpcId, ref routeId, memoryStream, message); - Kcp.Send(buffer.GetBuffer().AsSpan(0, (int)buffer.Position)); - - if (buffer.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - _kcpServerNetwork.MemoryStreamBufferPool.ReturnMemoryStream(buffer); - } - - _kcpServerNetwork.AddUpdateChannel(ChannelId, 0); - } - - private const byte KcpHeaderReceiveData = (byte)KcpHeader.ReceiveData; - - private unsafe void KcpSpanCallback(byte[] buffer, int count) - { - if (IsDisposed) - { - return; - } - - try - { - if (count == 0) - { - throw new Exception("KcpOutput count 0"); - } - - fixed (byte* p = buffer) - { - p[0] = KcpHeaderReceiveData; - *(uint*)(p + 1) = ChannelId; - } - - _kcpServerNetwork.SendAsync(buffer, 0, count + 5, RemoteEndPoint); - } - catch (Exception e) - { - Log.Error(e); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/NetworkProtocolFactory.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/NetworkProtocolFactory.cs deleted file mode 100644 index c7b6ecc..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/NetworkProtocolFactory.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Net; -using Fantasy.Entitas; -using Fantasy.Helper; -using Fantasy.Network.Interface; -#if !FANTASY_WEBGL -using Fantasy.Network.TCP; -using Fantasy.Network.KCP; -#endif -#if FANTASY_NET -using Fantasy.Network.HTTP; -#endif -using Fantasy.Network.WebSocket; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network -{ - internal static class NetworkProtocolFactory - { -#if FANTASY_NET - public static ANetwork CreateServer(Scene scene, NetworkProtocolType protocolType, NetworkTarget networkTarget, string bindIp, int port) - { - switch (protocolType) - { - case NetworkProtocolType.TCP: - { - var network = Entity.Create(scene, false, false); - var address = NetworkHelper.ToIPEndPoint(bindIp, port); - network.Initialize(networkTarget, address); - return network; - } - case NetworkProtocolType.KCP: - { - var network = Entity.Create(scene, false, true); - var address = NetworkHelper.ToIPEndPoint(bindIp, port); - network.Initialize(networkTarget, address); - return network; - } - case NetworkProtocolType.WebSocket: - { - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget, bindIp, port); - return network; - } - case NetworkProtocolType.HTTP: - { - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget, bindIp, port); - return network; - } - default: - { - throw new NotSupportedException($"Unsupported NetworkProtocolType:{protocolType}"); - } - } - } -#endif - public static AClientNetwork CreateClient(Scene scene, NetworkProtocolType protocolType, NetworkTarget networkTarget) - { -#if !FANTASY_WEBGL - switch (protocolType) - { - case NetworkProtocolType.TCP: - { - var network = Entity.Create(scene, false, false); - network.Initialize(networkTarget); - return network; - } - case NetworkProtocolType.KCP: - { - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget); - return network; - } - case NetworkProtocolType.WebSocket: - { - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget); - return network; - } - default: - { - throw new NotSupportedException($"Unsupported NetworkProtocolType:{protocolType}"); - } - } -#else - // Webgl平台只能用这个协议。 - var network = Entity.Create(scene, false, true); - network.Initialize(networkTarget); - return network; -#endif - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/NetworkProtocolType.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/NetworkProtocolType.cs deleted file mode 100644 index 55a04c9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/NetworkProtocolType.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace Fantasy.Network -{ - /// - /// 网络服务器类型 - /// - public enum NetworkType - { - /// - /// 默认 - /// - None = 0, - /// - /// 客户端网络 - /// - Client = 1, -#if FANTASY_NET - /// - /// 服务器网络 - /// - Server = 2 -#endif - } - /// - /// 网络服务的目标 - /// - public enum NetworkTarget - { - /// - /// 默认 - /// - None = 0, - /// - /// 对外 - /// - Outer = 1, -#if FANTASY_NET - /// - /// 对内 - /// - Inner = 2 -#endif - } - /// - /// 支持的网络协议 - /// - public enum NetworkProtocolType - { - /// - /// 默认 - /// - None = 0, - /// - /// KCP - /// - KCP = 1, - /// - /// TCP - /// - TCP = 2, - /// - /// WebSocket - /// - WebSocket = 3, - /// - /// HTTP - /// - HTTP = 4, - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/NetworkThreadComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/NetworkThreadComponent.cs deleted file mode 100644 index c0c166b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/NetworkThreadComponent.cs +++ /dev/null @@ -1,100 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Threading; -using Fantasy.Entitas; -// ReSharper disable ForCanBeConvertedToForeach -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Network -{ - internal interface INetworkThreadUpdate - { - void Update(); - } - - /// - /// 网络线程组件 - /// - internal sealed class NetworkThreadComponent : Entity - { - private Thread _netWorkThread; - internal ThreadSynchronizationContext SynchronizationContext { get; private set; } - private readonly List _updates = new List(); - - internal NetworkThreadComponent Initialize() - { - SynchronizationContext = new ThreadSynchronizationContext(); - _netWorkThread = new Thread(Update) - { - IsBackground = true - }; - _netWorkThread.Start(); - return this; - } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - SynchronizationContext.Post(() => - { - _updates.Clear(); - _netWorkThread.Join(); - _netWorkThread = null; - SynchronizationContext = null; - }); - - base.Dispose(); - } - - private void Update() - { - // 将同步上下文设置为网络线程的上下文,以确保操作在正确的线程上下文中执行。 - System.Threading.SynchronizationContext.SetSynchronizationContext(SynchronizationContext); - // 循环执行 - while (!IsDisposed) - { - for (var i = 0; i < _updates.Count; i++) - { - try - { - _updates[i].Update(); - } - catch (Exception e) - { - Log.Error(e); - } - } - SynchronizationContext.Update(); - Thread.Sleep(1); - } - } - - internal void AddNetworkThreadUpdate(INetworkThreadUpdate update) - { - SynchronizationContext.Post(() => - { - if (_updates.Contains(update)) - { - Log.Warning($"{update.GetType().FullName} Network thread update is already running"); - return; - } - _updates.Add(update); - }); - } - - internal void RemoveNetworkThreadUpdate(INetworkThreadUpdate update) - { - SynchronizationContext.Post(() => - { - _updates.Remove(update); - }); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/TCP/Client/TCPClientNetwork.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/TCP/Client/TCPClientNetwork.cs deleted file mode 100644 index 233fb7b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/TCP/Client/TCPClientNetwork.cs +++ /dev/null @@ -1,413 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Buffers; -using System.Collections.Generic; -using System.IO; -using System.IO.Pipelines; -using System.Net; -using System.Net.Sockets; -using System.Runtime.InteropServices; -using System.Threading; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). - -namespace Fantasy.Network.TCP -{ - public sealed class TCPClientNetwork : AClientNetwork - { - private bool _isSending; - private bool _isInnerDispose; - private long _connectTimeoutId; - private Socket _socket; - private IPEndPoint _remoteEndPoint; - private SocketAsyncEventArgs _sendArgs; - private ReadOnlyMemoryPacketParser _packetParser; - private readonly Pipe _pipe = new Pipe(); - private readonly Queue _sendBuffers = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - private Action _onConnectFail; - private Action _onConnectComplete; - private Action _onConnectDisconnect; - - public uint ChannelId { get; private set; } - - public void Initialize(NetworkTarget networkTarget) - { - base.Initialize(NetworkType.Client, NetworkProtocolType.TCP, networkTarget); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isSending = false; - _isInnerDispose = true; - ClearConnectTimeout(); - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - _onConnectDisconnect?.Invoke(); - - if (_socket.Connected) - { - _socket.Close(); - _socket = null; - } - - _sendBuffers.Clear(); - _packetParser?.Dispose(); - ChannelId = 0; - _sendArgs = null; - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - /// - /// 连接到远程服务器。 - /// - /// 远程服务器的终端点。 - /// 连接成功时的回调。 - /// 连接失败时的回调。 - /// 连接断开时的回调。 - /// - /// 连接超时时间,单位:毫秒。 - /// 连接的会话。 - public override Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - // 如果已经初始化过一次,抛出异常,要求重新实例化 - - if (IsInit) - { - throw new NotSupportedException("TCPClientNetwork Has already been initialized. If you want to call Connect again, please re instantiate it."); - } - - IsInit = true; - _isSending = false; - _onConnectFail = onConnectFail; - _onConnectComplete = onConnectComplete; - _onConnectDisconnect = onConnectDisconnect; - // 设置连接超时定时器 - _connectTimeoutId = Scene.TimerComponent.Net.OnceTimer(connectTimeout, () => - { - _onConnectFail?.Invoke(); - Dispose(); - }); - _packetParser = PacketParserFactory.CreateClientReadOnlyMemoryPacket(this); - _remoteEndPoint = NetworkHelper.GetIPEndPoint(remoteAddress); - _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - _socket.NoDelay = true; - _socket.SetSocketBufferToOsLimit(); - _sendArgs = new SocketAsyncEventArgs(); - _sendArgs.Completed += OnSendCompleted; - var outArgs = new SocketAsyncEventArgs - { - RemoteEndPoint = _remoteEndPoint - }; - outArgs.Completed += OnConnectSocketCompleted; - - if (!_socket.ConnectAsync(outArgs)) - { - OnReceiveSocketComplete(); - } - - Session = Session.Create(this, _remoteEndPoint); - return Session; - } - - private void OnConnectSocketCompleted(object sender, SocketAsyncEventArgs asyncEventArgs) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - if (asyncEventArgs.LastOperation == SocketAsyncOperation.Connect) - { - if (asyncEventArgs.SocketError == SocketError.Success) - { - Scene.ThreadSynchronizationContext.Post(OnReceiveSocketComplete); - } - else - { - Scene.ThreadSynchronizationContext.Post(() => - { - _onConnectFail?.Invoke(); - Dispose(); - }); - } - } - } - - private void OnReceiveSocketComplete() - { - ClearConnectTimeout(); - _onConnectComplete?.Invoke(); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); -#if UNITY_2021 - // Unity2021.3.14f有个恶心的问题,使用ReceiveAsync会导致memory不能正确写入 - // 所有只能使用ReceiveFromAsync来接收消息,但ReceiveFromAsync只有一个接受ArraySegment的接口。 - MemoryMarshal.TryGetArray(memory, out ArraySegment arraySegment); - var result = await _socket.ReceiveFromAsync(arraySegment, SocketFlags.None, _remoteEndPoint); - _pipe.Writer.Advance(result.ReceivedBytes); -#else - var count = await _socket.ReceiveAsync(memory, SocketFlags.None, _cancellationTokenSource.Token); - _pipe.Writer.Advance(count); -#endif - await _pipe.Writer.FlushAsync(); - } - catch (SocketException) - { - Dispose(); - break; - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (Exception ex) - { - Log.Error($"Unexpected exception: {ex.Message}"); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var message)) - { - ReceiveData(ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private bool TryReadMessage(ref ReadOnlySequence buffer, out ReadOnlyMemory message) - { - if (buffer.Length == 0) - { - message = default; - return false; - } - - message = buffer.First; - - if (message.Length == 0) - { - message = default; - return false; - } - - buffer = buffer.Slice(message.Length); - return true; - } - - private void ReceiveData(ref ReadOnlyMemory buffer) - { - try - { - while (_packetParser.UnPack(ref buffer, out var packInfo)) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - Session.Receive(packInfo); - } - } - catch (ScanException e) - { - Log.Warning(e.Message); - Dispose(); - } - catch (Exception e) - { - Log.Error(e); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - _sendBuffers.Enqueue(_packetParser.Pack(ref rpcId, ref routeId, memoryStream, message)); - - if (!_isSending) - { - Send(); - } - } - - private void Send() - { - if (_isSending || IsDisposed) - { - return; - } - - _isSending = true; - - while (_sendBuffers.Count > 0) - { - var memoryStreamBuffer = _sendBuffers.Dequeue(); - _sendArgs.UserToken = memoryStreamBuffer; - _sendArgs.SetBuffer(new ArraySegment(memoryStreamBuffer.GetBuffer(), 0, (int)memoryStreamBuffer.Position)); - - try - { - if (_socket.SendAsync(_sendArgs)) - { - break; - } - - ReturnMemoryStream(memoryStreamBuffer); - } - catch - { - _isSending = false; - return; - } - } - - _isSending = false; - } - - private void ReturnMemoryStream(MemoryStreamBuffer memoryStream) - { - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - - private void OnSendCompleted(object sender, SocketAsyncEventArgs asyncEventArgs) - { - if (asyncEventArgs.SocketError != SocketError.Success || asyncEventArgs.BytesTransferred == 0) - { - _isSending = false; - return; - } - - var memoryStreamBuffer = (MemoryStreamBuffer)asyncEventArgs.UserToken; - Scene.ThreadSynchronizationContext.Post(() => - { - ReturnMemoryStream(memoryStreamBuffer); - - if (_sendBuffers.Count > 0) - { - Send(); - } - else - { - _isSending = false; - } - }); - } - - #endregion - - public override void RemoveChannel(uint channelId) - { - Dispose(); - } - - private void ClearConnectTimeout() - { - if (_connectTimeoutId == 0) - { - return; - } - - Scene?.TimerComponent?.Net?.Remove(ref _connectTimeoutId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetwork.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetwork.cs deleted file mode 100644 index 3e8efb4..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetwork.cs +++ /dev/null @@ -1,161 +0,0 @@ -#if FANTASY_NET -using System.Net; -using System.Net.Sockets; -using Fantasy.Helper; -using Fantasy.Network.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -// ReSharper disable GCSuppressFinalizeForTypeWithoutDestructor -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Network.TCP -{ - public sealed class TCPServerNetwork : ANetwork - { - private Random _random; - private Socket _socket; - private SocketAsyncEventArgs _acceptAsync; - private readonly Dictionary _connectionChannel = new Dictionary(); - - public void Initialize(NetworkTarget networkTarget, IPEndPoint address) - { - base.Initialize(NetworkType.Server, NetworkProtocolType.TCP, networkTarget); - _random = new Random(); - _acceptAsync = new SocketAsyncEventArgs(); - _socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); - - if (address.AddressFamily == AddressFamily.InterNetworkV6) - { - _socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); - } - - _socket.Bind(address); - _socket.Listen(int.MaxValue); - _socket.SetSocketBufferToOsLimit(); - Log.Info($"SceneConfigId = {Scene.SceneConfigId} networkTarget = {networkTarget.ToString()} TCPServer Listen {address}"); - _acceptAsync.Completed += OnCompleted; - AcceptAsync(); - } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - try - { - foreach (var networkChannel in _connectionChannel.Values.ToArray()) - { - networkChannel.Dispose(); - } - - _connectionChannel.Clear(); - _random = null; - _socket.Dispose(); - _socket = null; - _acceptAsync.Dispose(); - _acceptAsync = null; - GC.SuppressFinalize(this); - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - private void AcceptAsync() - { - _acceptAsync.AcceptSocket = null; - - if (_socket.AcceptAsync(_acceptAsync)) - { - return; - } - - OnAcceptComplete(_acceptAsync); - } - - private void OnAcceptComplete(SocketAsyncEventArgs asyncEventArgs) - { - if (asyncEventArgs.AcceptSocket == null) - { - return; - } - - if (asyncEventArgs.SocketError != SocketError.Success) - { - Log.Error($"Socket Accept Error: {_acceptAsync.SocketError}"); - return; - } - - try - { - uint channelId; - do - { - channelId = 0xC0000000 | (uint)_random.Next(); - } while (_connectionChannel.ContainsKey(channelId)); - - _connectionChannel.Add(channelId, new TCPServerNetworkChannel(this, asyncEventArgs.AcceptSocket, channelId)); - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - AcceptAsync(); - } - } - - public override void RemoveChannel(uint channelId) - { - if (IsDisposed || !_connectionChannel.Remove(channelId, out var channel)) - { - return; - } - - if (channel.IsDisposed) - { - return; - } - - channel.Dispose(); - } - - #region 网络线程(由Socket底层产生的线程) - - private void OnCompleted(object sender, SocketAsyncEventArgs asyncEventArgs) - { - switch (asyncEventArgs.LastOperation) - { - case SocketAsyncOperation.Accept: - { - Scene.ThreadSynchronizationContext.Post(() => - { - OnAcceptComplete(asyncEventArgs); - }); - break; - } - default: - { - throw new Exception($"Socket Accept Error: {asyncEventArgs.LastOperation}"); - } - } - } - - #endregion - } -} -#endif - - diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetworkChannel.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetworkChannel.cs deleted file mode 100644 index 15f3f66..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/TCP/Server/TCPServerNetworkChannel.cs +++ /dev/null @@ -1,294 +0,0 @@ -#if FANTASY_NET -using System.Buffers; -using System.IO.Pipelines; -using System.Net.Sockets; -using Fantasy.Async; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. - -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8622 // Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes). - -namespace Fantasy.Network.TCP -{ - public sealed class TCPServerNetworkChannel : ANetworkServerChannel - { - private bool _isSending; - private bool _isInnerDispose; - private readonly Socket _socket; - private readonly ANetwork _network; - private readonly Pipe _pipe = new Pipe(); - private readonly SocketAsyncEventArgs _sendArgs; - private readonly ReadOnlyMemoryPacketParser _packetParser; - private readonly Queue _sendBuffers = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - public TCPServerNetworkChannel(ANetwork network, Socket socket, uint id) : base(network, id, socket.RemoteEndPoint) - { - _socket = socket; - _network = network; - _socket.NoDelay = true; - _sendArgs = new SocketAsyncEventArgs(); - _sendArgs.Completed += OnSendCompletedHandler; - _packetParser = PacketParserFactory.CreateServerReadOnlyMemoryPacket(network); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - _isInnerDispose = true; - _network.RemoveChannel(Id); - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - if (_socket != null) - { - _socket.Shutdown(SocketShutdown.Both); - _socket.Close(); - } - - _sendBuffers.Clear(); - _packetParser.Dispose(); - _isSending = false; - base.Dispose(); - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); - var count = await _socket.ReceiveAsync(memory, SocketFlags.None, _cancellationTokenSource.Token); - - if (count == 0) - { - Dispose(); - return; - } - - _pipe.Writer.Advance(count); - await _pipe.Writer.FlushAsync(); - } - catch (SocketException) - { - Dispose(); - break; - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (Exception ex) - { - Log.Error($"Unexpected exception: {ex.Message}"); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var message)) - { - ReceiveData(ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private bool TryReadMessage(ref ReadOnlySequence buffer, out ReadOnlyMemory message) - { - if (buffer.Length == 0) - { - message = default; - return false; - } - - message = buffer.First; - - if (message.Length == 0) - { - message = default; - return false; - } - - buffer = buffer.Slice(message.Length); - return true; - } - - private void ReceiveData(ref ReadOnlyMemory buffer) - { - try - { - while (_packetParser.UnPack(ref buffer, out var packInfo)) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - Session.Receive(packInfo); - } - } - catch (ScanException e) - { - Log.Warning($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - catch (Exception e) - { - Log.Error($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - _sendBuffers.Enqueue(_packetParser.Pack(ref rpcId, ref routeId, memoryStream, message)); - - if (!_isSending) - { - Send(); - } - } - - private void Send() - { - if (_isSending || IsDisposed) - { - return; - } - - _isSending = true; - - while (_sendBuffers.Count > 0) - { - var memoryStreamBuffer = _sendBuffers.Dequeue(); - _sendArgs.UserToken = memoryStreamBuffer; - _sendArgs.SetBuffer(new ArraySegment(memoryStreamBuffer.GetBuffer(), 0, (int)memoryStreamBuffer.Position)); - - try - { - if (_socket.SendAsync(_sendArgs)) - { - break; - } - - ReturnMemoryStream(memoryStreamBuffer); - } - catch - { - _isSending = false; - return; - } - } - - _isSending = false; - } - - private void ReturnMemoryStream(MemoryStreamBuffer memoryStream) - { - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - _network.MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - - private void OnSendCompletedHandler(object sender, SocketAsyncEventArgs asyncEventArgs) - { - if (asyncEventArgs.SocketError != SocketError.Success || asyncEventArgs.BytesTransferred == 0) - { - _isSending = false; - return; - } - - var memoryStreamBuffer = (MemoryStreamBuffer)asyncEventArgs.UserToken; - - Scene.ThreadSynchronizationContext.Post(() => - { - ReturnMemoryStream(memoryStreamBuffer); - - if (_sendBuffers.Count > 0) - { - Send(); - } - else - { - _isSending = false; - } - }); - } - - #endregion - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetwork.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetwork.cs deleted file mode 100644 index 45e69e8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetwork.cs +++ /dev/null @@ -1,345 +0,0 @@ -#if FANTASY_NET || FANTASY_CONSOLE -using System.Buffers; -using System.IO.Pipelines; -using System.Net.WebSockets; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -namespace Fantasy.Network.WebSocket -{ - public sealed class WebSocketClientNetwork : AClientNetwork - { - private bool _isSending; - private bool _isInnerDispose; - private long _connectTimeoutId; - private ClientWebSocket _clientWebSocket; - private ReadOnlyMemoryPacketParser _packetParser; - private readonly Pipe _pipe = new Pipe(); - private readonly Queue _sendBuffers = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - private Action _onConnectFail; - private Action _onConnectComplete; - private Action _onConnectDisconnect; - - public void Initialize(NetworkTarget networkTarget) - { - base.Initialize(NetworkType.Client, NetworkProtocolType.WebSocket, networkTarget); - _packetParser = PacketParserFactory.CreateClientReadOnlyMemoryPacket(this); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isInnerDispose = true; - - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - - ClearConnectTimeout(); - WebSocketClientDisposeAsync().Coroutine(); - _onConnectDisconnect?.Invoke(); - _packetParser.Dispose(); - _packetParser = null; - _isSending = false; - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - private async FTask WebSocketClientDisposeAsync() - { - if (_clientWebSocket == null) - { - return; - } - - await _clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); - _clientWebSocket.Dispose(); - _clientWebSocket = null; - } - - public override Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - if (IsInit) - { - throw new NotSupportedException( - $"WebSocketClientNetwork Id:{Id} Has already been initialized. If you want to call Connect again, please re instantiate it."); - } - - IsInit = true; - _onConnectFail = onConnectFail; - _onConnectComplete = onConnectComplete; - _onConnectDisconnect = onConnectDisconnect; - // 设置连接超时定时器 - _connectTimeoutId = Scene.TimerComponent.Net.OnceTimer(connectTimeout, () => - { - _onConnectFail?.Invoke(); - Dispose(); - }); - - _clientWebSocket = new ClientWebSocket(); - var webSocketAddress = WebSocketHelper.GetWebSocketAddress(remoteAddress, isHttps); - - try - { - _clientWebSocket.ConnectAsync(new Uri(webSocketAddress), _cancellationTokenSource.Token).Wait(); - - if (_cancellationTokenSource.IsCancellationRequested) - { - return null; - } - } - catch (WebSocketException wse) - { - Log.Error($"WebSocket error: {wse.Message}"); - Dispose(); - return null; - } - catch (Exception e) - { - Log.Error($"An error occurred: {e.Message}"); - Dispose(); - return null; - } - - ClearConnectTimeout(); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - _onConnectComplete?.Invoke(); - Session = Session.Create(this, null); - return Session; - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); - // 这里接收的数据不一定是一个完整的包。如果大于8192就会分成多个包。 - var receiveResult = await _clientWebSocket.ReceiveAsync(memory, _cancellationTokenSource.Token); - - if (receiveResult.MessageType == WebSocketMessageType.Close) - { - break; - } - - var count = receiveResult.Count; - - if (count > 0) - { - await PipeWriterFlushAsync(count); - } - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - // 这个先暂时注释掉,因为有些时候会出现WebSocketException - // 因为会出现这个挥手的错误,下个版本处理一下。 - // The remote party closed the WebSocket connection without completing the close handshake. - // catch (WebSocketException wse) - // { - // Log.Error($"WebSocket error: {wse.Message}"); - // Dispose(); - // break; - // } - catch (Exception e) - { - Log.Error(e); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - private async FTask PipeWriterFlushAsync(int count) - { - _pipe.Writer.Advance(count); - await _pipe.Writer.FlushAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var message)) - { - ReceiveData(ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private bool TryReadMessage(ref ReadOnlySequence buffer, out ReadOnlyMemory message) - { - if (buffer.Length == 0) - { - message = default; - return false; - } - - message = buffer.First; - - if (message.Length == 0) - { - message = default; - return false; - } - - buffer = buffer.Slice(message.Length); - return true; - } - - private void ReceiveData(ref ReadOnlyMemory buffer) - { - try - { - while (_packetParser.UnPack(ref buffer, out var packInfo)) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - Session.Receive(packInfo); - } - } - catch (ScanException e) - { - Log.Warning(e.Message); - Dispose(); - } - catch (Exception e) - { - Log.Error(e); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - _sendBuffers.Enqueue(_packetParser.Pack(ref rpcId, ref routeId, memoryStream, message)); - - if (!_isSending) - { - Send().Coroutine(); - } - } - - private async FTask Send() - { - if (_isSending || IsDisposed) - { - return; - } - - _isSending = true; - - while (_isSending) - { - if (!_sendBuffers.TryDequeue(out var memoryStream)) - { - _isSending = false; - return; - } - - await _clientWebSocket.SendAsync(new ArraySegment(memoryStream.GetBuffer(), 0, (int)memoryStream.Position), WebSocketMessageType.Binary, true, _cancellationTokenSource.Token); - - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - } - - #endregion - - public override void RemoveChannel(uint channelId) - { - Dispose(); - } - - private void ClearConnectTimeout() - { - if (_connectTimeoutId == 0) - { - return; - } - - Scene?.TimerComponent?.Net?.Remove(ref _connectTimeoutId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetworkWebgl.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetworkWebgl.cs deleted file mode 100644 index 36ef84d..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Client/WebSocketClientNetworkWebgl.cs +++ /dev/null @@ -1,190 +0,0 @@ -#if !FANTASY_NET && !FANTASY_CONSOLE -using System; -using System.Collections.Generic; -using System.IO; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -using UnityWebSocket; - -namespace Fantasy.Network.WebSocket -{ - // 因为webgl的限制、注定这个要是在游戏主线程里。所以这个库不会再其他线程执行的。 - // WebGL:在WebGL环境下运行 - // 另外不是运行在WebGL环境下,也没必要使用WebSocket协议了。完全可以使用TCP或KCP运行。同样也不会有那个队列产生的GC。 - public class WebSocketClientNetwork : AClientNetwork - { - private UnityWebSocket.WebSocket _webSocket; - private bool _isInnerDispose; - private bool _isConnected; - private long _connectTimeoutId; - private BufferPacketParser _packetParser; - private readonly Queue _messageCache = new Queue(); - - private Action _onConnectFail; - private Action _onConnectComplete; - private Action _onConnectDisconnect; - - public void Initialize(NetworkTarget networkTarget) - { - base.Initialize(NetworkType.Client, NetworkProtocolType.WebSocket, networkTarget); - _packetParser = PacketParserFactory.CreateClient(this); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - try - { - _isInnerDispose = true; - ClearConnectTimeout(); - - if (_webSocket != null && _webSocket.ReadyState != WebSocketState.Closed) - { - _onConnectDisconnect?.Invoke(); - _webSocket.CloseAsync(); - } - - _packetParser.Dispose(); - _messageCache.Clear(); - } - catch (Exception e) - { - Log.Error(e); - } - finally - { - base.Dispose(); - } - } - - public override Session Connect(string remoteAddress, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - // 如果已经初始化过一次,抛出异常,要求重新实例化 - - if (IsInit) - { - throw new NotSupportedException($"WebSocketClientNetwork Id:{Id} Has already been initialized. If you want to call Connect again, please re instantiate it."); - } - - IsInit = true; - _onConnectFail = onConnectFail; - _onConnectComplete = onConnectComplete; - _onConnectDisconnect = onConnectDisconnect; - _connectTimeoutId = Scene.TimerComponent.Net.OnceTimer(connectTimeout, () => - { - _onConnectFail?.Invoke(); - Dispose(); - }); - var webSocketAddress = WebSocketHelper.GetWebSocketAddress(remoteAddress, isHttps); - _webSocket = new UnityWebSocket.WebSocket(webSocketAddress); - _webSocket.OnOpen += OnNetworkConnectComplete; - _webSocket.OnMessage += OnReceiveComplete; - _webSocket.OnClose += (sender, args) => - { - _onConnectDisconnect?.Invoke(); - Dispose(); - }; - _webSocket.ConnectAsync(); - Session = Session.Create(this, null); - return Session; - } - - private void OnNetworkConnectComplete(object sender, OpenEventArgs e) - { - if (IsDisposed) - { - return; - } - - _isConnected = true; - ClearConnectTimeout(); - _onConnectComplete?.Invoke(); - - while (_messageCache.TryDequeue(out var memoryStream)) - { - Send(memoryStream); - } - } - - #region Receive - - private void OnReceiveComplete(object sender, MessageEventArgs e) - { - try - { - // WebSocket 协议已经在协议层面处理了消息的边界问题,因此不需要额外的粘包处理逻辑。 - // 所以如果解包的时候出现任何错误只能是恶意攻击造成的。 - var rawDataLength = e.RawData.Length; - _packetParser.UnPack(e.RawData, ref rawDataLength, out var packInfo); - Session.Receive(packInfo); - } - catch (ScanException ex) - { - Log.Warning($"{ex}"); - Dispose(); - } - catch (Exception ex) - { - Log.Error($"{ex}"); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - if (IsDisposed) - { - return; - } - - var buffer = _packetParser.Pack(ref rpcId, ref routeId, memoryStream, message); - - if (!_isConnected) - { - _messageCache.Enqueue(buffer); - return; - } - - Send(buffer); - } - - private void Send(MemoryStreamBuffer memoryStream) - { - _webSocket.SendAsync(memoryStream.GetBuffer(), 0, (int)memoryStream.Position); -#if !UNITY_EDITOR && UNITY_WEBGL - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } -#endif - } - - #endregion - - public override void RemoveChannel(uint channelId) - { - Dispose(); - } - - private void ClearConnectTimeout() - { - if (_connectTimeoutId == 0) - { - return; - } - - Scene?.TimerComponent?.Net?.Remove(ref _connectTimeoutId); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetwork.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetwork.cs deleted file mode 100644 index 09feb2b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetwork.cs +++ /dev/null @@ -1,112 +0,0 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#if FANTASY_NET -using System.Net; -using System.Security.Cryptography.X509Certificates; -using Fantasy.Async; -using Fantasy.Network.Interface; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable PossibleMultipleEnumeration -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Network.WebSocket; - -public class WebSocketServerNetwork : ANetwork -{ - private Random _random; - private HttpListener _httpListener; - private readonly Dictionary _connectionChannel = new Dictionary(); - - public void Initialize(NetworkTarget networkTarget, string bindIp, int port) - { - base.Initialize(NetworkType.Server, NetworkProtocolType.WebSocket, networkTarget); - - try - { - _random = new Random(); - _httpListener = new HttpListener(); - StartAcceptAsync(bindIp, port).Coroutine(); - } - catch (HttpListenerException e) - { - if (e.ErrorCode == 5) - { - throw new Exception($"CMD管理员中输入: netsh http add urlacl url=http://*:8080/ user=Everyone", e); - } - - Log.Error(e); - } - catch (Exception e) - { - Log.Error(e); - } - } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - if (_httpListener != null) - { - _httpListener.Close(); - _httpListener = null; - } - - foreach (var channel in _connectionChannel.Values.ToArray()) - { - channel.Dispose(); - } - - _connectionChannel.Clear(); - base.Dispose(); - } - - private async FTask StartAcceptAsync(string bindIp, int port) - { - var listenUrl = ""; - var certificatePath = Path.Combine(AppContext.BaseDirectory, $"certificate{bindIp}{port}"); - listenUrl = Directory.Exists(certificatePath) ? $"https://{bindIp}:{port}/" : $"http://{bindIp}:{port}/"; - _httpListener.Prefixes.Add(listenUrl); - _httpListener.Start(); - Log.Info($"SceneConfigId = {Scene.SceneConfigId} WebSocketServer Listen {listenUrl}"); - while (!IsDisposed) - { - try - { - var httpListenerContext = await _httpListener.GetContextAsync(); - var webSocketContext = await httpListenerContext.AcceptWebSocketAsync(null); - var channelId = 0xC0000000 | (uint) _random.Next(); - - while (_connectionChannel.ContainsKey(channelId)) - { - channelId = 0xC0000000 | (uint) _random.Next(); - } - - _connectionChannel.Add(channelId, new WebSocketServerNetworkChannel(this, channelId, webSocketContext, httpListenerContext.Request.RemoteEndPoint)); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void RemoveChannel(uint channelId) - { - if (IsDisposed || !_connectionChannel.Remove(channelId, out var channel)) - { - return; - } - - if (channel.IsDisposed) - { - return; - } - - channel.Dispose(); - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetworkChannel.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetworkChannel.cs deleted file mode 100644 index 3b8ee90..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Protocol/WebSocket/Server/WebSocketServerNetworkChannel.cs +++ /dev/null @@ -1,253 +0,0 @@ -#if FANTASY_NET -using System.Buffers; -using System.IO.Pipelines; -using System.Net; -using System.Net.Sockets; -using System.Net.WebSockets; -using Fantasy.Async; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.Serialize; -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Network.WebSocket; - -public sealed class WebSocketServerNetworkChannel : ANetworkServerChannel -{ - private bool _isSending; - private bool _isInnerDispose; - private readonly Pipe _pipe = new Pipe(); - private readonly System.Net.WebSockets.WebSocket _webSocket; - private readonly WebSocketServerNetwork _network; - private readonly ReadOnlyMemoryPacketParser _packetParser; - private readonly Queue _sendBuffers = new Queue(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - public WebSocketServerNetworkChannel(ANetwork network, uint id, HttpListenerWebSocketContext httpListenerWebSocketContext, IPEndPoint remoteEndPoint) : base(network, id, remoteEndPoint) - { - _network = (WebSocketServerNetwork)network; - _webSocket = httpListenerWebSocketContext.WebSocket; - _packetParser = PacketParserFactory.CreateServerReadOnlyMemoryPacket(network); - ReadPipeDataAsync().Coroutine(); - ReceiveSocketAsync().Coroutine(); - } - - public override void Dispose() - { - if (IsDisposed || _isInnerDispose) - { - return; - } - - _isInnerDispose = true; - if (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - _cancellationTokenSource.Cancel(); - } - catch (OperationCanceledException) - { - // 通常情况下,此处的异常可以忽略 - } - } - _sendBuffers.Clear(); - _network.RemoveChannel(Id); - if (_webSocket.State == WebSocketState.Open || _webSocket.State == WebSocketState.CloseReceived) - { - _webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Normal Closure", - _cancellationTokenSource.Token).GetAwaiter().GetResult(); - } - _webSocket.Dispose(); - _isSending = false; - base.Dispose(); - } - - #region ReceiveSocket - - private async FTask ReceiveSocketAsync() - { - while (!_cancellationTokenSource.IsCancellationRequested) - { - try - { - var memory = _pipe.Writer.GetMemory(8192); - // 这里接收的数据不一定是一个完整的包。如果大于8192就会分成多个包。 - var receiveResult = await _webSocket.ReceiveAsync(memory, _cancellationTokenSource.Token); - - if (receiveResult.MessageType == WebSocketMessageType.Close) - { - Dispose(); - break; - } - - var count = receiveResult.Count; - - if (count > 0) - { - await PipeWriterFlushAsync(count); - } - } - catch (OperationCanceledException) - { - break; - } - catch (ObjectDisposedException) - { - Dispose(); - break; - } - catch (WebSocketException) - { - // Log.Error($"WebSocket error: {wse.Message}"); - Dispose(); - break; - } - catch (Exception e) - { - Log.Error(e); - } - } - - await _pipe.Writer.CompleteAsync(); - } - - private async FTask PipeWriterFlushAsync(int count) - { - _pipe.Writer.Advance(count); - await _pipe.Writer.FlushAsync(); - } - - #endregion - - #region ReceivePipeData - - private async FTask ReadPipeDataAsync() - { - var pipeReader = _pipe.Reader; - while (!_cancellationTokenSource.IsCancellationRequested) - { - ReadResult result = default; - - try - { - result = await pipeReader.ReadAsync(_cancellationTokenSource.Token); - } - catch (OperationCanceledException) - { - // 出现这个异常表示取消了_cancellationTokenSource。一般Channel断开会取消。 - break; - } - - var buffer = result.Buffer; - var consumed = buffer.Start; - var examined = buffer.End; - - while (TryReadMessage(ref buffer, out var message)) - { - ReceiveData(ref message); - consumed = buffer.Start; - } - - if (result.IsCompleted) - { - break; - } - - pipeReader.AdvanceTo(consumed, examined); - } - - await pipeReader.CompleteAsync(); - } - - private bool TryReadMessage(ref ReadOnlySequence buffer, out ReadOnlyMemory message) - { - if (buffer.Length == 0) - { - message = default; - return false; - } - - message = buffer.First; - - if (message.Length == 0) - { - message = default; - return false; - } - - buffer = buffer.Slice(message.Length); - return true; - } - - private void ReceiveData(ref ReadOnlyMemory buffer) - { - try - { - while (_packetParser.UnPack(ref buffer, out var packInfo)) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - return; - } - - Session.Receive(packInfo); - } - } - catch (ScanException e) - { - Log.Warning($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - catch (Exception e) - { - Log.Error($"RemoteAddress:{RemoteEndPoint} \n{e}"); - Dispose(); - } - } - - #endregion - - #region Send - - public override void Send(uint rpcId, long routeId, MemoryStreamBuffer memoryStream, IMessage message) - { - _sendBuffers.Enqueue(_packetParser.Pack(ref rpcId, ref routeId, memoryStream, message)); - - if (!_isSending) - { - Send().Coroutine(); - } - } - - private async FTask Send() - { - if (_isSending || IsDisposed) - { - return; - } - - _isSending = true; - - while (_isSending) - { - if (!_sendBuffers.TryDequeue(out var memoryStream)) - { - _isSending = false; - return; - } - - await _webSocket.SendAsync(new ArraySegment(memoryStream.GetBuffer(), 0, (int)memoryStream.Position), WebSocketMessageType.Binary, true, _cancellationTokenSource.Token); - - if (memoryStream.MemoryStreamBufferSource == MemoryStreamBufferSource.Pack) - { - _network.MemoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - } - } - - #endregion -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/RoamingComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/RoamingComponent.cs deleted file mode 100644 index a42d582..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/RoamingComponent.cs +++ /dev/null @@ -1,254 +0,0 @@ -#if FANTASY_NET -using System.Runtime.CompilerServices; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Timer; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Network.Roaming; - -/// -/// 漫游组件,用来管理当然Scene下的所有漫游消息。 -/// 大多数是在Gate这样的转发服务器上创建的。 -/// -public sealed class RoamingComponent : Entity -{ - private TimerSchedulerNet _timerSchedulerNet; - private readonly Dictionary _sessionRoamingComponents = new(); - private readonly Dictionary _delayRemoveTaskId = new(); - - internal RoamingComponent Initialize() - { - _timerSchedulerNet = Scene.TimerComponent.Net; - return this; - } - - /// - /// 销毁方法。 - /// - public override void Dispose() - { - DisposeAsync().Coroutine(); - } - - private async FTask DisposeAsync() - { - foreach (var (_,taskId) in _delayRemoveTaskId) - { - _timerSchedulerNet.Remove(taskId); - } - - _delayRemoveTaskId.Clear(); - - foreach (var (_, sessionRoamingComponent) in _sessionRoamingComponents) - { - await sessionRoamingComponent.UnLink(); - } - - _sessionRoamingComponents.Clear(); - _timerSchedulerNet = null; - base.Dispose(); - } - - /// - /// 给Session会话增加漫游功能 - /// 如果指定的roamingId已经存在漫游,会把这个漫游功能和当前Session会话关联起来。 - /// - /// - /// 自定义roamingId,这个Id在漫游中并没有实际作用,但用户可以用这个id来进行标记。。 - /// 是否在Session断开的时候自动断开漫游功能。 - /// 如果开启了自定断开漫游功能需要设置一个延迟多久执行断开。 - /// 创建成功会返回SessionRoamingComponent组件,这个组件提供漫游的所有功能。 - public SessionRoamingComponent Create(Session session, long roamingId, bool isAutoDispose, int delayRemove) - { - if (session.SessionRoamingComponent != null) - { - if (session.SessionRoamingComponent.Id != roamingId) - { - Log.Error("The current session has created a SessionRoamingComponent."); - return null; - } - } - else - { - if (!_sessionRoamingComponents.TryGetValue(roamingId, out var sessionRoamingComponent)) - { - sessionRoamingComponent = Entity.Create(Scene, roamingId, true, true); - sessionRoamingComponent.Initialize(session); - _sessionRoamingComponents.Add(roamingId, sessionRoamingComponent); - } - } - - if (isAutoDispose) - { - session.AddComponent(roamingId).DelayRemove = delayRemove; - } - - return session.SessionRoamingComponent; - } - - /// - /// 获取当前Session会话的漫游组件 - /// - /// - /// - public SessionRoamingComponent Get(Session session) - { - var sessionRoamingFlgComponent = session.GetComponent(); - - if (sessionRoamingFlgComponent != null) - { - if (_sessionRoamingComponents.TryGetValue(sessionRoamingFlgComponent.Id, out var sessionRoamingComponent)) - { - return sessionRoamingComponent; - } - - Log.Error($"There is no SessionRoamingComponent with roamingId: {sessionRoamingFlgComponent.Id}."); - } - else - { - Log.Error("The current session has not created a roaming session yet, so you need to create one first."); - } - - return null; - } - - /// - /// 获取当前Session会话的漫游组件 - /// - /// - /// - /// - public bool TryGet(Session session, out SessionRoamingComponent sessionRoamingComponent) - { - var sessionRoamingFlgComponent = session.GetComponent(); - - if (sessionRoamingFlgComponent != null) - { - return _sessionRoamingComponents.TryGetValue(sessionRoamingFlgComponent.Id, out sessionRoamingComponent); - } - - sessionRoamingComponent = null; - return false; - } - - /// - /// 移除一个漫游 - /// - /// - /// 要移除的RoamingType,默认不设置是移除所有漫游。 - /// 当设置了延迟移除时间后,会在设置的时间后再进行移除。 - public async FTask Remove(long roamingId, int roamingType, int delayRemove = 0) - { - if (_delayRemoveTaskId.Remove(roamingId, out var taskId)) - { - _timerSchedulerNet.Remove(taskId); - } - - if (delayRemove <= 0) - { - await InnerRemove(roamingId, roamingType); - return; - } - - taskId = _timerSchedulerNet.OnceTimer(delayRemove, () => - { InnerRemove(roamingId, roamingType).Coroutine(); }); - _delayRemoveTaskId.Add(roamingId, taskId); - } - - private async FTask InnerRemove(long roamingId, int roamingType) - { - if (!_sessionRoamingComponents.Remove(roamingId, out var sessionRoamingComponent)) - { - return; - } - - await sessionRoamingComponent.UnLink(roamingType); - sessionRoamingComponent.Dispose(); - _delayRemoveTaskId.Remove(roamingId); - } -} - -/// -/// 漫游Roaming帮助类 -/// -public static class RoamingHelper -{ - /// - /// 给Session会话增加漫游功能 - /// 如果指定的roamingId已经存在漫游,会把这个漫游功能和当前Session会话关联起来。 - /// - /// - /// 自定义roamingId,这个Id在漫游中并没有实际作用,但用户可以用这个id来进行标记。 - /// 是否在Session断开的时候自动断开漫游功能。 - /// 如果开启了自定断开漫游功能需要设置一个延迟多久执行断开。 - /// 创建成功会返回SessionRoamingComponent组件,这个组件提供漫游的所有功能。 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SessionRoamingComponent CreateRoaming(this Session session, long roamingId, bool isAutoDispose = true, int delayRemove = 1000 * 60 * 3) - { - return session.Scene.RoamingComponent.Create(session, roamingId, isAutoDispose, delayRemove); - } - - /// - /// 获取当前Session会话的漫游组件 - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SessionRoamingComponent GetRoaming(this Session session) - { - return session.Scene.RoamingComponent.Get(session); - } - - /// - /// 获取当前Session会话的漫游组件 - /// - /// - /// - /// 如果返回为false表示没有获取到漫游组件。 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryGetRoaming(this Session session, out SessionRoamingComponent sessionRoamingComponent) - { - return session.Scene.RoamingComponent.TryGet(session, out sessionRoamingComponent); - } - - /// - /// 移除一个漫游 - /// - /// - /// 要移除的RoamingType,默认不设置是移除所有漫游。 - /// 当设置了延迟移除时间后,会在设置的时间后再进行移除。 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static async FTask RemoveRoaming(this Session session, int roamingType = 0, int delayRemove = 0) - { - if (session.SessionRoamingComponent == null || session.SessionRoamingComponent.Id == 0) - { - return; - } - - await session.Scene.RoamingComponent.Remove(session.SessionRoamingComponent.Id, roamingType, delayRemove); - } - - /// - /// 移除一个漫游 - /// - /// - /// - /// 要移除的RoamingType,默认不设置是移除所有漫游。 - /// 当设置了延迟移除时间后,会在设置的时间后再进行移除。 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static async FTask RemoveRoaming(Scene scene, long roamingId, int roamingType = 0, int delayRemove = 0) - { - if (roamingId == 0) - { - return; - } - - await scene.RoamingComponent.Remove(roamingId, roamingType, delayRemove); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/SessionRoamingComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/SessionRoamingComponent.cs deleted file mode 100644 index c5ce55a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/SessionRoamingComponent.cs +++ /dev/null @@ -1,279 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Platform.Net; -using Fantasy.Scheduler; -using Fantasy.Timer; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -namespace Fantasy.Network.Roaming; - -internal sealed class SessionRoamingComponentDestroySystem : DestroySystem -{ - protected override void Destroy(SessionRoamingComponent self) - { - self.RoamingLock.Dispose(); - self.RoamingMessageLock.Dispose(); - - self.RoamingLock = null; - self.RoamingMessageLock = null; - self.TimerComponent = null; - self.NetworkMessagingComponent = null; - self.MessageDispatcherComponent = null; - } -} - -/// -/// Session的漫游组件。 -/// 用于关联对应的Session的功能。 -/// 但这个组件并不会挂载到这个Session下。 -/// -public sealed class SessionRoamingComponent : Entity -{ - internal CoroutineLock RoamingLock; - internal CoroutineLock RoamingMessageLock; - internal TimerComponent TimerComponent; - internal NetworkMessagingComponent NetworkMessagingComponent; - internal MessageDispatcherComponent MessageDispatcherComponent; - /// - /// 漫游的列表。 - /// - private readonly Dictionary _roaming = new Dictionary(); - - internal void Initialize(Session session) - { - session.SessionRoamingComponent = this; - - var scene = session.Scene; - TimerComponent = scene.TimerComponent; - NetworkMessagingComponent = scene.NetworkMessagingComponent; - MessageDispatcherComponent = scene.MessageDispatcherComponent; - RoamingLock = scene.CoroutineLockComponent.Create(this.GetType().TypeHandle.Value.ToInt64()); - RoamingMessageLock = scene.CoroutineLockComponent.Create(this.GetType().TypeHandle.Value.ToInt64()); - } - - #region Get - - /// - /// 尝试获取一个漫游。 - /// - /// - /// - /// - public bool TryGetRoaming(int roamingType, out Roaming roaming) - { - return _roaming.TryGetValue(roamingType, out roaming); - } - - #endregion - - #region Link - - /// - /// 建立漫游关系。 - /// - /// 要建立漫游协议的目标Scene的SceneConfig。 - /// 需要转发的Session - /// 要创建的漫游协议类型。 - /// 如果建立完成会返回为0,其余不为0的都是发生错误了。可以通过InnerErrorCode.cs来查看错误。 - public async FTask Link(Session session, SceneConfig targetSceneConfig, int roamingTyp) - { - return await Link(targetSceneConfig.RouteId, session.RuntimeId, roamingTyp); - } - - /// - /// 建立漫游关系。 - /// - /// 要建立漫游协议的目标Scene的RouteId。 - /// 需要转发的Session的RouteId。 - /// 要创建的漫游协议类型。 - /// 如果建立完成会返回为0,其余不为0的都是发生错误了。可以通过InnerErrorCode.cs来查看错误。 - public async FTask Link(long targetSceneRouteId, long forwardSessionRouteId, int roamingType) - { - if (_roaming.ContainsKey(roamingType)) - { - return InnerErrorCode.ErrLinkRoamingAlreadyExists; - } - - var response = (I_LinkRoamingResponse)await Scene.NetworkMessagingComponent.CallInnerRoute(targetSceneRouteId, - new I_LinkRoamingRequest() - { - RoamingId = Id, - RoamingType = roamingType, - ForwardSessionRouteId = forwardSessionRouteId, - SceneRouteId = Scene.RuntimeId - }); - - if (response.ErrorCode != 0) - { - return response.ErrorCode; - } - - var roaming = Entity.Create(Scene, true, true); - roaming.TerminusId = response.TerminusId; - roaming.TargetSceneRouteId = targetSceneRouteId; - roaming.ForwardSessionRouteId = forwardSessionRouteId; - roaming.SessionRoamingComponent = this; - roaming.RoamingType = roamingType; - roaming.RoamingLock = RoamingLock; - _roaming.Add(roamingType, roaming); - return 0; - } - - #endregion - - #region UnLink - - /// - /// 断开当前的所有漫游关系。 - /// 要移除的RoamingType,默认不设置是移除所有漫游。 - /// - public async FTask UnLink(int removeRoamingType = 0) - { - switch (removeRoamingType) - { - case 0: - { - foreach (var (roamingType,roaming) in _roaming) - { - try - { - var errorCode = await roaming.Disconnect(); - - if (errorCode != 0) - { - Log.Warning($"roaming roamingId:{Id} roamingType:{roamingType} disconnect errorCode:{errorCode}"); - } - } - finally - { - roaming.Dispose(); - } - } - - _roaming.Clear(); - return; - } - default: - { - if (!_roaming.Remove(removeRoamingType, out var roaming)) - { - return; - } - - var errorCode = await roaming.Disconnect(); - - if (errorCode != 0) - { - Log.Warning($"roaming roamingId:{Id} roamingType:{removeRoamingType} disconnect errorCode:{errorCode}"); - } - - roaming.Dispose(); - return; - } - } - } - - #endregion - - #region Message - - internal async FTask Send(int roamingType, Type requestType, APackInfo packInfo) - { - await Call(roamingType, requestType, packInfo); - } - - internal async FTask Call(int roamingType, Type requestType, APackInfo packInfo) - { - if (IsDisposed) - { - return MessageDispatcherComponent.CreateResponse(requestType, InnerErrorCode.ErrNotFoundRoaming); - } - - packInfo.IsDisposed = true; - - if (!_roaming.TryGetValue(roamingType, out var roaming)) - { - return MessageDispatcherComponent.CreateResponse(requestType, InnerErrorCode.ErrNotFoundRoaming); - } - - var failCount = 0; - var runtimeId = RuntimeId; - var routeId = roaming.TerminusId; - IResponse iRouteResponse = null; - - try - { - using (await RoamingMessageLock.Wait(roamingType, "RoamingComponent Call MemoryStream")) - { - while (!IsDisposed) - { - if (routeId == 0) - { - routeId = await roaming.GetTerminusId(); - } - - if (routeId == 0) - { - return MessageDispatcherComponent.CreateResponse(requestType, InnerErrorCode.ErrNotFoundRoaming); - } - - iRouteResponse = await NetworkMessagingComponent.CallInnerRoute(routeId, requestType, packInfo); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRoamingTimeout; - } - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrRouteTimeout: - case InnerErrorCode.ErrRoamingTimeout: - { - return iRouteResponse; - } - case InnerErrorCode.ErrNotFoundRoute: - case InnerErrorCode.ErrNotFoundRoaming: - { - if (++failCount > 20) - { - Log.Error($"RoamingComponent.Call failCount > 20 route send message fail, LinkRoamingId: {routeId}"); - return iRouteResponse; - } - - await TimerComponent.Net.WaitAsync(100); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrNotFoundRoaming; - } - routeId = 0; - continue; - } - default: - { - return iRouteResponse; // 对于其他情况,直接返回响应,无需额外处理 - } - } - } - } - } - finally - { - packInfo.Dispose(); - } - - return iRouteResponse; - } - - #endregion -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/SessionRoamingFlgComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/SessionRoamingFlgComponent.cs deleted file mode 100644 index 23f4c33..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/SessionRoamingFlgComponent.cs +++ /dev/null @@ -1,23 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.Entitas; -namespace Fantasy.Network.Roaming; - -internal sealed class SessionRoamingFlgComponent : Entity -{ - public int DelayRemove; - - public override void Dispose() - { - DisposeAsync().Coroutine(); - } - - private async FTask DisposeAsync() - { - var roamingId = Id; - await Scene.RoamingComponent.Remove(roamingId, 0, DelayRemove); - DelayRemove = 0; - base.Dispose(); - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/TerminusComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/TerminusComponent.cs deleted file mode 100644 index 0185261..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Component/TerminusComponent.cs +++ /dev/null @@ -1,138 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.DataStructure.Dictionary; -using Fantasy.Entitas; -using Fantasy.Network; -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - -namespace Fantasy.Network.Roaming; - -/// -/// 当Terminus创建完成后发送的事件参数 -/// -public struct OnCreateTerminus -{ - /// - /// 获取与事件关联的场景实体。 - /// - public readonly Scene Scene; - /// - /// 获取与事件关联的Terminus。 - /// - public readonly Terminus Terminus; - /// - /// 初始化一个新的 OnCreateTerminus 实例。 - /// - /// - /// - public OnCreateTerminus(Scene scene, Terminus terminus) - { - Scene = scene; - Terminus = terminus; - } -} - -/// -/// 漫游终端管理组件。 -/// 这个组件不需要手动挂载,会在Scene启动的时候自动挂载这个组件。 -/// -public sealed class TerminusComponent : Entity -{ - /// - /// 漫游终端的实体集合。 - /// - private readonly Dictionary _terminals = new(); - - /// - /// Dispose - /// - public override void Dispose() - { - foreach (var (_, terminus) in _terminals) - { - terminus.Dispose(); - } - - _terminals.Clear(); - base.Dispose(); - } - - /// - /// 创建一个新的漫游终端。 - /// - /// - /// - /// - /// - /// - public async FTask<(uint, Terminus)> Create(long roamingId, int roamingType, long forwardSessionRouteId, long forwardSceneRouteId) - { - if (_terminals.ContainsKey(roamingId)) - { - return (InnerErrorCode.ErrAddRoamingTerminalAlreadyExists, null); - } - - var terminus = roamingId == 0 - ? Entity.Create(Scene, false, true) - : Entity.Create(Scene, roamingId, false, true); - terminus.RoamingType = roamingType; - terminus.TerminusId = terminus.RuntimeId; - terminus.ForwardSceneRouteId = forwardSceneRouteId; - terminus.ForwardSessionRouteId = forwardSessionRouteId; - terminus.RoamingMessageLock = Scene.CoroutineLockComponent.Create(terminus.Type.TypeHandle.Value.ToInt64()); - await Scene.EventComponent.PublishAsync(new OnCreateTerminus(Scene, terminus)); - _terminals.Add(terminus.Id, terminus); - return (0U, terminus); - } - - /// - /// 添加一个漫游终端。 - /// - /// - public void AddTerminus(Terminus terminus) - { - _terminals.Add(terminus.Id, terminus); - } - - /// - /// 根据roamingId获取一个漫游终端。 - /// - /// - /// - /// - public bool TryGetTerminus(long roamingId, out Terminus terminus) - { - return _terminals.TryGetValue(roamingId, out terminus); - } - - /// - /// 根据roamingId获取一个漫游终端。 - /// - /// - /// - public Terminus GetTerminus(long roamingId) - { - return _terminals[roamingId]; - } - - /// - /// 根据roamingId移除一个漫游终端。 - /// - /// - /// - public void RemoveTerminus(long roamingId, bool isDispose = true) - { - if (!_terminals.Remove(roamingId, out var terminus)) - { - return; - } - - if (isDispose) - { - terminus.Dispose(); - } - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Entity/Roaming.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Entity/Roaming.cs deleted file mode 100644 index 33a5355..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Entity/Roaming.cs +++ /dev/null @@ -1,132 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.InnerMessage; - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -namespace Fantasy.Network.Roaming; - -/// -/// 漫游实体 -/// -public sealed class Roaming : Entity -{ - /// - /// 连接到漫游TerminusId。 - /// 也可以理解为目标实体的RouteId。 - /// - internal long TerminusId; - /// - /// 漫游目标Scene的RouteId。 - /// - public long TargetSceneRouteId { get; internal set; } - /// - /// 漫游转发Session的RouteId。 - /// - public long ForwardSessionRouteId { get; internal set; } - /// - /// 当前漫游类型。 - /// - public int RoamingType { get; internal set; } - /// - /// 协程锁。 - /// - internal CoroutineLock RoamingLock; - /// - /// 当前正在执行的协程锁。 - /// - private WaitCoroutineLock? _waitCoroutineLock; - /// - /// 关联Session的漫游组件。 - /// - internal SessionRoamingComponent SessionRoamingComponent; - /// - /// 获得当前漫游对应终端的TerminusId。 - /// - /// - internal async FTask GetTerminusId() - { - using (await RoamingLock.Wait(RoamingType,"Roaming.cs GetTerminusId")) - { - return TerminusId; - } - } - /// - /// 设置当前漫游对应的终端的TerminusId。 - /// - /// - internal async FTask SetTerminusId(long terminusId) - { - using (await RoamingLock.Wait(RoamingType,"Roaming.cs SetTerminusId")) - { - TerminusId = terminusId; - } - } - /// - /// 锁定TerminusId。 - /// - internal async FTask LockTerminusId() - { - _waitCoroutineLock = await RoamingLock.Wait(RoamingType,"Roaming.cs LockTerminusId"); - } - - /// - /// 解锁TerminusId。 - /// - /// - /// - internal void UnLockTerminusId(long terminusId, long targetSceneRouteId) - { - if (_waitCoroutineLock == null) - { - Log.Error("terminusId unlock waitCoroutineLock is null"); - return; - } - - TerminusId = terminusId; - TargetSceneRouteId = targetSceneRouteId; - _waitCoroutineLock.Dispose(); - _waitCoroutineLock = null; - } - - /// - /// 断开当前漫游的连接。 - /// - /// - public async FTask Disconnect() - { - var response = - await Scene.NetworkMessagingComponent.CallInnerRoute(TargetSceneRouteId, new I_UnLinkRoamingRequest() - { - RoamingId = SessionRoamingComponent.Id - }); - return response.ErrorCode; - } - /// - /// 销毁方法 - /// - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - if (_waitCoroutineLock != null) - { - _waitCoroutineLock.Dispose(); - _waitCoroutineLock = null; - } - - TerminusId = 0; - TargetSceneRouteId = 0; - ForwardSessionRouteId = 0; - - RoamingLock = null; - SessionRoamingComponent = null; - base.Dispose(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Entity/Terminus.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Entity/Terminus.cs deleted file mode 100644 index 8d4448b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Entity/Terminus.cs +++ /dev/null @@ -1,338 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Scheduler; -using MongoDB.Bson.Serialization.Attributes; -// ReSharper disable UnassignedField.Global -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. -#pragma warning disable CS8603 // Possible null reference return. -namespace Fantasy.Network.Roaming; - -/// -/// 漫游终端实体 -/// -public sealed class Terminus : Entity -{ - /// - /// 当前漫游终端的TerminusId。 - /// 可以通过 TerminusId 发送消息给这个漫游终端。 - /// 也可以理解为实体的RuntimeId。 - /// - internal long TerminusId; - /// - /// 当前漫游终端的类型。 - /// - [BsonElement("r")] - internal int RoamingType; - /// - /// 漫游转发Session所在的Scene的RouteId。 - /// - [BsonElement("s")] - internal long ForwardSceneRouteId; - /// - /// 漫游转发Session的RouteId。 - /// 不知道原理千万不要手动赋值这个。 - /// - [BsonElement("f")] - internal long ForwardSessionRouteId; - /// - /// 关联的玩家实体 - /// - [BsonElement("e")] - public Entity TerminusEntity; - /// - /// 漫游消息锁。 - /// - [BsonIgnore] - internal CoroutineLock RoamingMessageLock; - /// - /// 获得转发的SessionRouteId,可以通过这个Id来发送消息来自动转发到客户端。 - /// - public long SessionRouteId => ForwardSessionRouteId; - /// - /// 存放其他漫游终端的Id。 - /// 通过这个Id可以发送消息给它。 - /// - [BsonIgnore] - private readonly Dictionary _roamingTerminusId = new Dictionary(); - /// - /// 创建关联的终端实体。 - /// 创建完成后,接收消息都是由关联的终端实体来处理。 - /// 注意,当你销毁这个实体的时候,并不能直接销毁Terminus,会导致无法接收到漫游消息。 - /// - /// - /// - public T LinkTerminusEntity() where T : Entity, new() - { - if (TerminusEntity != null) - { - Log.Error($"TerminusEntity:{TerminusEntity.Type.FullName} Already exists!"); - return null; - } - - var t = Entity.Create(Scene, true, true); - TerminusEntity = t; - TerminusId = TerminusEntity.RuntimeId; - return t; - } - - /// - /// 关联的终端实体。 - /// 注意,当你销毁这个实体的时候,并不能直接销毁Terminus,会导致无法接收到漫游消息 - /// - /// - public void LinkTerminusEntity(Entity entity) - { - if (entity == null) - { - Log.Error("Entity cannot be empty"); - return; - } - - if (TerminusEntity != null) - { - Log.Error($"TerminusEntity:{TerminusEntity.Type.FullName} Already exists!"); - return; - } - - TerminusEntity = entity; - TerminusId = TerminusEntity.RuntimeId; - } - - #region Transfer - - /// - /// 传送漫游终端 - /// 传送完成后,漫游终端和关联的玩家实体都会被销毁。 - /// 所以如果有其他组件关联这个实体,要提前记录好Id,方便传送后清理。 - /// - /// - public async FTask StartTransfer(long targetSceneRouteId) - { - var currentSceneRouteId = Scene.SceneConfig.RouteId; - if (targetSceneRouteId == currentSceneRouteId) - { - Log.Warning($"Unable to teleport to your own scene targetSceneRouteId:{targetSceneRouteId} == currentSceneRouteId:{currentSceneRouteId}"); - return 0; - } - - try - { - // 传送目标服务器之前要先锁定,防止再传送过程中还有其他消息发送过来。 - var lockErrorCode = await Lock(); - if (lockErrorCode != 0) - { - return lockErrorCode; - } - // 开始执行传送请求。 - var response = (I_TransferTerminusResponse)await Scene.NetworkMessagingComponent.CallInnerRoute( - targetSceneRouteId, - new I_TransferTerminusRequest() - { - Terminus = this - }); - if (response.ErrorCode != 0) - { - // 如果传送出现异常,需要先解锁,不然会出现一直卡死的问题。 - await UnLock(); - return response.ErrorCode; - } - // 在当前Scene下移除漫游终端。 - Scene.TerminusComponent.RemoveTerminus(Id); - } - catch (Exception e) - { - Log.Error(e); - // 如果代码执行出现任何异常,要先去解锁,避免会出现卡死的问题。 - await UnLock(); - return InnerErrorCode.ErrTerminusStartTransfer; - } - - return 0; - } - - /// - /// 传送完成。 - /// 当传送完成后,需要清理漫游终端。 - /// - /// - public async FTask TransferComplete(Scene scene) - { - // 首先恢复漫游终端的序列化数据。并且注册到框架中。 - Deserialize(scene); - TerminusId = RuntimeId; - if (TerminusEntity != null) - { - TerminusEntity.Deserialize(scene); - TerminusId = TerminusEntity.RuntimeId; - } - // 然后要解锁下漫游 - return await UnLock(); - } - - /// - /// 锁定漫游当执行锁定了后,所有消息都会被暂时放入队列中不会发送。 - /// 必须要解锁后才能继续发送消息。 - /// - /// - public async FTask Lock() - { - var response = await Scene.NetworkMessagingComponent.CallInnerRoute(ForwardSceneRouteId, - new I_LockTerminusIdRequest() - { - SessionRuntimeId = ForwardSessionRouteId, - RoamingType = RoamingType - }); - return response.ErrorCode; - } - - /// - /// 锁定漫游 - /// - /// - public async FTask UnLock() - { - var response = await Scene.NetworkMessagingComponent.CallInnerRoute(ForwardSceneRouteId, - new I_UnLockTerminusIdRequest() - { - SessionRuntimeId = ForwardSessionRouteId, - RoamingType = RoamingType, - TerminusId = TerminusId, - TargetSceneRouteId = Scene.RouteId - }); - return response.ErrorCode; - } - - #endregion - - #region Message - - private async FTask GetTerminusId(int roamingType) - { - if (IsDisposed) - { - return 0; - } - - var response = (I_GetTerminusIdResponse)await Scene.NetworkMessagingComponent.CallInnerRoute( - ForwardSceneRouteId, - new I_GetTerminusIdRequest() - { - SessionRuntimeId = ForwardSessionRouteId, - RoamingType = roamingType - }); - return response.TerminusId; - } - - /// - /// 发送一个消息给客户端 - /// - /// - public void Send(IRouteMessage message) - { - Scene.NetworkMessagingComponent.SendInnerRoute(ForwardSessionRouteId, message); - } - /// - /// 发送一个漫游消息 - /// - /// - /// - public void Send(int roamingType, IRoamingMessage message) - { - Call(roamingType, message).Coroutine(); - } - - /// - /// 发送一个漫游RPC消息。 - /// - /// - /// - /// - public async FTask Call(int roamingType, IRoamingMessage request) - { - if (IsDisposed) - { - return Scene.MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoaming); - } - - if (roamingType == RoamingType) - { - Log.Warning($"Does not support sending messages to the same scene as roamingType currentRoamingType:{RoamingType} roamingType:{roamingType}"); - return Scene.MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoaming); - } - - var failCount = 0; - var runtimeId = RuntimeId; - IResponse iRouteResponse = null; - _roamingTerminusId.TryGetValue(roamingType, out var routeId); - - using (await RoamingMessageLock.Wait(roamingType, "Terminus Call request")) - { - while (!IsDisposed) - { - if (routeId == 0) - { - routeId = await GetTerminusId(roamingType); - - if (routeId != 0) - { - _roamingTerminusId[roamingType] = routeId; - } - else - { - return Scene.MessageDispatcherComponent.CreateResponse(request.GetType(), InnerErrorCode.ErrNotFoundRoaming); - } - } - - iRouteResponse = await Scene.NetworkMessagingComponent.CallInnerRoute(routeId, request); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrRoamingTimeout; - } - - switch (iRouteResponse.ErrorCode) - { - case InnerErrorCode.ErrRouteTimeout: - case InnerErrorCode.ErrRoamingTimeout: - { - return iRouteResponse; - } - case InnerErrorCode.ErrNotFoundRoute: - case InnerErrorCode.ErrNotFoundRoaming: - { - if (++failCount > 20) - { - Log.Error($"Terminus.Call failCount > 20 route send message fail, TerminusId: {routeId}"); - return iRouteResponse; - } - - await Scene.TimerComponent.Net.WaitAsync(100); - - if (runtimeId != RuntimeId) - { - iRouteResponse.ErrorCode = InnerErrorCode.ErrNotFoundRoaming; - } - - routeId = 0; - continue; - } - default: - { - return iRouteResponse; // 对于其他情况,直接返回响应,无需额外处理 - } - } - } - } - - return iRouteResponse; - } - - #endregion -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_GetTerminusIdRequestHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_GetTerminusIdRequestHandler.cs deleted file mode 100644 index 90f7ab9..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_GetTerminusIdRequestHandler.cs +++ /dev/null @@ -1,32 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Network.Roaming; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -namespace Fantasy.Roaming.Handler; - -internal sealed class I_GetTerminusIdRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_GetTerminusIdRequest request, I_GetTerminusIdResponse response, Action reply) - { - if (!scene.TryGetEntity(request.SessionRuntimeId, out var sessionEntity)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundSession; - return; - } - - var session = (Session)sessionEntity; - - if (!scene.RoamingComponent.TryGet(session, out var sessionRoamingComponent) || !sessionRoamingComponent.TryGetRoaming(request.RoamingType, out var sessionRoaming)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundRoamingType; - return; - } - - response.TerminusId = await sessionRoaming.GetTerminusId(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_LinkRoamingRequestHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_LinkRoamingRequestHandler.cs deleted file mode 100644 index 6efb58c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_LinkRoamingRequestHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Roaming.Handler; - -public sealed class I_LinkRoamingRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_LinkRoamingRequest request, I_LinkRoamingResponse response, Action reply) - { - var (errorCode, roamingTerminal) = await scene.TerminusComponent.Create( - request.RoamingId, request.RoamingType, - request.ForwardSessionRouteId, request.SceneRouteId); - - if (errorCode != 0) - { - response.ErrorCode = errorCode; - return; - } - - response.TerminusId = roamingTerminal.TerminusId; - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_LockTerminusIdRequestHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_LockTerminusIdRequestHandler.cs deleted file mode 100644 index c530a1e..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_LockTerminusIdRequestHandler.cs +++ /dev/null @@ -1,35 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Network.Interface; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Roaming.Handler; - -/// -/// 内部网络漫游锁定的请求处理。 -/// -internal sealed class I_LockTerminusIdRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_LockTerminusIdRequest request, I_LockTerminusIdResponse response, Action reply) - { - if (!scene.TryGetEntity(request.SessionRuntimeId, out var sessionEntity)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundSession; - return; - } - - var session = (Session)sessionEntity; - - if (!scene.RoamingComponent.TryGet(session, out var sessionRoamingComponent) || !sessionRoamingComponent.TryGetRoaming(request.RoamingType, out var sessionRoaming)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundRoamingType; - return; - } - - await sessionRoaming.LockTerminusId(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_TransferTerminusRequestHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_TransferTerminusRequestHandler.cs deleted file mode 100644 index 162171f..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_TransferTerminusRequestHandler.cs +++ /dev/null @@ -1,22 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Roaming.Handler; - -/// -/// 传送漫游Terminus的请求处理 -/// -internal sealed class I_TransferTerminusRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_TransferTerminusRequest request, I_TransferTerminusResponse response, Action reply) - { - // 添加Terminus到当前Scene下。 - scene.TerminusComponent.AddTerminus(request.Terminus); - // 执行Terminus的传送完成逻辑。 - await request.Terminus.TransferComplete(scene); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_UnLinkRoamingRequestHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_UnLinkRoamingRequestHandler.cs deleted file mode 100644 index 5849b11..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_UnLinkRoamingRequestHandler.cs +++ /dev/null @@ -1,16 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network.Interface; - -namespace Fantasy.Roaming.Handler; - -internal sealed class I_UnLinkRoamingRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_UnLinkRoamingRequest request, I_UnLinkRoamingResponse response, Action reply) - { - scene.TerminusComponent.RemoveTerminus(request.RoamingId, request.DisposeRoaming); - await FTask.CompletedTask; - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_UnLockTerminusIdRequestHandler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_UnLockTerminusIdRequestHandler.cs deleted file mode 100644 index 8a04079..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Roaming/Handler/I_UnLockTerminusIdRequestHandler.cs +++ /dev/null @@ -1,36 +0,0 @@ -#if FANTASY_NET -using Fantasy.Async; -using Fantasy.InnerMessage; -using Fantasy.Network; -using Fantasy.Network.Interface; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Roaming.Handler; - -/// -/// 内部网络漫游解锁的请求处理。 -/// -internal sealed class I_UnLockTerminusIdRequestHandler : RouteRPC -{ - protected override async FTask Run(Scene scene, I_UnLockTerminusIdRequest request, I_UnLockTerminusIdResponse response, Action reply) - { - if (!scene.TryGetEntity(request.SessionRuntimeId, out var sessionEntity)) - { - response.ErrorCode = InnerErrorCode.ErrUnLockTerminusIdNotFoundSession; - return; - } - - var session = (Session)sessionEntity; - - if (!scene.RoamingComponent.TryGet(session, out var sessionRoamingComponent) || !sessionRoamingComponent.TryGetRoaming(request.RoamingType, out var sessionRoaming)) - { - response.ErrorCode = InnerErrorCode.ErrLockTerminusIdNotFoundRoamingType; - return; - } - - sessionRoaming.UnLockTerminusId(request.TerminusId, request.TargetSceneRouteId); - await FTask.CompletedTask; - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Route/RouteComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Route/RouteComponent.cs deleted file mode 100644 index 1ce1fe8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Route/RouteComponent.cs +++ /dev/null @@ -1,82 +0,0 @@ -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; - -#if FANTASY_NET -namespace Fantasy.Network; - -/// -/// RouteComponent的AwakeSystem -/// -public sealed class RouteComponentAwakeSystem : AwakeSystem -{ - /// - /// Awake - /// - /// - /// - protected override void Awake(RouteComponent self) - { - ((Session)self.Parent).RouteComponent = self; - } -} - -/// -/// 自定义Route组件、如果要自定义Route协议必须使用这个组件 -/// -public sealed class RouteComponent : Entity -{ - /// - /// 存储路由类型和路由ID的映射关系。 - /// - public readonly Dictionary RouteAddress = new Dictionary(); - - /// - /// 添加路由类型和路由ID的映射关系。 - /// - /// 路由类型。 - /// 路由ID。 - public void AddAddress(long routeType, long routeId) - { - RouteAddress.Add(routeType, routeId); - } - - /// - /// 移除指定路由类型的映射关系。 - /// - /// 路由类型。 - public void RemoveAddress(long routeType) - { - RouteAddress.Remove(routeType); - } - - /// - /// 获取指定路由类型的路由ID。 - /// - /// 路由类型。 - /// 路由ID。 - public long GetRouteId(long routeType) - { - return RouteAddress.GetValueOrDefault(routeType, 0); - } - - /// - /// 尝试获取指定路由类型的路由ID。 - /// - /// 路由类型。 - /// 输出的路由ID。 - /// 如果获取成功返回true,否则返回false。 - public bool TryGetRouteId(long routeType, out long routeId) - { - return RouteAddress.TryGetValue(routeType, out routeId); - } - - /// - /// 释放组件资源,清空映射关系。 - /// - public override void Dispose() - { - RouteAddress.Clear(); - base.Dispose(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Component/ConsoleSessionHeartbeatComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Component/ConsoleSessionHeartbeatComponent.cs deleted file mode 100644 index dc4677e..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Component/ConsoleSessionHeartbeatComponent.cs +++ /dev/null @@ -1,156 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global - -#if FANTASY_CONSOLE - -using System; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.InnerMessage; -using Fantasy.Timer; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Network -{ - public class SessionHeartbeatComponentAwakeSystem : AwakeSystem - { - protected override void Awake(SessionHeartbeatComponent self) - { - self.TimerComponent = self.Scene.TimerComponent; - } - } - - /// - /// 负责管理会话心跳的组件。 - /// - public class SessionHeartbeatComponent : Entity - { - public int TimeOut; - public long TimerId; - public long LastTime; - public long SelfRunTimeId; - public long TimeOutTimerId; - public long SessionRunTimeId; - public TimerComponent TimerComponent; - public EntityReference Session; - private readonly PingRequest _pingRequest = new PingRequest(); - - public int Ping { get; private set; } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - Stop(); - Ping = 0; - Session = null; - TimeOut = 0; - SelfRunTimeId = 0; - base.Dispose(); - } - - /// - /// 使用指定的间隔启动心跳功能。 - /// - /// 以毫秒为单位的心跳请求发送间隔。 - /// 设置与服务器的通信超时时间,如果超过这个时间限制,将自动断开会话(Session)。 - /// 用于检测与服务器连接超时频率。 - public void Start(int interval, int timeOut = 2000, int timeOutInterval = 3000) - { - TimeOut = timeOut + interval; - Session = (Session)Parent; - SelfRunTimeId = RuntimeId; - LastTime = TimeHelper.Now; - - if (TimerComponent == null) - { - Log.Error("请在Unity的菜单执行Fantasy->Generate link.xml再重新打包"); - return; - } - - TimerId = TimerComponent.Net.RepeatedTimer(interval, () => RepeatedSend().Coroutine()); - TimeOutTimerId = TimerComponent.Net.RepeatedTimer(timeOutInterval, CheckTimeOut); - } - - private void CheckTimeOut() - { - if (TimeHelper.Now - LastTime < TimeOut) - { - return; - } - - Session entityReference = Session; - - if (entityReference == null) - { - return; - } - - entityReference.Dispose(); - } - - /// - /// 停止心跳功能。 - /// - public void Stop() - { - if (TimerId != 0) - { - TimerComponent?.Net.Remove(ref TimerId); - } - - if (TimeOutTimerId != 0) - { - TimerComponent?.Net.Remove(ref TimeOutTimerId); - } - } - - /// - /// 异步发送心跳请求并处理响应。 - /// - /// 表示进行中操作的异步任务。 - private async FTask RepeatedSend() - { - if (SelfRunTimeId != RuntimeId) - { - Stop(); - return; - } - - Session session = Session; - - if (session == null) - { - Dispose(); - return; - } - - try - { - var requestTime = TimeHelper.Now; - - var pingResponse = (PingResponse)await session.Call(_pingRequest); - - if (pingResponse.ErrorCode != 0) - { - return; - } - - var responseTime = TimeHelper.Now; - LastTime = responseTime; - Ping = (int)(responseTime - requestTime) / 2; - TimeHelper.TimeDiff = pingResponse.Now + Ping - responseTime; - } - catch (Exception) - { - Dispose(); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Component/SessionIdleCheckerComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Component/SessionIdleCheckerComponent.cs deleted file mode 100644 index 1edc1cf..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Component/SessionIdleCheckerComponent.cs +++ /dev/null @@ -1,104 +0,0 @@ -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Timer; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#if FANTASY_NET -namespace Fantasy.Network; - -public class SessionIdleCheckerComponentAwakeSystem : AwakeSystem -{ - protected override void Awake(SessionIdleCheckerComponent self) - { - self.TimerComponent = self.Scene.TimerComponent; - } -} - -/// -/// 负责检查会话空闲超时的组件。 -/// -public class SessionIdleCheckerComponent : Entity -{ - /// - /// 空闲超时时间(毫秒) - /// - private long _timeOut; - /// - /// 检查计时器的 ID - /// - private long _timerId; - /// - /// 用于确保组件完整性的自身运行时 ID - /// - private long _selfRuntimeId; - /// - /// 对会话对象的引用 - /// - private Session _session; - public TimerComponent TimerComponent; - - /// - /// 重写 Dispose 方法以释放资源。 - /// - public override void Dispose() - { - Stop(); // 停止检查计时器 - _timeOut = 0; // 重置空闲超时时间 - _selfRuntimeId = 0; // 重置自身运行时 ID - _session = null; // 清除会话引用 - base.Dispose(); - } - - /// - /// 使用指定的间隔和空闲超时时间启动空闲检查功能。 - /// - /// 以毫秒为单位的检查间隔。 - /// 以毫秒为单位的空闲超时时间。 - public void Start(int interval, int timeOut) - { - _timeOut = timeOut; - _session = (Session)Parent; - _selfRuntimeId = RuntimeId; - // 安排重复计时器,在指定的间隔内执行 Check 方法 - _timerId = TimerComponent.Net.RepeatedTimer(interval, Check); - } - - /// - /// 停止空闲检查功能。 - /// - public void Stop() - { - if (_timerId == 0) - { - return; - } - - TimerComponent.Net.Remove(ref _timerId); - } - - /// - /// 执行空闲检查操作。 - /// - private void Check() - { - if (_selfRuntimeId != RuntimeId || IsDisposed || _session == null) - { - Stop(); - return; - } - - var timeNow = TimeHelper.Now; - - if (timeNow - _session.LastReceiveTime < _timeOut) - { - return; - } - - Log.Warning($"session timeout id:{Id} timeNow:{timeNow} _session.LastReceiveTime:{_session.LastReceiveTime} _timeOut:{_timeOut}"); - _session.Dispose(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Component/UnitySessionHeartbeatComponent.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Component/UnitySessionHeartbeatComponent.cs deleted file mode 100644 index 83c7cbf..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Component/UnitySessionHeartbeatComponent.cs +++ /dev/null @@ -1,156 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global - -using System; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.InnerMessage; -using Fantasy.Timer; - -#if FANTASY_UNITY - -namespace Fantasy.Network -{ - public class SessionHeartbeatComponentAwakeSystem : AwakeSystem - { - protected override void Awake(SessionHeartbeatComponent self) - { - self.TimerComponent = self.Scene.TimerComponent; - } - } - - /// - /// 负责管理会话心跳的组件。 - /// - public class SessionHeartbeatComponent : Entity - { - public int TimeOut; - public long TimerId; - public long LastTime; - public long SelfRunTimeId; - public long TimeOutTimerId; - public TimerComponent TimerComponent; - public EntityReference Session; - private readonly PingRequest _pingRequest = new PingRequest(); - - public int Ping { get; private set; } - - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - Stop(); - Ping = 0; - Session = null; - TimeOut = 0; - LastTime = 0; - SelfRunTimeId = 0; - base.Dispose(); - } - - /// - /// 使用指定的间隔启动心跳功能。 - /// - /// 以毫秒为单位的心跳请求发送间隔。 - /// 设置与服务器的通信超时时间,如果超过这个时间限制,将自动断开会话(Session)。 - /// 用于检测与服务器连接超时频率。 - public void Start(int interval, int timeOut = 5000, int timeOutInterval = 3000) - { - TimeOut = timeOut + interval; - Session = (Session)Parent; - SelfRunTimeId = RuntimeId; - LastTime = TimeHelper.Now; - - if (TimerComponent == null) - { - Log.Error("请在Unity的菜单执行Fantasy->Generate link.xml再重新打包"); - return; - } - - TimerId = TimerComponent.Unity.RepeatedTimer(interval, () => - { - RepeatedSend().Coroutine(); - }); - TimeOutTimerId = TimerComponent.Unity.RepeatedTimer(timeOutInterval, CheckTimeOut); - } - - private void CheckTimeOut() - { - if (TimeHelper.Now - LastTime < TimeOut) - { - return; - } - - Session entityReference = Session; - - if (entityReference == null) - { - return; - } - - entityReference.Dispose(); - } - - /// - /// 停止心跳功能。 - /// - public void Stop() - { - if (TimerId != 0) - { - TimerComponent?.Unity.Remove(ref TimerId); - } - - if (TimeOutTimerId != 0) - { - TimerComponent?.Unity.Remove(ref TimeOutTimerId); - } - } - - /// - /// 异步发送心跳请求并处理响应。 - /// - /// 表示进行中操作的异步任务。 - private async FTask RepeatedSend() - { - if (SelfRunTimeId != RuntimeId) - { - Stop(); - return; - } - - Session session = Session; - - if (session == null) - { - Dispose(); - return; - } - - try - { - var requestTime = TimeHelper.Now; - var pingResponse = (PingResponse)await session.Call(_pingRequest); - - if (pingResponse.ErrorCode != 0) - { - return; - } - - var responseTime = TimeHelper.Now; - LastTime = responseTime; - Ping = (int)(responseTime - requestTime) / 2; - TimeHelper.TimeDiff = pingResponse.Now + Ping - responseTime; - } - catch (Exception) - { - Dispose(); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/ProcessSession/ProcessScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Session/ProcessSession/ProcessScheduler.cs deleted file mode 100644 index ec7c30c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/ProcessSession/ProcessScheduler.cs +++ /dev/null @@ -1,269 +0,0 @@ -#if FANTASY_NET -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -using Fantasy.IdFactory; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.PacketParser.Interface; -using Fantasy.Platform.Net; - -namespace Fantasy.Scheduler; - -internal static class ProcessScheduler -{ - public static void Scheduler(this ProcessSession session, Type messageType, uint rpcId, long routeId, APackInfo packInfo) - { - switch (packInfo.OpCodeIdStruct.Protocol) - { - case OpCodeType.InnerResponse: - case OpCodeType.InnerRouteResponse: - case OpCodeType.InnerAddressableResponse: - case OpCodeType.InnerRoamingResponse: - case OpCodeType.OuterAddressableResponse: - case OpCodeType.OuterCustomRouteResponse: - case OpCodeType.OuterRoamingResponse: - { - using (packInfo) - { - var sessionScene = session.Scene; - var message = packInfo.Deserialize(messageType); - sessionScene.ThreadSynchronizationContext.Post(() => - { - // 因为有可能是其他Scene线程下发送过来的、所以必须放到当前Scene进程下运行。 - sessionScene.NetworkMessagingComponent.ResponseHandler(rpcId, (IResponse)message); - }); - } - - return; - } - case OpCodeType.InnerRouteMessage: - { - using (packInfo) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new Exception($"not found scene routeId:{routeId}"); - } - - var message = packInfo.Deserialize(messageType); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - var sceneMessageDispatcherComponent = scene.MessageDispatcherComponent; - - if (entity == null || entity.IsDisposed) - { - return; - } - - sceneMessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, message, rpcId).Coroutine(); - }); - } - - return; - } - case OpCodeType.InnerRouteRequest: - { - using (packInfo) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new Exception($"not found scene routeId:{routeId}"); - } - - var message = packInfo.Deserialize(messageType); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - var sceneMessageDispatcherComponent = scene.MessageDispatcherComponent; - - if (entity == null || entity.IsDisposed) - { - sceneMessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, rpcId); - return; - } - - sceneMessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, message, rpcId).Coroutine(); - }); - } - - return; - } - case OpCodeType.OuterAddressableMessage: - case OpCodeType.OuterCustomRouteMessage: - case OpCodeType.OuterAddressableRequest: - case OpCodeType.OuterCustomRouteRequest: - case OpCodeType.OuterRoamingMessage: - case OpCodeType.OuterRoamingRequest: - { - using (packInfo) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new NotSupportedException($"not found scene routeId = {routeId}"); - } - - var message = packInfo.Deserialize(messageType); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - - if (entity == null || entity.IsDisposed) - { - scene.MessageDispatcherComponent.FailRouteResponse(session, messageType, InnerErrorCode.ErrNotFoundRoute, rpcId); - return; - } - - scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, message, rpcId).Coroutine(); - }); - } - return; - } - default: - { - var packInfoProtocolCode = packInfo.ProtocolCode; - packInfo.Dispose(); - throw new NotSupportedException($"SessionInnerScheduler Received unsupported message protocolCode:{packInfoProtocolCode} messageType:{messageType}"); - } - } - } - - public static void Scheduler(this ProcessSession session, Type messageType, uint rpcId, long routeId, uint protocolCode, object message) - { - OpCodeIdStruct opCodeIdStruct = protocolCode; - - switch (opCodeIdStruct.Protocol) - { - case OpCodeType.InnerResponse: - case OpCodeType.InnerRouteResponse: - case OpCodeType.InnerAddressableResponse: - case OpCodeType.InnerRoamingResponse: - case OpCodeType.OuterAddressableResponse: - case OpCodeType.OuterCustomRouteResponse: - case OpCodeType.OuterRoamingResponse: - { - var sessionScene = session.Scene; - sessionScene.ThreadSynchronizationContext.Post(() => - { - var iResponse = (IResponse)session.Deserialize(messageType, message, ref opCodeIdStruct); - // 因为有可能是其他Scene线程下发送过来的、所以必须放到当前Scene进程下运行。 - sessionScene.NetworkMessagingComponent.ResponseHandler(rpcId, iResponse); - }); - - return; - } - case OpCodeType.InnerRoamingMessage: - case OpCodeType.InnerAddressableMessage: - case OpCodeType.InnerRouteMessage: - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new Exception($"not found scene routeId:{routeId}"); - } - - var messageObject = session.Deserialize(messageType, message, ref opCodeIdStruct); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - var sceneMessageDispatcherComponent = scene.MessageDispatcherComponent; - - if (entity == null || entity.IsDisposed) - { - return; - } - - sceneMessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, messageObject, rpcId).Coroutine(); - }); - - return; - } - case OpCodeType.InnerAddressableRequest: - case OpCodeType.InnerRoamingRequest: - case OpCodeType.InnerRouteRequest: - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - throw new Exception($"not found scene routeId:{routeId}"); - } - - var messageObject = session.Deserialize(messageType, message, ref opCodeIdStruct); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - var sceneMessageDispatcherComponent = scene.MessageDispatcherComponent; - - if (entity == null || entity.IsDisposed) - { - sceneMessageDispatcherComponent.FailRouteResponse(session, message.GetType(), InnerErrorCode.ErrNotFoundRoute, rpcId); - return; - } - - sceneMessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, messageObject, rpcId).Coroutine(); - }); - - return; - } - case OpCodeType.OuterAddressableMessage: - case OpCodeType.OuterCustomRouteMessage: - case OpCodeType.OuterRoamingMessage: - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - - if (!Process.TryGetScene(sceneId, out var scene)) - { - Log.Error($"not found scene routeId:{routeId}"); - return; - } - - var messageObject = session.Deserialize(messageType, message, ref opCodeIdStruct); - - scene.ThreadSynchronizationContext.Post(() => - { - var entity = scene.GetEntity(routeId); - - switch (entity) - { - case null: - { - // 执行到这里是说明Session已经断开了 - // 因为这里是其他服务器Send到外网的数据、所以不需要给发送端返回就可以 - return; - } - case Session gateSession: - { - // 这里如果是Session只可能是Gate的Session、如果是的话、肯定是转发Address消息 - gateSession.Send((IMessage)messageObject, rpcId); - return; - } - default: - { - scene.MessageDispatcherComponent.RouteMessageHandler(session, messageType, entity, messageObject, rpcId).Coroutine(); - return; - } - } - }); - - return; - } - default: - { - throw new NotSupportedException($"SessionInnerScheduler Received unsupported message protocolCode:{protocolCode} messageType:{messageType}"); - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/ProcessSession/ProcessSession.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Session/ProcessSession/ProcessSession.cs deleted file mode 100644 index ecd0bd4..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/ProcessSession/ProcessSession.cs +++ /dev/null @@ -1,124 +0,0 @@ -using Fantasy.Async; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.PacketParser.Interface; -using Fantasy.Pool; -using Fantasy.Scheduler; -using Fantasy.Serialize; -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#if FANTASY_NET -namespace Fantasy.Network; - -/// -/// 网络服务器内部会话。 -/// -public sealed class ProcessSession : Session -{ - private readonly MemoryStreamBufferPool _memoryStreamBufferPool = new MemoryStreamBufferPool(); - private readonly Dictionary> _createInstances = new Dictionary>(); - - /// - /// 发送消息到服务器内部。 - /// - /// 要发送的消息。 - /// RPC 标识符。 - /// 路由标识符。 - public override void Send(IMessage message, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - this.Scheduler(message.GetType(), rpcId, routeId, message.OpCode(), message); - } - - /// - /// 发送路由消息到服务器内部。 - /// - /// 要发送的路由消息。 - /// RPC 标识符。 - /// 路由标识符。 - public override void Send(IRouteMessage routeMessage, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - this.Scheduler(routeMessage.GetType(), rpcId, routeId, routeMessage.OpCode(), routeMessage); - } - - public override void Send(uint rpcId, long routeId, Type messageType, APackInfo packInfo) - { - if (IsDisposed) - { - return; - } - - this.Scheduler(messageType, rpcId, routeId, packInfo); - } - - public override void Send(ProcessPackInfo packInfo, uint rpcId = 0, long routeId = 0) - { - this.Scheduler(packInfo.MessageType, rpcId, routeId, packInfo); - } - - public override void Send(MemoryStreamBuffer memoryStream, uint rpcId = 0, long routeId = 0) - { - throw new Exception("The use of this method is not supported"); - } - - public override FTask Call(IRouteRequest request, long routeId = 0) - { - throw new Exception("The use of this method is not supported"); - } - - public override FTask Call(IRequest request, long routeId = 0) - { - throw new Exception("The use of this method is not supported"); - } - - public object Deserialize(Type messageType, object message, ref OpCodeIdStruct opCodeIdStruct) - { - var memoryStream = _memoryStreamBufferPool.RentMemoryStream(MemoryStreamBufferSource.None); - - try - { - if (SerializerManager.TryGetSerializer(opCodeIdStruct.OpCodeProtocolType, out var serializer)) - { - serializer.Serialize(messageType, message, memoryStream); - - if (memoryStream.Position == 0) - { - if (_createInstances.TryGetValue(messageType, out var createInstance)) - { - return createInstance(); - } - - createInstance = CreateInstance.CreateObject(messageType); - _createInstances.Add(messageType, createInstance); - return createInstance(); - } - - memoryStream.SetLength(memoryStream.Position); - memoryStream.Seek(0, SeekOrigin.Begin); - return serializer.Deserialize(messageType, memoryStream); - } - } - catch (Exception e) - { - Log.Error($"ProcessSession.Deserialize {e}"); - } - finally - { - _memoryStreamBufferPool.ReturnMemoryStream(memoryStream); - } - - throw new Exception($"type:{messageType} Does not support processing protocol"); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/ProcessSession/ProcessSessionInfo.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Session/ProcessSession/ProcessSessionInfo.cs deleted file mode 100644 index 6e3a534..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/ProcessSession/ProcessSessionInfo.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Fantasy.Network.Interface; - -#if FANTASY_NET -namespace Fantasy.Network; - -internal sealed class ProcessSessionInfo(Session session, AClientNetwork aClientNetwork) : IDisposable -{ - public readonly Session Session = session; - public readonly AClientNetwork AClientNetwork = aClientNetwork; - - public void Dispose() - { - Session.Dispose(); - AClientNetwork?.Dispose(); - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Session.cs b/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Session.cs deleted file mode 100644 index fc75dea..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Network/Session/Session.cs +++ /dev/null @@ -1,272 +0,0 @@ -// ReSharper disable RedundantUsingDirective -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; -using Fantasy.Helper; -using Fantasy.Network.Interface; -using Fantasy.PacketParser; -using Fantasy.PacketParser.Interface; -using Fantasy.Scheduler; -using Fantasy.Serialize; -#if FANTASY_NET -using Fantasy.Network.Route; -using Fantasy.Platform.Net; -using Fantasy.Network.Roaming; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#endif -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 -#pragma warning disable CS8601 -#pragma warning disable CS8618 - -namespace Fantasy.Network -{ - /// - /// 网络会话的基类,用于管理网络通信。 - /// - public class Session : Entity, ISupportedMultiEntity - { - private uint _rpcId; - internal long LastReceiveTime; - /// - /// 关联的网络连接通道 - /// - internal INetworkChannel Channel { get; private set; } - /// - /// 当前Session的终结点信息 - /// - public IPEndPoint RemoteEndPoint { get; private set; } - private ANetworkMessageScheduler NetworkMessageScheduler { get; set;} - internal readonly Dictionary> RequestCallback = new(); - /// - /// Session的Dispose委托 - /// - internal event Action OnDispose; -#if FANTASY_NET - internal RouteComponent RouteComponent; - internal SessionRoamingComponent SessionRoamingComponent; - internal AddressableRouteComponent AddressableRouteComponent; - internal static Session Create(ANetworkMessageScheduler networkMessageScheduler, ANetworkServerChannel channel, NetworkTarget networkTarget) - { - var session = Entity.Create(channel.Scene, false, true); - session.Channel = channel; - session.NetworkMessageScheduler = networkMessageScheduler; - session.RemoteEndPoint = channel.RemoteEndPoint as IPEndPoint; - session.OnDispose = channel.Dispose; - session.LastReceiveTime = TimeHelper.Now; - // 在外部网络目标下,添加会话空闲检查组件 - if (networkTarget == NetworkTarget.Outer) - { - var interval = ProcessDefine.SessionIdleCheckerInterval; - var timeOut = ProcessDefine.SessionIdleCheckerTimeout; - session.AddComponent().Start(interval, timeOut); - } - return session; - } -#endif - internal static Session Create(AClientNetwork network, IPEndPoint remoteEndPoint) - { - // 创建会话实例 - var session = Entity.Create(network.Scene, false, true); - session.Channel = network; - session.RemoteEndPoint = remoteEndPoint; - session.OnDispose = network.Dispose; - session.NetworkMessageScheduler = network.NetworkMessageScheduler; - session.LastReceiveTime = TimeHelper.Now; - return session; - } -#if FANTASY_NET - internal static ProcessSession CreateInnerSession(Scene scene) - { - var session = Entity.Create(scene, false, false); - session.NetworkMessageScheduler = new InnerMessageScheduler(scene); - return session; - } - - /// - /// 发送一个消息,框架内部使用建议不要用这个方法。 - /// - /// 如果是RPC消息需要传递一个RPCId - /// routeId - /// 消息的类型 - /// packInfo消息包 - public virtual void Send(uint rpcId, long routeId, Type messageType, APackInfo packInfo) - { - if (IsDisposed) - { - return; - } - - Channel.Send(rpcId, routeId, packInfo.MemoryStream, null); - } - - /// - /// 发送一个消息,框架内部使用建议不要用这个方法。 - /// - /// 一个ProcessPackInfo消息包 - /// 如果是RPC消息需要传递一个RPCId - /// routeId - public virtual void Send(ProcessPackInfo packInfo, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - using (packInfo) - { - Channel.Send(rpcId, routeId, packInfo.MemoryStream, null); - } - } - - /// - /// 发送一个消息 - /// - /// 需要发送的MemoryStreamBuffer - /// 如果是RPC消息需要传递一个RPCId - /// routeId - public virtual void Send(MemoryStreamBuffer memoryStream, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - Channel.Send(rpcId, routeId, memoryStream, null); - } -#endif - /// - /// 销毁一个Session,当执行了这个方法会自动断开网络的连接。 - /// - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - _rpcId = 0; - LastReceiveTime = 0; - Channel = null; - RemoteEndPoint = null; - NetworkMessageScheduler = null; -#if FANTASY_NET - SessionRoamingComponent = null; - RouteComponent = null; - AddressableRouteComponent = null; -#endif - base.Dispose(); - - // 终止所有等待中的请求回调 - foreach (var requestCallback in RequestCallback.Values.ToArray()) - { - requestCallback.SetException(new Exception($"session is dispose: {Id}")); - } - - RequestCallback.Clear(); - OnDispose?.Invoke(); - } - - /// - /// 发送一个消息 - /// - /// 消息的实例 - /// 如果是RPC消息需要传递一个RPCId - /// routeId - public virtual void Send(IMessage message, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - Channel.Send(rpcId, routeId, null, message); - } - - /// - /// 发送一个消息 - /// - /// 消息的实例,不同的是这个是发送Route消息使用的 - /// 如果是RPC消息需要传递一个RPCId - /// routeId - public virtual void Send(IRouteMessage routeMessage, uint rpcId = 0, long routeId = 0) - { - if (IsDisposed) - { - return; - } - - Channel.Send(rpcId, routeId, null, routeMessage); - } - - /// - /// 发送一个RPC消息 - /// - /// 请求Route消息的实例 - /// routeId - /// - public virtual FTask Call(IRouteRequest request, long routeId = 0) - { - if (IsDisposed) - { - return null; - } - - var requestCallback = FTask.Create(); - var rpcId = ++_rpcId; - RequestCallback.Add(rpcId, requestCallback); - Send(request, rpcId, routeId); - return requestCallback; - } - - /// - /// 发送一个RPC消息 - /// - /// 请求消息的实例 - /// routeId - /// - public virtual FTask Call(IRequest request, long routeId = 0) - { - if (IsDisposed) - { - return null; - } - - var requestCallback = FTask.Create(); - var rpcId = ++_rpcId; - RequestCallback.Add(rpcId, requestCallback); - Send(request, rpcId, routeId); - return requestCallback; - } - - internal void Receive(APackInfo packInfo) - { - if (IsDisposed) - { - return; - } - - LastReceiveTime = TimeHelper.Now; - - try - { - NetworkMessageScheduler.Scheduler(this, packInfo).Coroutine(); - } - catch (Exception e) - { - // 如果解析失败,只有一种可能,那就是有人恶意发包。 - // 所以这里强制关闭了当前连接。不让对方一直发包。 - Dispose(); - Log.Error(e); - } - } - } -} diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Console/Entry.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Console/Entry.cs deleted file mode 100644 index 2cddb8b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Console/Entry.cs +++ /dev/null @@ -1,101 +0,0 @@ -#if FANTASY_CONSOLE -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.Serialize; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Console -{ - public struct OnFantasyInit - { - public Scene Scene; - } - - /// - /// 一般的控制台启动入口,可以适用大部分客户端环境 - /// - public sealed class Entry - { - private static bool _isInit; - private static Thread _updateThread; - public static Scene Scene { get; private set; } - - /// - /// 初始化框架 - /// - /// - public static async FTask Initialize(params System.Reflection.Assembly[] assemblies) - { - if (_isInit) - { - Log.Error("Fantasy has already been initialized and does not need to be initialized again!"); - return; - } - - // 初始化程序集管理系统 - await AssemblySystem.InnerInitialize(assemblies); - // 初始化序列化 - SerializerManager.Initialize(); - _isInit = true; - Log.Debug("Fantasy Initialize Complete!"); - } - - /// - /// 启动框架。 - /// 如果您的平台有每帧更新逻辑的方法,请不要调用这个方法。 - /// 如果没有实现每帧执行方法平台需要调用这个方法,目的是开启一个新的线程来每帧执行Update。 - /// 注意因为开启了一个新的线程来处理更新逻辑,所以要注意多线程的问题。 - /// - public static void StartUpdate() - { - _updateThread = new Thread(() => - { - while (_isInit) - { - ThreadScheduler.Update(); - Thread.Sleep(1); - } - }) - { - IsBackground = true - }; - _updateThread.Start(); - } - - /// - /// 在Entry中创建一个Scene,如果Scene已经被创建过,将先销毁Scene再创建。 - /// - /// - /// - public static async FTask CreateScene(string sceneRuntimeMode = SceneRuntimeMode.MainThread) - { - Scene?.Dispose(); - Scene = await Scene.Create(sceneRuntimeMode); - await Scene.EventComponent.PublishAsync(new OnFantasyInit() - { - Scene = Scene - }); - return Scene; - } - - /// - /// 如果有的话一定要在每帧执行这个方法 - /// - public void Update() - { - ThreadScheduler.Update(); - } - - public static void Dispose() - { - AssemblySystem.Dispose(); - SerializerManager.Dispose(); - Scene?.Dispose(); - Scene = null; - _isInit = false; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Console/ThreadSynchronizationContext.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Console/ThreadSynchronizationContext.cs deleted file mode 100644 index 29fd54a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Console/ThreadSynchronizationContext.cs +++ /dev/null @@ -1,38 +0,0 @@ -#if FANTASY_CONSOLE -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8765 // Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes). -namespace Fantasy -{ - public sealed class ThreadSynchronizationContext : SynchronizationContext - { - private Action _actionHandler; - private readonly Queue _queue = new(); - - public void Update() - { - while (_queue.TryDequeue(out _actionHandler)) - { - try - { - _actionHandler(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void Post(SendOrPostCallback callback, object state) - { - Post(() => callback(state)); - } - - public void Post(Action action) - { - _queue.Enqueue(action); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/MachineConfig.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/MachineConfig.cs deleted file mode 100644 index e09b00e..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/MachineConfig.cs +++ /dev/null @@ -1,88 +0,0 @@ -#if FANTASY_NET -// ReSharper disable InconsistentNaming -using System.Collections.Concurrent; -using System.Runtime.Serialization; -using Fantasy.Helper; -using Newtonsoft.Json; -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Net -{ - /// - /// 用于记录服务器物理信息 - /// - public sealed class MachineConfigData - { - /// - /// 存放所有MachineConfigInfo信息 - /// - public List List; - [JsonIgnore] - [IgnoreDataMember] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); - /// - /// 获得MachineConfig的实例 - /// - public static MachineConfigData Instance { get; private set; } - /// - /// 初始化MachineConfig - /// - /// - public static void Initialize(string machineConfigJson) - { - Instance = machineConfigJson.Deserialize(); - foreach (var config in Instance.List) - { - Instance._configs.TryAdd(config.Id, config); - } - } - /// - /// 根据Id获取MachineConfig - /// - /// - /// - /// - public MachineConfig Get(uint id) - { - if (_configs.TryGetValue(id, out var machineConfigInfo)) - { - return machineConfigInfo; - } - - throw new FileNotFoundException($"MachineConfig not find {id} Id"); - } - /// - /// 根据Id获取MachineConfig - /// - /// - /// - /// - public bool TryGet(uint id, out MachineConfig config) - { - return _configs.TryGetValue(id, out config); - } - } - /// - /// 表示一个物理服务器的信息 - /// - public sealed class MachineConfig - { - /// - /// Id - /// - public uint Id { get; set; } - /// - /// 外网IP - /// - public string OuterIP { get; set; } - /// - /// 外网绑定IP - /// - public string OuterBindIP { get; set; } - /// - /// 内网绑定IP - /// - public string InnerBindIP { get; set; } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/ProcessConfig.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/ProcessConfig.cs deleted file mode 100644 index 4a400b0..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/ProcessConfig.cs +++ /dev/null @@ -1,100 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using System.Runtime.Serialization; -using Fantasy.Helper; -using Newtonsoft.Json; -// ReSharper disable CollectionNeverUpdated.Global -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Platform.Net -{ - /// - /// 用于管理进程信息 - /// - public sealed class ProcessConfigData - { - /// - /// 存放所有ProcessConfig信息 - /// - public List List; - [JsonIgnore] - [IgnoreDataMember] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); - /// - /// 获得ProcessConfigData的实例 - /// - public static ProcessConfigData Instance { get; private set; } - /// - /// 初始化MachineConfig - /// - /// - public static void Initialize(string processConfigJson) - { - Instance = processConfigJson.Deserialize(); - foreach (var config in Instance.List) - { - Instance._configs.TryAdd(config.Id, config); - } - } - /// - /// 根据Id获取ProcessConfig - /// - /// - /// - /// - public ProcessConfig Get(uint id) - { - if (_configs.TryGetValue(id, out var processConfigInfo)) - { - return processConfigInfo; - } - - throw new FileNotFoundException($"MachineConfig not find {id} Id"); - } - /// - /// 根据Id获取ProcessConfig - /// - /// - /// - /// - public bool TryGet(uint id, out ProcessConfig config) - { - return _configs.TryGetValue(id, out config); - } - /// - /// 按照startupGroup寻找属于startupGroup组的ProcessConfig - /// - /// startupGroup - /// - public IEnumerable ForEachByStartupGroup(uint startupGroup) - { - foreach (var processConfig in List) - { - if (processConfig.StartupGroup == startupGroup) - { - yield return processConfig; - } - } - } - } - /// - /// 表示一个进程配置信息 - /// - public sealed class ProcessConfig - { - /// - /// 进程Id - /// - public uint Id { get; set; } - /// - /// 机器ID - /// - public uint MachineId { get; set; } - /// - /// 启动组 - /// - public uint StartupGroup { get; set; } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/SceneConfig.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/SceneConfig.cs deleted file mode 100644 index e939419..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/SceneConfig.cs +++ /dev/null @@ -1,196 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using System.Runtime.Serialization; -using Fantasy.DataStructure.Collection; -using Fantasy.DataStructure.Dictionary; -using Fantasy.Helper; -using Fantasy.IdFactory; -using Newtonsoft.Json; -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8601 // Possible null reference assignment. - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Net -{ - /// - /// 存放所有SceneConfigInfo信息 - /// - public sealed class SceneConfigData - { - /// - /// 存放所有SceneConfig信息 - /// - public List List; - [JsonIgnore] - [IgnoreDataMember] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); - [JsonIgnore] - [IgnoreDataMember] - private readonly OneToManyList _sceneConfigBySceneType = new OneToManyList(); - [JsonIgnore] - [IgnoreDataMember] - private readonly OneToManyList _sceneConfigByProcess = new OneToManyList(); - [JsonIgnore] [IgnoreDataMember] - private readonly Dictionary>> _worldSceneTypes = new Dictionary>>(); - /// - /// 获得SceneConfigData的实例 - /// - public static SceneConfigData Instance { get; private set; } - /// - /// 初始化SceneConfig - /// - /// - public static void Initialize(string sceneConfigJson) - { - Instance = sceneConfigJson.Deserialize(); - foreach (var config in Instance.List) - { - config.Initialize(); - Instance._configs.TryAdd(config.Id, config); - Instance._sceneConfigByProcess.Add(config.ProcessConfigId, config); - Instance._sceneConfigBySceneType.Add(config.SceneType, config); - - var configWorldConfigId = (int)config.WorldConfigId; - - if (!Instance._worldSceneTypes.TryGetValue(configWorldConfigId, out var sceneConfigDic)) - { - sceneConfigDic = new Dictionary>(); - Instance._worldSceneTypes.Add(configWorldConfigId, sceneConfigDic); - } - - if (!sceneConfigDic.TryGetValue(config.SceneType, out var sceneConfigList)) - { - sceneConfigList = new List(); - sceneConfigDic.Add(config.SceneType, sceneConfigList); - } - - sceneConfigList.Add(config); - } - } - - /// - /// 根据Id获取SceneConfig - /// - /// - /// - /// - public SceneConfig Get(uint id) - { - if (_configs.TryGetValue(id, out var sceneConfigInfo)) - { - return sceneConfigInfo; - } - - throw new FileNotFoundException($"WorldConfig not find {id} Id"); - } - - /// - /// 根据Id获取SceneConfig - /// - /// - /// - /// - public bool TryGet(uint id, out SceneConfig config) - { - return _configs.TryGetValue(id, out config); - } - - /// - /// 获得SceneConfig - /// - /// - /// - public List GetByProcess(uint serverConfigId) - { - return _sceneConfigByProcess.TryGetValue(serverConfigId, out var list) ? list : new List(); - } - - /// - /// 获得SceneConfig - /// - /// - /// - public List GetSceneBySceneType(int sceneType) - { - return !_sceneConfigBySceneType.TryGetValue(sceneType, out var list) ? new List() : list; - } - - /// - /// 获得SceneConfig - /// - /// - /// - /// - public List GetSceneBySceneType(int world, int sceneType) - { - if (!_worldSceneTypes.TryGetValue(world, out var sceneConfigDic)) - { - return new List(); - } - - if (!sceneConfigDic.TryGetValue(sceneType, out var list)) - { - return new List(); - } - - return list; - } - } - - /// - /// 表示一个Scene配置信息 - /// - public sealed class SceneConfig - { - /// - /// ID - /// - public uint Id { get; set; } - /// - /// 进程Id - /// - public uint ProcessConfigId { get; set; } - /// - /// 世界Id - /// - public uint WorldConfigId { get; set; } - /// - /// Scene运行类型 - /// - public string SceneRuntimeMode { get; set; } - /// - /// Scene类型 - /// - public string SceneTypeString { get; set; } - /// - /// 协议类型 - /// - public string NetworkProtocol { get; set; } - /// - /// 外网端口 - /// - public int OuterPort { get; set; } - /// - /// 内网端口 - /// - public int InnerPort { get; set; } - /// - /// Scene类型 - /// - public int SceneType { get; set; } - /// - /// RouteId - /// - [JsonIgnore] - [IgnoreDataMember] - public long RouteId { get; private set; } - /// - /// 初始化方法 - /// - public void Initialize() - { - RouteId = IdFactoryHelper.RuntimeId(0, Id, (byte)WorldConfigId, 0); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/WorldConfig.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/WorldConfig.cs deleted file mode 100644 index 9b0ede5..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ConfigTable/WorldConfig.cs +++ /dev/null @@ -1,93 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using System.Runtime.Serialization; -using Fantasy.Helper; -using Newtonsoft.Json; -#pragma warning disable CS8601 // Possible null reference assignment. - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Net -{ - /// - /// 存放所有WorldConfigInfo信息 - /// - public sealed class WorldConfigData - { - /// - /// 存放所有WorldConfigInfo信息 - /// - public List List; - [JsonIgnore] - [IgnoreDataMember] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); - /// - /// 获得WorldConfig的实例 - /// - public static WorldConfigData Instance { get; private set; } - /// - /// 初始化WorldConfig - /// - /// - public static void Initialize(string worldConfigJson) - { - Instance = worldConfigJson.Deserialize(); - foreach (var config in Instance.List) - { - Instance._configs.TryAdd(config.Id, config); - } - } - /// - /// 根据Id获取WorldConfig - /// - /// - /// - /// - public WorldConfig Get(uint id) - { - if (_configs.TryGetValue(id, out var worldConfigInfo)) - { - return worldConfigInfo; - } - - throw new FileNotFoundException($"WorldConfig not find {id} Id"); - } - /// - /// 根据Id获取WorldConfig - /// - /// - /// - /// - public bool TryGet(uint id, out WorldConfig config) - { - return _configs.TryGetValue(id, out config); - } - } - - /// - /// 表示一个世界配置信息 - /// - public sealed class WorldConfig - { - /// - /// Id - /// - public uint Id { get; set; } - /// - /// 名称 - /// - public string WorldName { get; set; } - /// - /// 数据库连接字符串 - /// - public string DbConnection { get; set; } - /// - /// 数据库名称 - /// - public string DbName { get; set; } - /// - /// 数据库类型 - /// - public string DbType { get; set; } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/Entry.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/Entry.cs deleted file mode 100644 index 959818d..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/Entry.cs +++ /dev/null @@ -1,124 +0,0 @@ -#if FANTASY_NET -using CommandLine; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.IdFactory; -using Fantasy.LowLevel; -using Fantasy.Network; -using Fantasy.Serialize; -// ReSharper disable FunctionNeverReturns - -namespace Fantasy.Platform.Net; - -/// -/// Fantasy.Net 应用程序入口 -/// -/// 当命令行格式异常时抛出。 -/// 不支持的 ProcessType 类型异常。 -public static class Entry -{ - /// - /// 框架初始化 - /// - /// 注册的Assembly - public static async FTask Initialize(params System.Reflection.Assembly[] assemblies) - { - // 解析命令行参数 - Parser.Default.ParseArguments(Environment.GetCommandLineArgs()) - .WithNotParsed(error => throw new Exception("Command line format error!")) - .WithParsed(option => - { - ProcessDefine.Options = option; - ProcessDefine.InnerNetwork = Enum.Parse(option.InnerNetwork); - }); - // 初始化Log系统 - Log.Initialize(); - // 检查启动参数,后期可能有机器人等不同的启动参数 - switch (ProcessDefine.Options.ProcessType) - { - case "Game": - { - break; - } - default: - { - throw new NotSupportedException($"ProcessType is {ProcessDefine.Options.ProcessType} Unrecognized!"); - } - } - // 初始化程序集管理系统 - await AssemblySystem.InnerInitialize(assemblies); - // 初始化序列化 - SerializerManager.Initialize(); - // 精度处理(只针对Windows下有作用、其他系统没有这个问题、一般也不会用Windows来做服务器的) - WinPeriod.Initialize(); - - FantasyMemory.Initialize(); - } - - /// - /// 启动Fantasy.Net - /// - public static async FTask Start() - { - // 启动Process - StartProcess().Coroutine(); - await FTask.CompletedTask; - while (true) - { - ThreadScheduler.Update(); - Thread.Sleep(1); - } - } - - /// - /// 初始化并且启动框架 - /// - /// - public static async FTask Start(params System.Reflection.Assembly[] assemblies) - { - await Initialize(assemblies); - await Start(); - } - - private static async FTask StartProcess() - { - if (ProcessDefine.Options.StartupGroup != 0) - { - foreach (var processConfig in ProcessConfigData.Instance.ForEachByStartupGroup((uint)ProcessDefine.Options.StartupGroup)) - { - await Process.Create(processConfig.Id); - } - - return; - } - - switch (ProcessDefine.Options.Mode) - { - case "Develop": - { - foreach (var processConfig in ProcessConfigData.Instance.List) - { - await Process.Create(processConfig.Id); - } - - return; - } - case "Release": - { - await Process.Create(ProcessDefine.Options.ProcessId); - return; - } - } - } - - /// - /// 关闭 Fantasy - /// - public static void Close() - { - AssemblySystem.Dispose(); - SerializerManager.Dispose(); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/Process.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/Process.cs deleted file mode 100644 index e3a6cf8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/Process.cs +++ /dev/null @@ -1,156 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -using Fantasy.Async; -using Fantasy.IdFactory; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8601 // Possible null reference assignment. -namespace Fantasy.Platform.Net; - -/// -/// 一个进程的实例 -/// -public sealed class Process : IDisposable -{ - /// - /// 当前进程的Id - /// - public readonly uint Id; - /// - /// 进程关联的MachineId - /// - public readonly uint MachineId; - private readonly ConcurrentDictionary _processScenes = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary Scenes = new ConcurrentDictionary(); - private Process() {} - private Process(uint id, uint machineId) - { - Id = id; - MachineId = machineId; - } - - internal bool IsProcess(ref long routeId) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - return _processScenes.ContainsKey(sceneId); - } - - internal bool IsProcess(ref uint sceneId) - { - return _processScenes.ContainsKey(sceneId); - } - - internal void AddSceneToProcess(Scene scene) - { - _processScenes.TryAdd(scene.SceneConfigId, scene); - } - - internal void RemoveSceneToProcess(Scene scene, bool isDispose) - { - if (!_processScenes.Remove(scene.SceneConfigId, out _)) - { - return; - } - - if (isDispose) - { - scene.Dispose(); - } - } - - internal bool TryGetSceneToProcess(long routeId, out Scene scene) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - return _processScenes.TryGetValue(sceneId, out scene); - } - - internal bool TryGetSceneToProcess(uint sceneId, out Scene scene) - { - return _processScenes.TryGetValue(sceneId, out scene); - } - /// - /// 销毁方法 - /// - public void Dispose() - { - if (_processScenes.IsEmpty) - { - return; - } - - var sceneQueue = new Queue(); - - foreach (var (_, scene) in _processScenes) - { - sceneQueue.Enqueue(scene); - } - - while (sceneQueue.TryDequeue(out var removeScene)) - { - removeScene.Dispose(); - } - - _processScenes.Clear(); - } - - internal static async FTask Create(uint processConfigId) - { - if (!ProcessConfigData.Instance.TryGet(processConfigId, out var processConfig)) - { - Log.Error($"not found processConfig by Id:{processConfigId}"); - return null; - } - - if (!MachineConfigData.Instance.TryGet(processConfig.MachineId, out var machineConfig)) - { - Log.Error($"not found machineConfig by Id:{processConfig.MachineId}"); - return null; - } - - var process = new Process(processConfigId, processConfig.MachineId); - var sceneConfigs = SceneConfigData.Instance.GetByProcess(processConfigId); - - foreach (var sceneConfig in sceneConfigs) - { - await Scene.Create(process, machineConfig, sceneConfig); - } - - Log.Info($"Process:{processConfigId} Startup Complete SceneCount:{sceneConfigs.Count}"); - return process; - } - - internal bool IsInAppliaction(ref uint sceneId) - { - return _processScenes.ContainsKey(sceneId); - } - - internal static void AddScene(Scene scene) - { - Scenes.TryAdd(scene.SceneConfigId, scene); - } - - internal static void RemoveScene(Scene scene, bool isDispose) - { - if (!Scenes.Remove(scene.SceneConfigId, out _)) - { - return; - } - - if (isDispose) - { - scene.Dispose(); - } - } - - internal static bool TryGetScene(long routeId, out Scene scene) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref routeId); - return Scenes.TryGetValue(sceneId, out scene); - } - - internal static bool TryGetScene(uint sceneId, out Scene scene) - { - return Scenes.TryGetValue(sceneId, out scene); - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ProcessDefine.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ProcessDefine.cs deleted file mode 100644 index 2bcc4e0..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ProcessDefine.cs +++ /dev/null @@ -1,99 +0,0 @@ -#if FANTASY_NET -using CommandLine; -using Fantasy.Network; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Platform.Net; - -/// -/// Process运行模式 -/// -public enum ProcessMode -{ - /// - /// 默认 - /// - None =0, - /// - /// 开发模式 - /// - Develop = 1, - /// - /// 发布模式 - /// - Release = 2 -} - -internal sealed class CommandLineOptions -{ - /// - /// 用于启动指定的进程,该进程的 ID 与 ProcessConfig 的 ID 相关联。此参数只能传递单个 ID,不支持传递多个 ID。 - /// - [Option("pid", Required = false, Default = (uint)0, HelpText = "Enter an ProcessIdId such as 1")] - public uint ProcessId { get; set; } - /// - /// Process类型,获取或设置应用程序的类型。 - /// Game - 游戏服务器Process - /// Robot - 机器人(暂未支持该功能) - /// - [Option('a', "ProcessType", Required = false, Default = "Game", HelpText = "Game")] - public string ProcessType { get; set; } - /// - /// 服务器运行模式,获取或设置服务器的运行模式。 - /// Develop - 开发模式(启动Process配置表中的所有Process) - /// Release - 发布模式(根据ProcessId启动Process) - /// - [Option('m', "Mode", Required = true, Default = "Release", HelpText = "Develop:启动Process配置表中的所有Process,\nRelease:根据ProcessId启动Process")] - public string Mode { get; set; } - /// - /// 服务器内部网络协议 - /// TCP - 服务器内部之间通讯使用TCP协议 - /// KCP - 服务器内部之间通讯使用KCP协议 - /// WebSocket - 服务器内部之间通讯使用WebSocket协议(不推荐、TCP或KCP) - /// - [Option('n', "InnerNetwork", Required = false, Default = "TCP", HelpText = "TCP、KCP、WebSocket")] - public string InnerNetwork { get; set; } - /// - /// 会话空闲检查超时时间。 - /// - [Option('t', "SessionIdleCheckerTimeout", Required = false, Default = 8000, HelpText = "Session idle check timeout")] - public int SessionIdleCheckerTimeout { get; set; } - /// - /// 会话空闲检查间隔。 - /// - [Option('i', "SessionIdleCheckerInterval", Required = false, Default = 5000, HelpText = "Session idle check interval")] - public int SessionIdleCheckerInterval { get; set; } - /// - /// 启动组。 - /// - [Option('g', "StartupGroup", Required = false, Default = 0, HelpText = "Used to start a group of Process")] - public int StartupGroup { get; set; } -} - -/// -/// AppDefine -/// -internal static class ProcessDefine -{ - /// - /// 命令行选项 - /// - public static CommandLineOptions Options; - /// - /// App程序Id - /// - public static uint ProcessId => Options.ProcessId; - /// - /// 会话空闲检查超时时间。 - /// - public static int SessionIdleCheckerTimeout => Options.SessionIdleCheckerTimeout; - /// - /// 会话空闲检查间隔。 - /// - public static int SessionIdleCheckerInterval => Options.SessionIdleCheckerInterval; - /// - /// 内部网络通讯协议类型 - /// - public static NetworkProtocolType InnerNetwork; -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ThreadSynchronizationContext.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ThreadSynchronizationContext.cs deleted file mode 100644 index bb2948a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Net/ThreadSynchronizationContext.cs +++ /dev/null @@ -1,52 +0,0 @@ -#if FANTASY_NET -using System.Collections.Concurrent; -#pragma warning disable CS8765 -#pragma warning disable CS8601 -#pragma warning disable CS8618 - -namespace Fantasy; - -/// -/// 线程的同步上下文 -/// -public sealed class ThreadSynchronizationContext : SynchronizationContext -{ - private readonly ConcurrentQueue _queue = new(); - /// - /// 执行当前上下文投递过的逻辑 - /// - public void Update() - { - while (_queue.TryDequeue(out var actionHandler)) - { - try - { - actionHandler(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - /// - /// 投递一个逻辑到当前上下文 - /// - /// - /// - public override void Post(SendOrPostCallback callback, object state) - { - Post(() => callback(state)); - } - - /// - /// 投递一个逻辑到当前上下文 - /// - /// - public void Post(Action action) - { - _queue.Enqueue(action); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/AppDefine.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/AppDefine.cs deleted file mode 100644 index d9d85ae..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/AppDefine.cs +++ /dev/null @@ -1,19 +0,0 @@ -#if FANTASY_UNITY -namespace Fantasy.Platform.Unity -{ - public static class AppDefine - { - public static string RemoteUpdatePath; - public static bool EditorModel = true; - public const string VersionName = "version.bytes"; - public const string VersionMD5Name = "version.md5"; - public const string AssetBundleManifestName = "Fantasy"; - public static bool IsEditor => UnityEngine.Application.isEditor && EditorModel; - public static string AssetBundleSaveDirectory => "Assets/AssetBundles"; - public static string LocalAssetBundlePath => UnityEngine.Application.streamingAssetsPath; - public static string RemoteAssetBundlePath => UnityEngine.Application.persistentDataPath; - public static string PersistentDataVersion => $"{UnityEngine.Application.persistentDataPath}/{VersionName}"; - public static string StreamingAssetsVersion => $"{UnityEngine.Application.streamingAssetsPath}/{VersionName}"; - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonDefaultValueAttribute.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonDefaultValueAttribute.cs deleted file mode 100644 index 49914ec..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonDefaultValueAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] - public class BsonDefaultValueAttribute : Attribute - { - public BsonDefaultValueAttribute(object defaultValue) { } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonElementAttribute.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonElementAttribute.cs deleted file mode 100644 index 3892727..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonElementAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] - public class BsonElementAttribute : Attribute - { - public BsonElementAttribute() { } - - public BsonElementAttribute(string elementName) { } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIdAttribute.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIdAttribute.cs deleted file mode 100644 index 48274d0..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIdAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public class BsonIdAttribute : Attribute - { - - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreAttribute.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreAttribute.cs deleted file mode 100644 index 23e55c8..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] - public class BsonIgnoreAttribute : Attribute - { - - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfDefaultAttribute.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfDefaultAttribute.cs deleted file mode 100644 index 82dddde..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfDefaultAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] - public class BsonIgnoreIfDefaultAttribute : Attribute - { - public BsonIgnoreIfDefaultAttribute() { } - - public BsonIgnoreIfDefaultAttribute(bool value) { } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfNullAttribute.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfNullAttribute.cs deleted file mode 100644 index f330a8b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Attributes/BsonIgnoreIfNullAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if FANTASY_UNITY -using System; -namespace MongoDB.Bson.Serialization.Attributes -{ - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public class BsonIgnoreIfNullAttribute : Attribute - { - - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Entry.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Entry.cs deleted file mode 100644 index e5377f2..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Entry.cs +++ /dev/null @@ -1,102 +0,0 @@ -#if FANTASY_UNITY -using System.Linq; -using Fantasy.Assembly; -using Fantasy.Async; -using Fantasy.Serialize; -using UnityEngine; -using UnityEngine.Scripting; - -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Platform.Unity -{ - public sealed class FantasyObject : MonoBehaviour - { - public static GameObject FantasyObjectGameObject { get; private set; } - - public static void OnRuntimeMethodLoad() - { - FantasyObjectGameObject = new GameObject("Fantasy.Net"); - DontDestroyOnLoad(FantasyObjectGameObject); - } - private void OnApplicationQuit() - { - Destroy(FantasyObjectGameObject); - } - } - - public struct OnSceneCreate - { - public Scene Scene; - public object Arg; - } - - public class Entry : MonoBehaviour - { - private static bool _isInit; - public static Scene Scene { get; private set; } - - /// - /// 初始化框架 - /// - /// - public static async FTask Initialize(params System.Reflection.Assembly[] assemblies) - { - if (_isInit) - { - Log.Error("Fantasy has already been initialized and does not need to be initialized again!"); - return; - } - FantasyObject.OnRuntimeMethodLoad(); - Log.Register(new UnityLog()); - await AssemblySystem.InnerInitialize(assemblies); - // 初始化序列化 - SerializerManager.Initialize(); -#if FANTASY_WEBGL - ThreadSynchronizationContext.Initialize(); -#endif - _isInit = true; - FantasyObject.FantasyObjectGameObject.AddComponent(); - Log.Debug("Fantasy Initialize Complete!"); - } - - /// - /// 在Entry中创建一个Scene,如果Scene已经被创建过,将先销毁Scene再创建。 - /// - /// - /// - /// - public static async FTask CreateScene(object arg = null, string sceneRuntimeMode = SceneRuntimeMode.MainThread) - { - Scene?.Dispose(); - Scene = await Scene.Create(sceneRuntimeMode); - await Scene.EventComponent.PublishAsync(new OnSceneCreate() - { - Arg = arg, - Scene = Scene - }); - return Scene; - } - - private void Update() - { - ThreadScheduler.Update(); - } - - private void OnDestroy() - { - AssemblySystem.Dispose(); - SerializerManager.Dispose(); - if (Scene != null) - { - Scene?.Dispose(); - Scene = null; - } - _isInit = false; - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Temp.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Temp.cs deleted file mode 100644 index 399488f..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/Temp.cs +++ /dev/null @@ -1,108 +0,0 @@ -// using System.Reflection; -// using Fantasy.Assembly; -// using Fantasy.Async; -// // using UnityEngine; -// #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value -// #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -// #pragma warning disable CS8603 // Possible null reference return. -// #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -// #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -// -// namespace Fantasy.Platform.Unity -// { -// public class MonoBehaviour -// { -// -// } -// -// public class GameObject -// { -// public GameObject(string name) -// { -// -// } -// } -// -// internal enum RuntimeInitializeLoadType -// { -// BeforeSceneLoad = 1, -// } -// -// internal class RuntimeInitializeOnLoadMethodAttribute : Attribute -// { -// public RuntimeInitializeLoadType RuntimeInitializeLoadType; -// -// public RuntimeInitializeOnLoadMethodAttribute(RuntimeInitializeLoadType loadType) -// { -// -// } -// } -// -// public sealed class FantasyObject : MonoBehaviour -// { -// public static GameObject FantasyObjectGameObject { get; private set; } -// // 这个方法将在游戏启动时自动调用 -// [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] -// static void OnRuntimeMethodLoad() -// { -// FantasyObjectGameObject = new GameObject("Fantasy.Net"); -// // DontDestroyOnLoad(FantasyObjectGameObject); -// } -// private void OnApplicationQuit() -// { -// // Destroy(FantasyObjectGameObject); -// } -// } -// -// public struct OnFantasyInit -// { -// public Scene Scene; -// } -// -// public class Entry : MonoBehaviour -// { -// private static bool _isInit; -// public static Scene Scene { get; private set; } -// /// -// /// 初始化框架 -// /// -// public static async FTask Initialize(params System.Reflection.Assembly[] assemblies) -// { -// Scene?.Dispose(); -// // 初始化程序集管理系统 -// AssemblySystem.Initialize(assemblies); -// if (!_isInit) -// { -// #if FANTASY_WEBGL -// ThreadSynchronizationContext.Initialize(); -// #endif -// _isInit = true; -// // FantasyObject.FantasyObjectGameObject.AddComponent(); -// } -// // Scene = await Scene.Create(SceneRuntimeType.MainThread); -// // await Scene.EventComponent.PublishAsync(new OnFantasyInit() -// // { -// // Scene = Scene -// // }); -// // return Scene; -// await FTask.CompletedTask; -// return null; -// } -// -// private void Update() -// { -// ThreadScheduler.Update(); -// } -// -// private void OnDestroy() -// { -// AssemblySystem.Dispose(); -// if (Scene != null) -// { -// Scene?.Dispose(); -// Scene = null; -// } -// _isInit = false; -// } -// } -// } diff --git a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/ThreadSynchronizationContext.cs b/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/ThreadSynchronizationContext.cs deleted file mode 100644 index 44b165a..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Platform/Unity/ThreadSynchronizationContext.cs +++ /dev/null @@ -1,104 +0,0 @@ -#if FANTASY_UNITY && !FANTASY_WEBGL -#pragma warning disable CS8765 -#pragma warning disable CS8601 -#pragma warning disable CS8618 -using System; -using System.Collections.Concurrent; -using System.Threading; - -namespace Fantasy -{ - public sealed class ThreadSynchronizationContext : SynchronizationContext - { - private Action _actionHandler; - private readonly ConcurrentQueue _queue = new(); - - public void Update() - { - while (_queue.TryDequeue(out _actionHandler)) - { - try - { - _actionHandler(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void Post(SendOrPostCallback callback, object state) - { - Post(() => callback(state)); - } - - public void Post(Action action) - { - _queue.Enqueue(action); - } - } -} -#endif -#if FANTASY_UNITY && FANTASY_WEBGL -using System; -using System.Collections.Generic; -using System.Threading; -using Fantasy; -using UnityEngine; -using Object = UnityEngine.Object; - -public class WebGLSynchronizationContextUpdater : MonoBehaviour -{ - private ThreadSynchronizationContext _context; - - public void Initialize(ThreadSynchronizationContext context) - { - _context = context; - } - - void Update() - { - _context.Update(); - } -} -public sealed class ThreadSynchronizationContext : SynchronizationContext -{ - private Action _actionHandler; - private readonly Queue _queue = new(); - - public static void Initialize() - { - var context = new ThreadSynchronizationContext(); - SetSynchronizationContext(context); - var go = new GameObject("WebGLSynchronizationContextUpdater"); - go.AddComponent().Initialize(context); - Object.DontDestroyOnLoad(go); - } - - public void Update() - { - while (_queue.TryDequeue(out _actionHandler)) - { - try - { - _actionHandler(); - } - catch (Exception e) - { - Log.Error(e); - } - } - } - - public override void Post(SendOrPostCallback callback, object state) - { - Post(() => callback(state)); - } - - public void Post(Action action) - { - _queue.Enqueue(action); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Pool/Concurrent/MultiThreadPool.cs b/Fantasy/Fantays.Console/Runtime/Core/Pool/Concurrent/MultiThreadPool.cs deleted file mode 100644 index 4c946d1..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Pool/Concurrent/MultiThreadPool.cs +++ /dev/null @@ -1,37 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Concurrent; -using System.Runtime.CompilerServices; -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Pool -{ - /// - /// 线程安全的静态通用对象池。 - /// - internal static class MultiThreadPool - { - private static readonly ConcurrentDictionary ObjectPools = new ConcurrentDictionary(); - - public static T Rent() where T : IPool, new() - { - return ObjectPools.GetOrAdd(typeof(T), t => new MultiThreadPoolQueue(2000, () => new T())).Rent(); - } - - public static IPool Rent(Type type) - { - return ObjectPools.GetOrAdd(type, t => new MultiThreadPoolQueue(2000, CreateInstance.CreateIPool(type))).Rent(); - } - - public static void Return(T obj) where T : IPool, new() - { - if (!obj.IsPool()) - { - return; - } - - ObjectPools.GetOrAdd(typeof(T), t => new MultiThreadPoolQueue(2000, () => new T())).Return(obj); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Pool/Concurrent/MultiThreadPoolQueue.cs b/Fantasy/Fantays.Console/Runtime/Core/Pool/Concurrent/MultiThreadPoolQueue.cs deleted file mode 100644 index df15a1c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Pool/Concurrent/MultiThreadPoolQueue.cs +++ /dev/null @@ -1,76 +0,0 @@ -#if !FANTASY_WEBGL -using System; -using System.Collections.Concurrent; -using System.Threading; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Pool -{ - /// - /// 线程安全的对象池。 - /// - internal class MultiThreadPoolQueue - { - private int _poolCount; - private readonly int _maxCapacity; - private readonly Func _createInstance; - private readonly ConcurrentQueue _poolQueue = new ConcurrentQueue(); - private MultiThreadPoolQueue() { } - - public MultiThreadPoolQueue(int maxCapacity, Func createInstance) - { - _maxCapacity = maxCapacity; - _createInstance = createInstance; - } - - public T Rent() where T : IPool, new() - { - if (!_poolQueue.TryDequeue(out var t)) - { - var pool = new T(); - pool.SetIsPool(true); - return pool; - } - - t.SetIsPool(true); - Interlocked.Decrement(ref _poolCount); - return (T)t; - } - - public IPool Rent() - { - if (!_poolQueue.TryDequeue(out var t)) - { - var instance = _createInstance(); - instance.SetIsPool(true); - return instance; - } - - t.SetIsPool(true); - Interlocked.Decrement(ref _poolCount); - return t; - } - - public void Return(IPool obj) - { - if (!obj.IsPool()) - { - return; - } - - obj.SetIsPool(false); - - if (Interlocked.Increment(ref _poolCount) <= _maxCapacity) - { - _poolQueue.Enqueue(obj); - return; - } - - Interlocked.Decrement(ref _poolCount); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Pool/Interface/IPool.cs b/Fantasy/Fantays.Console/Runtime/Core/Pool/Interface/IPool.cs deleted file mode 100644 index 1775f28..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Pool/Interface/IPool.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Fantasy.Pool -{ - /// - /// 实现了这个接口代表支持对象池 - /// - public interface IPool - { - /// - /// 是否从池里创建的 - /// - bool IsPool(); - /// - /// 设置是否从池里创建的 - /// - /// - void SetIsPool(bool isPool); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Pool/Normal/Pool.cs b/Fantasy/Fantays.Console/Runtime/Core/Pool/Normal/Pool.cs deleted file mode 100644 index 88006e1..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Pool/Normal/Pool.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -// ReSharper disable CheckNamespace - -namespace Fantasy.Pool -{ - /// - /// 静态的对象池系统,不支持多线程。 - /// - /// - public static class Pool where T : IPool, new() - { - private static readonly Queue PoolQueue = new Queue(); - /// - /// 池子里可用的数量 - /// - public static int Count => PoolQueue.Count; - - /// - /// 租借 - /// - /// - public static T Rent() - { - return PoolQueue.Count == 0 ? new T() : PoolQueue.Dequeue(); - } - - /// - /// 租借 - /// - /// 如果池子里没有,会先执行这个委托。 - /// - public static T Rent(Func generator) - { - return PoolQueue.Count == 0 ? generator() : PoolQueue.Dequeue(); - } - - /// - /// 返还 - /// - /// - public static void Return(T t) - { - if (t == null) - { - return; - } - - PoolQueue.Enqueue(t); - } - - /// - /// 返还 - /// - /// 返还的东西 - /// 返还后执行的委托 - public static void Return(T t, Action reset) - { - if (t == null) - { - return; - } - - reset(t); - PoolQueue.Enqueue(t); - } - - /// - /// 清空池子 - /// - public static void Clear() - { - PoolQueue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Pool/Normal/PoolCore.cs b/Fantasy/Fantays.Console/Runtime/Core/Pool/Normal/PoolCore.cs deleted file mode 100644 index 94144f1..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Pool/Normal/PoolCore.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using Fantasy.DataStructure.Collection; - -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy.Pool -{ - /// - /// 对象池抽象接口,用于创建和管理可重复使用的对象实例。 - /// - public abstract class PoolCore : IDisposable - { - private int _poolCount; - private readonly int _maxCapacity; - /// - /// 池子里可用的数量 - /// - public int Count => _poolQueue.Count; - private readonly OneToManyQueue _poolQueue = new OneToManyQueue(); - private readonly Dictionary> _typeCheckCache = new Dictionary>(); - - /// - /// 构造函数 - /// - /// 初始的容量 - protected PoolCore(int maxCapacity) - { - _maxCapacity = maxCapacity; - } - - /// - /// 租借 - /// - /// - /// - public T Rent() where T : IPool, new() - { - if (!_poolQueue.TryDequeue(typeof(T), out var queue)) - { - queue = new T(); - } - - queue.SetIsPool(true); - _poolCount--; - return (T)queue; - } - - /// - /// 租借 - /// - /// 租借的类型 - /// - /// - public IPool Rent(Type type) - { - if (!_poolQueue.TryDequeue(type, out var queue)) - { - if (!_typeCheckCache.TryGetValue(type, out var createInstance)) - { - if (!typeof(IPool).IsAssignableFrom(type)) - { - throw new NotSupportedException($"{this.GetType().FullName} Type:{type.FullName} must inherit from IPool"); - } - else - { - createInstance = CreateInstance.CreateIPool(type); - _typeCheckCache[type] = createInstance; - } - } - - var instance = createInstance(); - instance.SetIsPool(true); - return instance; - } - - queue.SetIsPool(true); - _poolCount--; - return queue; - } - - /// - /// 返还 - /// - /// - /// - public void Return(Type type, IPool obj) - { - if (obj == null) - { - return; - } - - if (!obj.IsPool()) - { - return; - } - - if (_poolCount >= _maxCapacity) - { - return; - } - - _poolCount++; - obj.SetIsPool(false); - _poolQueue.Enqueue(type, obj); - } - - /// - /// 销毁方法 - /// - public virtual void Dispose() - { - _poolCount = 0; - _poolQueue.Clear(); - _typeCheckCache.Clear(); - } - } - - /// - /// 泛型对象池核心类,用于创建和管理可重复使用的对象实例。 - /// - /// 要池化的对象类型 - public abstract class PoolCore where T : IPool, new() - { - private int _poolCount; - private readonly int _maxCapacity; - private readonly Queue _poolQueue = new Queue(); - /// - /// 池子里可用的数量 - /// - public int Count => _poolQueue.Count; - - /// - /// 构造函数 - /// - /// 初始的容量 - protected PoolCore(int maxCapacity) - { - _maxCapacity = maxCapacity; - } - - /// - /// 租借 - /// - /// - public virtual T Rent() - { - T dequeue; - - if (_poolQueue.Count == 0) - { - dequeue = new T(); - } - else - { - _poolCount--; - dequeue = _poolQueue.Dequeue(); - } - - dequeue.SetIsPool(true); - return dequeue; - } - - /// - /// 返还 - /// - /// - public virtual void Return(T item) - { - if (item == null) - { - return; - } - - if (!item.IsPool()) - { - return; - } - - if (_poolCount >= _maxCapacity) - { - return; - } - - _poolCount++; - item.SetIsPool(false); - _poolQueue.Enqueue(item); - } - - /// - /// 销毁方法 - /// - public virtual void Dispose() - { - _poolCount = 0; - _poolQueue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Pool/Normal/PoolWithDisposable.cs b/Fantasy/Fantays.Console/Runtime/Core/Pool/Normal/PoolWithDisposable.cs deleted file mode 100644 index 3f97f1c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Pool/Normal/PoolWithDisposable.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections.Generic; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - -namespace Fantasy.Pool -{ - /// - /// 静态通用对象池,用于存储实现了 IDisposable 接口的对象。 - /// - /// 要存储在对象池中的对象类型,必须实现 IDisposable 接口。 - public abstract class PoolWithDisposable : IDisposable where T : IPool, IDisposable, new() - { - private int _poolCount; - private readonly int _maxCapacity; - private readonly Queue _poolQueue = new Queue(); - /// - /// 池子里可用的数量 - /// - public int Count => _poolQueue.Count; - - /// - /// 构造函数 - /// - /// 初始的容量 - protected PoolWithDisposable(int maxCapacity) - { - _maxCapacity = maxCapacity; - } - - /// - /// 租借 - /// - /// - public T Rent() - { - T dequeue; - if (_poolQueue.Count == 0) - { - dequeue = new T(); - } - else - { - _poolCount--; - dequeue = _poolQueue.Dequeue(); - } - - dequeue.SetIsPool(true); - return dequeue; - } - - /// - /// 租借 - /// - /// - /// - public T Rent(Func generator) - { - T dequeue; - - if (_poolQueue.Count == 0) - { - dequeue = generator(); - } - else - { - _poolCount--; - dequeue = _poolQueue.Dequeue(); - } - - dequeue.SetIsPool(true); - return dequeue; - } - - /// - /// 返还 - /// - /// - public void Return(T t) - { - if (t == null) - { - return; - } - - if (!t.IsPool()) - { - return; - } - - if (_poolCount >= _maxCapacity) - { - return; - } - - _poolCount++; - t.SetIsPool(true); - _poolQueue.Enqueue(t); - t.Dispose(); - } - - /// - /// 返还 - /// - /// - /// - public void Return(T t, Action reset) - { - if (t == null) - { - return; - } - - if (!t.IsPool()) - { - reset(t); - return; - } - - if (_poolCount >= _maxCapacity) - { - return; - } - - reset(t); - _poolCount++; - t.SetIsPool(false); - _poolQueue.Enqueue(t); - t.Dispose(); - } - - /// - /// 销毁方法 - /// - public virtual void Dispose() - { - _poolCount = 0; - _poolQueue.Clear(); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Pool/PoolHelper.cs b/Fantasy/Fantays.Console/Runtime/Core/Pool/PoolHelper.cs deleted file mode 100644 index d9214fd..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Pool/PoolHelper.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Reflection.Emit; -using Fantasy.Serialize; - -#pragma warning disable CS8604 // Possible null reference argument. - -namespace Fantasy.Pool -{ - internal static class CreateInstance where T : IPool - { - public static Func Create { get; } - - static CreateInstance() - { - var type = typeof(T); - var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - var il = dynamicMethod.GetILGenerator(); - il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - il.Emit(OpCodes.Ret); - Create = (Func) dynamicMethod.CreateDelegate(typeof(Func)); - } - } - - internal static class CreateInstance - { - public static Func CreateIPool(Type type) - { - var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - var il = dynamicMethod.GetILGenerator(); - il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - il.Emit(OpCodes.Ret); - return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - } - - public static Func CreateObject(Type type) - { - var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - var il = dynamicMethod.GetILGenerator(); - il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - il.Emit(OpCodes.Ret); - return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - } - - public static Func CreateMessage(Type type) - { - var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - var il = dynamicMethod.GetILGenerator(); - il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - il.Emit(OpCodes.Ret); - return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - } - } - - // public static class CreateInstance - // { - // public static Func Create(Type type) - // { - // var dynamicMethod = new DynamicMethod($"CreateInstance_{type.Name}", type, Type.EmptyTypes, true); - // var il = dynamicMethod.GetILGenerator(); - // il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); - // il.Emit(OpCodes.Ret); - // return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - // } - // } - - // /// - // /// 利用泛型的特性来减少反射的使用。 - // /// - // /// - // public static class PoolChecker where T : new() - // { - // public static bool IsPool { get; } - // - // static PoolChecker() - // { - // IsPool = typeof(IPool).IsAssignableFrom(typeof(T)); - // } - // } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/ISceneUpdate.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/ISceneUpdate.cs deleted file mode 100644 index f736edf..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/ISceneUpdate.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Fantasy -{ - internal interface ISceneUpdate - { - void Update(); - } - - internal sealed class EmptySceneUpdate : ISceneUpdate - { - public void Update() - { - - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scene.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/Scene.cs deleted file mode 100644 index e961533..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scene.cs +++ /dev/null @@ -1,619 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Fantasy.Async; -using Fantasy.Entitas; -using Fantasy.Event; -using Fantasy.IdFactory; -using Fantasy.Network; -using Fantasy.Network.Interface; -using Fantasy.Pool; -using Fantasy.Scheduler; -using Fantasy.Timer; -#if FANTASY_NET -using Fantasy.DataBase; -using Fantasy.Platform.Net; -using Fantasy.SingleCollection; -using System.Runtime.CompilerServices; -using Fantasy.Network.Route; -using Fantasy.Network.Roaming; -#endif -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -namespace Fantasy -{ - /// - /// 当Scene创建完成后发送的事件参数 - /// - public struct OnCreateScene - { - /// - /// 获取与事件关联的场景实体。 - /// - public readonly Scene Scene; - /// - /// 初始化一个新的 OnCreateScene 实例。 - /// - /// - public OnCreateScene(Scene scene) - { - Scene = scene; - } - } - - /// - /// 表示一个场景实体,用于创建与管理特定的游戏场景信息。 - /// - public partial class Scene : Entity - { - #region Members - /// - /// Scene的运行类型 - /// - public SceneRuntimeType SceneRuntimeType { get; protected set; } -#if FANTASY_NET - /// - /// Scene类型,对应SceneConfig的SceneType - /// - public int SceneType { get; protected set; } - /// - /// 所属的世界 - /// - public World World { get; protected set; } - /// - /// 所在的Process - /// - public Process Process { get; protected set; } - /// - /// SceneConfig的Id - /// - public uint SceneConfigId { get; protected set; } - internal ANetwork InnerNetwork { get; private set; } - internal ANetwork OuterNetwork { get; private set; } - internal SceneConfig SceneConfig => SceneConfigData.Instance.Get(SceneConfigId); - private readonly Dictionary _processSessionInfos = new Dictionary(); -#endif - /// - /// 当前Scene的上下文 - /// - public ThreadSynchronizationContext ThreadSynchronizationContext { get; internal set; } - /// - /// 当前Scene的下创建的Entity - /// - private readonly Dictionary _entities = new Dictionary(); - internal readonly Dictionary> TypeInstance = new Dictionary>(); - #endregion - - #region IdFactory - - /// - /// Entity实体Id的生成器 - /// - public IEntityIdFactory EntityIdFactory { get; protected set; } - /// - /// Entity实体RuntimeId的生成器 - /// - public IRuntimeIdFactory RuntimeIdFactory { get; protected set; } - - #endregion - - #region Pool - - internal EntityPool EntityPool; - internal EntityListPool EntityListPool; - internal EntitySortedDictionaryPool EntitySortedDictionaryPool; - - #endregion - - #region Component - - /// - /// Scene下的任务调度器系统组件 - /// - public TimerComponent TimerComponent { get; internal set; } - /// - /// Scene下的事件系统组件 - /// - public EventComponent EventComponent { get; internal set; } - /// - /// Scene下的ESC系统组件 - /// - public EntityComponent EntityComponent { get; internal set; } - /// - /// Scene下的网络消息对象池组件 - /// - public MessagePoolComponent MessagePoolComponent { get; internal set; } - /// - /// Scene下的协程锁组件 - /// - public CoroutineLockComponent CoroutineLockComponent { get; internal set; } - /// - /// Scene下的网络消息派发组件 - /// - internal MessageDispatcherComponent MessageDispatcherComponent { get; set; } -#if FANTASY_NET - /// - /// Scene下的Entity分表组件 - /// - public SingleCollectionComponent SingleCollectionComponent { get; internal set; } - /// - /// Scene下的内网消息发送组件 - /// - public NetworkMessagingComponent NetworkMessagingComponent { get; internal set; } - /// - /// Scene下的漫游终端管理组件 - /// - public TerminusComponent TerminusComponent { get; internal set; } - /// - /// Scene下的Session漫游组件 - /// - public RoamingComponent RoamingComponent { get; internal set; } -#endif - #endregion - - #region Initialize - - private async FTask Initialize() - { - EntityPool = new EntityPool(); - EntityListPool = new EntityListPool(); - EntitySortedDictionaryPool = new EntitySortedDictionaryPool(); - SceneUpdate = EntityComponent = await Create(this, false, false).Initialize(); - MessagePoolComponent = Create(this,false,true); - EventComponent = await Create(this,false,true).Initialize(); - TimerComponent = Create(this, false, true).Initialize(); - CoroutineLockComponent = Create(this, false, true).Initialize(); - MessageDispatcherComponent = await Create(this, false, true).Initialize(); -#if FANTASY_NET - NetworkMessagingComponent = Create(this, false, true); - SingleCollectionComponent = await Create(this, false, true).Initialize(); - TerminusComponent = Create(this, false, true); - RoamingComponent = Create(this, false, true).Initialize(); -#endif - } - - /// - /// Scene销毁方法,执行了该方法会把当前Scene下的所有实体都销毁掉。 - /// - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - base.Dispose(); - _entities.Remove(RuntimeId); - - switch (SceneRuntimeType) - { - case SceneRuntimeType.Root: - { -#if FANTASY_NET - foreach (var (_, processSessionInfo) in _processSessionInfos.ToList()) - { - processSessionInfo.Dispose(); - } - - _processSessionInfos.Clear(); -#endif - _entities.Remove(EntityComponent.RuntimeId); - - foreach (var (runtimeId, entity) in _entities.ToList()) - { - if (runtimeId != entity.RuntimeId) - { - continue; - } - entity.Dispose(); - } - - _entities.Clear(); -#if FANTASY_UNITY - _unityWorldId--; - _unitySceneId--; -#endif - TypeInstance.Clear(); -#if FANTASY_NET - Process.RemoveScene(this, false); - Process.RemoveSceneToProcess(this, false); -#endif - EntityComponent.Dispose(); - EntityPool.Dispose(); - EntityListPool.Dispose(); - EntitySortedDictionaryPool.Dispose(); - break; - } - case SceneRuntimeType.SubScene: - { - break; - } - default: - { - Log.Error($"SceneRuntimeType: {SceneRuntimeType} The unsupported SceneRuntimeType of the Scene executed Dispose."); - break; - } - } - - SceneUpdate = null; - EntityIdFactory = null; - RuntimeIdFactory = null; - - EntityPool = null; - EntityListPool = null; - EntitySortedDictionaryPool = null; - EntityComponent = null; - TimerComponent = null; - EventComponent = null; - MessagePoolComponent = null; - CoroutineLockComponent = null; - MessageDispatcherComponent = null; -#if FANTASY_NET - World = null; - Process = null; - SceneType = 0; - SceneConfigId = 0; - SingleCollectionComponent = null; - NetworkMessagingComponent = null; - TerminusComponent = null; - RoamingComponent = null; -#elif FANTASY_UNITY - Session = null; - UnityNetwork = null; -#endif - ThreadSynchronizationContext = null; - SceneRuntimeType = SceneRuntimeType.None; - } - - #endregion - - internal ISceneUpdate SceneUpdate { get; set; } - - internal void Update() - { - try - { - SceneUpdate.Update(); - } - catch (Exception e) - { - Log.Error(e); - } - } - - #region Create - -#if FANTASY_UNITY || FANTASY_CONSOLE - private static uint _unitySceneId = 0; - private static byte _unityWorldId = 0; - public Session Session { get; private set; } - private AClientNetwork UnityNetwork { get; set; } - /// - /// 创建一个Unity的Scene,注意:该方法只能在主线程下使用。 - /// - /// 选择Scene的运行方式 - /// - /// - public static async FTask Create(string sceneRuntimeMode = SceneRuntimeMode.MainThread) - { - var world = ++_unityWorldId; - - if (world > byte.MaxValue - 1) - { - throw new Exception($"World ID ({world}) exceeds the maximum allowed value of 255."); - } - - var sceneId = (uint)(++_unitySceneId + world * 1000); - - if (sceneId > 255255) - { - throw new Exception($"Scene ID ({sceneId}) exceeds the maximum allowed value of 255255."); - } - - var scene = new Scene(); - scene.Scene = scene; - scene.Parent = scene; - scene.Type = typeof(Scene); - scene.SceneRuntimeType = SceneRuntimeType.Root; - scene.EntityIdFactory = IdFactoryHelper.EntityIdFactory(sceneId, world); - scene.RuntimeIdFactory = IdFactoryHelper.RuntimeIdFactory(0, sceneId, world); - scene.Id = IdFactoryHelper.EntityId(0, sceneId, world, 0); - scene.RuntimeId = IdFactoryHelper.RuntimeId(0, sceneId, world, 0); - scene.AddEntity(scene); - await SetScheduler(scene, sceneRuntimeMode); - scene.ThreadSynchronizationContext.Post(() => - { - scene.EventComponent.PublishAsync(new OnCreateScene(scene)).Coroutine(); - }); - return scene; - } - public Session Connect(string remoteAddress, NetworkProtocolType networkProtocolType, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000) - { - UnityNetwork?.Dispose(); - UnityNetwork = NetworkProtocolFactory.CreateClient(this, networkProtocolType, NetworkTarget.Outer); - Session = UnityNetwork.Connect(remoteAddress, onConnectComplete, onConnectFail, onConnectDisconnect, isHttps, connectTimeout); - return Session; - } -#endif -#if FANTASY_NET - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Scene Create(Process process, byte worldId, uint sceneConfigId) - { - var scene = new Scene(); - scene.Scene = scene; - scene.Parent = scene; - scene.Type = typeof(Scene); - scene.Process = process; - scene.SceneRuntimeType = SceneRuntimeType.Root; - scene.EntityIdFactory = IdFactoryHelper.EntityIdFactory(sceneConfigId, worldId); - scene.RuntimeIdFactory = IdFactoryHelper.RuntimeIdFactory(0,sceneConfigId, worldId); - scene.Id = IdFactoryHelper.EntityId(0, sceneConfigId, worldId, 0); - scene.RuntimeId = IdFactoryHelper.RuntimeId(0, sceneConfigId, worldId, 0); - scene.AddEntity(scene); - return scene; - } - /// - /// 创建一个新的Scene - /// - /// 所属的Process - /// 对应的MachineConfig配置文件 - /// 对应的SceneConfig配置文件 - /// 创建成功后会返回创建的Scene的实例 - public static async FTask Create(Process process, MachineConfig machineConfig, SceneConfig sceneConfig) - { - var scene = Create(process, (byte)sceneConfig.WorldConfigId, sceneConfig.Id); - scene.SceneType = sceneConfig.SceneType; - scene.SceneConfigId = sceneConfig.Id; - await SetScheduler(scene, sceneConfig.SceneRuntimeMode); - - if (sceneConfig.WorldConfigId != 0) - { - scene.World = World.Create(scene, (byte)sceneConfig.WorldConfigId); - } - - if (sceneConfig.InnerPort != 0) - { - // 创建内网网络服务器 - scene.InnerNetwork = NetworkProtocolFactory.CreateServer(scene, ProcessDefine.InnerNetwork, NetworkTarget.Inner, machineConfig.InnerBindIP, sceneConfig.InnerPort); - } - - if (sceneConfig.OuterPort != 0) - { - // 创建外网网络服务 - var networkProtocolType = Enum.Parse(sceneConfig.NetworkProtocol); - scene.OuterNetwork = NetworkProtocolFactory.CreateServer(scene, networkProtocolType, NetworkTarget.Outer, machineConfig.OuterBindIP, sceneConfig.OuterPort); - } - - Process.AddScene(scene); - process.AddSceneToProcess(scene); - - scene.ThreadSynchronizationContext.Post(() => - { - if (sceneConfig.SceneTypeString == "Addressable") - { - // 如果是AddressableScene,自动添加上AddressableManageComponent。 - scene.AddComponent(); - } - - scene.EventComponent.PublishAsync(new OnCreateScene(scene)).Coroutine(); - }); - - return scene; - } - /// - /// 在Scene下面创建一个子Scene,一般用于副本,或者一些特殊的场景。 - /// - /// 主Scene的实例 - /// SceneType,可以在SceneType里找到,例如:SceneType.Addressable - /// 子Scene创建成功后执行的委托,可以传递null - /// - public static SubScene CreateSubScene(Scene parentScene, int sceneType, Action onSubSceneComplete = null) - { - var scene = new SubScene(); - scene.Scene = scene; - scene.Parent = scene; - scene.RootScene = parentScene; - scene.Type = typeof(SubScene); - scene.SceneType = sceneType; - scene.World = parentScene.World; - scene.Process = parentScene.Process; - scene.SceneRuntimeType = SceneRuntimeType.SubScene; - scene.EntityIdFactory = parentScene.EntityIdFactory; - scene.RuntimeIdFactory = parentScene.RuntimeIdFactory; - scene.Id = scene.EntityIdFactory.Create; - scene.RuntimeId = scene.RuntimeIdFactory.Create; - scene.AddEntity(scene); - scene.Initialize(parentScene); - scene.ThreadSynchronizationContext.Post(() => OnEvent().Coroutine()); - return scene; - async FTask OnEvent() - { - await scene.EventComponent.PublishAsync(new OnCreateScene(scene)); - onSubSceneComplete?.Invoke(scene, parentScene); - } - } -#endif - private static async FTask SetScheduler(Scene scene, string sceneRuntimeMode) - { - switch (sceneRuntimeMode) - { - case "MainThread": - { - scene.ThreadSynchronizationContext = ThreadScheduler.MainScheduler.ThreadSynchronizationContext; - scene.SceneUpdate = new EmptySceneUpdate(); - ThreadScheduler.AddMainScheduler(scene); - await scene.Initialize(); - break; - } - case "MultiThread": - { -#if !FANTASY_WEBGL - scene.ThreadSynchronizationContext = new ThreadSynchronizationContext(); -#endif - scene.SceneUpdate = new EmptySceneUpdate(); - ThreadScheduler.AddToMultiThreadScheduler(scene); - await scene.Initialize(); - break; - } - case "ThreadPool": - { -#if !FANTASY_WEBGL - scene.ThreadSynchronizationContext = new ThreadSynchronizationContext(); -#endif - scene.SceneUpdate = new EmptySceneUpdate(); - ThreadScheduler.AddToThreadPoolScheduler(scene); - await scene.Initialize(); - break; - } - } - } - #endregion - - #region Entities - - /// - /// 添加一个实体到当前Scene下 - /// - /// 实体实例 - public virtual void AddEntity(Entity entity) - { - _entities.Add(entity.RuntimeId, entity); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 返回的实体 - public virtual Entity GetEntity(long runTimeId) - { - return _entities.TryGetValue(runTimeId, out var entity) ? entity : null; - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 实体实例 - /// 返回一个bool值来提示是否查找到这个实体 - public virtual bool TryGetEntity(long runTimeId, out Entity entity) - { - return _entities.TryGetValue(runTimeId, out entity); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 要查询实体的泛型类型 - /// 返回的实体 - public virtual T GetEntity(long runTimeId) where T : Entity - { - return _entities.TryGetValue(runTimeId, out var entity) ? (T)entity : null; - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 实体实例 - /// 要查询实体的泛型类型 - /// 返回一个bool值来提示是否查找到这个实体 - public virtual bool TryGetEntity(long runTimeId, out T entity) where T : Entity - { - if (_entities.TryGetValue(runTimeId, out var getEntity)) - { - entity = (T)getEntity; - return true; - } - - entity = null; - return false; - } - - /// - /// 删除一个实体,仅是删除不会指定实体的销毁方法 - /// - /// 实体的RunTimeId - /// 返回一个bool值来提示是否删除了这个实体 - public virtual bool RemoveEntity(long runTimeId) - { - return _entities.Remove(runTimeId); - } - - /// - /// 删除一个实体,仅是删除不会指定实体的销毁方法 - /// - /// 实体实例 - /// 返回一个bool值来提示是否删除了这个实体 - public virtual bool RemoveEntity(Entity entity) - { - return _entities.Remove(entity.RuntimeId); - } - - #endregion - - #region InnerSession - -#if FANTASY_NET - /// - /// 根据runTimeId获得Session - /// - /// - /// - /// - public virtual Session GetSession(long runTimeId) - { - var sceneId = IdFactoryHelper.RuntimeIdTool.GetSceneId(ref runTimeId); - - if (_processSessionInfos.TryGetValue(sceneId, out var processSessionInfo)) - { - if (!processSessionInfo.Session.IsDisposed) - { - return processSessionInfo.Session; - } - - _processSessionInfos.Remove(sceneId); - } - - if (Process.IsInAppliaction(ref sceneId)) - { - // 如果在同一个Process下,不需要通过Socket发送了,直接通过Process下转发。 - var processSession = Session.CreateInnerSession(Scene); - _processSessionInfos.Add(sceneId, new ProcessSessionInfo(processSession, null)); - return processSession; - } - - if (!SceneConfigData.Instance.TryGet(sceneId, out var sceneConfig)) - { - throw new Exception($"The scene with sceneId {sceneId} was not found in the configuration file"); - } - - if (!ProcessConfigData.Instance.TryGet(sceneConfig.ProcessConfigId, out var processConfig)) - { - throw new Exception($"The process with processId {sceneConfig.ProcessConfigId} was not found in the configuration file"); - } - - if (!MachineConfigData.Instance.TryGet(processConfig.MachineId, out var machineConfig)) - { - throw new Exception($"The machine with machineId {processConfig.MachineId} was not found in the configuration file"); - } - - var remoteAddress = $"{machineConfig.InnerBindIP}:{sceneConfig.InnerPort}"; - var client = NetworkProtocolFactory.CreateClient(Scene, ProcessDefine.InnerNetwork, NetworkTarget.Inner); - var session = client.Connect(remoteAddress, null, () => - { - Log.Error($"Unable to connect to the target server sourceServerId:{Scene.Process.Id} targetServerId:{sceneConfig.ProcessConfigId}"); - }, null, false); - _processSessionInfos.Add(sceneId, new ProcessSessionInfo(session, client)); - return session; - } -#endif - #endregion - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/SceneRuntimeMode.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/SceneRuntimeMode.cs deleted file mode 100644 index 60dbc85..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/SceneRuntimeMode.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Fantasy -{ - /// - /// Scene的运行类型 - /// - public class SceneRuntimeMode - { - /// - /// Scene在主线程中运行. - /// - public const string MainThread = "MainThread"; - /// - /// Scene在一个独立的线程中运行. - /// - public const string MultiThread = "MultiThread"; - /// - /// Scene在一个根据当前CPU核心数创建的线程池中运行. - /// - public const string ThreadPool = "ThreadPool"; - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/SceneRuntimeType.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/SceneRuntimeType.cs deleted file mode 100644 index 664107f..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/SceneRuntimeType.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Fantasy -{ - /// - /// 代表一个Scene的类型 - /// - public enum SceneRuntimeType - { - /// - /// 默认 - /// - None = 0, - /// - /// 代表一个普通的Scene,一个普通的Scene肯定是是Root的 - /// - Root = 1, - /// - /// 代表一个子场景,子场景肯定是有父场景的 - /// - SubScene = 2, - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/ISceneScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/ISceneScheduler.cs deleted file mode 100644 index c04cc30..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/ISceneScheduler.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Fantasy -{ - internal interface ISceneScheduler : IDisposable - { - void Add(Scene scene); - void Remove(Scene scene); - void Update(); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/MainScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/MainScheduler.cs deleted file mode 100644 index 692def0..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/MainScheduler.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System.Collections.Generic; -#if FANTASY_UNITY || FANTASY_NET || !FANTASY_WEBGL -using System.Threading; -#endif -#if FANTASY_NET -using Fantasy.Platform.Net; -#endif -namespace Fantasy -{ - internal sealed class MainScheduler : ISceneScheduler - { - private readonly Queue _queue = new Queue(); - public readonly ThreadSynchronizationContext ThreadSynchronizationContext; - - public MainScheduler() - { - ThreadSynchronizationContext = new ThreadSynchronizationContext(); -#if !FANTASY_WEBGL - SynchronizationContext.SetSynchronizationContext(ThreadSynchronizationContext); -#endif - } - public void Dispose() - { - _queue.Clear(); - } - - public void Add(Scene scene) - { - ThreadSynchronizationContext.Post(() => - { - if (scene.IsDisposed) - { - return; - } - - _queue.Enqueue(scene); - }); - } - - public void Remove(Scene scene) - { - ThreadSynchronizationContext.Post(() => - { - if (scene.IsDisposed) - { - return; - } - - var initialCount = _queue.Count; - for (var i = 0; i < initialCount; i++) - { - var currentScene = _queue.Dequeue(); - if (currentScene != scene) - { - _queue.Enqueue(currentScene); - } - } - }); - } - - public void Update() - { - ThreadSynchronizationContext.Update(); - var initialCount = _queue.Count; - - while (initialCount-- > 0) - { - if(!_queue.TryDequeue(out var scene)) - { - continue; - } - - if (scene.IsDisposed) - { - continue; - } - - scene.Update(); - _queue.Enqueue(scene); - } - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/MultiThreadScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/MultiThreadScheduler.cs deleted file mode 100644 index 28f2d42..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/MultiThreadScheduler.cs +++ /dev/null @@ -1,103 +0,0 @@ -#if !FANTASY_WEBGL || !FANTASY_SINGLETHREAD -using System; -using System.Collections.Concurrent; -using System.Threading; -namespace Fantasy -{ - internal struct MultiThreadStruct : IDisposable - { - public readonly Thread Thread; - public readonly CancellationTokenSource Cts; - - public MultiThreadStruct(Thread thread, CancellationTokenSource cts) - { - Thread = thread; - Cts = cts; - } - - public void Dispose() - { - Cts.Cancel(); - if (Thread.IsAlive) - { - Thread.Join(); - } - Cts.Dispose(); - } - } - - internal sealed class MultiThreadScheduler : ISceneScheduler - { - private bool _isDisposed; - private readonly ConcurrentDictionary _threads = new ConcurrentDictionary(); - public int ThreadCount => _threads.Count; - - public void Dispose() - { - if (_isDisposed) - { - return; - } - - _isDisposed = true; - - foreach (var (_, multiThreadStruct) in _threads.ToArray()) - { - multiThreadStruct.Dispose(); - } - - _threads.Clear(); - } - - public void Add(Scene scene) - { - var cts = new CancellationTokenSource(); - var thread = new Thread(() => Loop(scene, cts.Token)); - _threads.TryAdd(scene.RuntimeId, new MultiThreadStruct(thread, cts)); - thread.Start(); - } - - public void Remove(Scene scene) - { - if (_threads.TryRemove(scene.RuntimeId, out var multiThreadStruct)) - { - multiThreadStruct.Dispose(); - } - } - - public void Update() - { - throw new NotImplementedException(); - } - - private void Loop(Scene scene, CancellationToken cancellationToken) - { - var sceneThreadSynchronizationContext = scene.ThreadSynchronizationContext; - SynchronizationContext.SetSynchronizationContext(sceneThreadSynchronizationContext); - - while (!cancellationToken.IsCancellationRequested) - { - try - { - if (scene.IsDisposed) - { - Remove(scene); - return; - } - - sceneThreadSynchronizationContext.Update(); - scene.Update(); - } - catch (Exception e) - { - Log.Error($"Error in MultiThreadScheduler loop: {e.Message}"); - } - finally - { - Thread.Sleep(1); - } - } - } - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/ThreadPoolScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/ThreadPoolScheduler.cs deleted file mode 100644 index 9f5a44c..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/ThreadPoolScheduler.cs +++ /dev/null @@ -1,140 +0,0 @@ -#if !FANTASY_WEBGL || !FANTASY_SINGLETHREAD -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8604 // Possible null reference argument. -namespace Fantasy -{ - internal sealed class ThreadPoolScheduler : ISceneScheduler - { - private bool _isDisposed; - private readonly List _threads; - private readonly ConcurrentBag _queue = new ConcurrentBag(); - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - public ThreadPoolScheduler() - { - // 最大线程数、避免线程过多发生的资源抢占问题。 - // 但如果使用了MultiThreadScheduler,那么这里的线程数就算是设置了也有可能导致线程过多的问题。 - // 线程过多看每个线程的抢占情况,如果抢占资源占用不是很大也没什么大问题。如果过大的情况,就会有性能问题。 - // 所以根据情况来使用不同的调度器。 - var maxThreadCount = Environment.ProcessorCount; - _threads = new List(maxThreadCount); - - for (var i = 0; i < maxThreadCount; ++i) - { - Thread thread = new(() => Loop(_cancellationTokenSource.Token)) - { - IsBackground = true - }; - _threads.Add(thread); - thread.Start(); - } - } - - public void Dispose() - { - if (_isDisposed) - { - return; - } - - _isDisposed = true; - _cancellationTokenSource.Cancel(); - - foreach (var thread in _threads) - { - if (thread.IsAlive) - { - thread.Join(); - } - } - - _cancellationTokenSource.Dispose(); - _threads.Clear(); - } - - public void Add(Scene scene) - { - if (_isDisposed) - { - return; - } - - _queue.Add(scene); - } - - public void Remove(Scene scene) - { - if (_isDisposed) - { - return; - } - - var newQueue = new Queue(); - - while (!_queue.IsEmpty) - { - if (_queue.TryTake(out var currentScene)) - { - if (currentScene != scene) - { - newQueue.Enqueue(currentScene); - } - } - } - - while (newQueue.TryDequeue(out var newScene)) - { - _queue.Add(newScene); - } - } - - public void Update() - { - throw new NotImplementedException(); - } - - private void Loop(CancellationToken cancellationToken) - { - while (!cancellationToken.IsCancellationRequested) - { - if (_queue.TryTake(out var scene)) - { - if (scene == null || scene.IsDisposed) - { - continue; - } - - var sceneThreadSynchronizationContext = scene.ThreadSynchronizationContext; - SynchronizationContext.SetSynchronizationContext(sceneThreadSynchronizationContext); - - try - { - sceneThreadSynchronizationContext.Update(); - scene.Update(); - } - catch (Exception e) - { - Log.Error($"Error in ThreadPoolScheduler scene: {e.Message}"); - } - finally - { - SynchronizationContext.SetSynchronizationContext(null); - } - - _queue.Add(scene); - Thread.Sleep(1); - } - else - { - // 当队列为空的时候、避免无效循环消耗CPU。 - Thread.Sleep(10); - } - } - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/ThreadScheduler.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/ThreadScheduler.cs deleted file mode 100644 index 5bd0dea..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/Scheduler/ThreadScheduler.cs +++ /dev/null @@ -1,66 +0,0 @@ -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy -{ - /// - /// 线程调度器 - /// - internal static class ThreadScheduler - { - /// - /// 主线程调度器 - /// - public static MainScheduler MainScheduler { get; private set; } - /// - /// 多线程调度器,根据当前CPU核心数量创建的固定线程。 - /// - public static ISceneScheduler MultiThreadScheduler { get; private set; } - /// - /// 线程池调度器 - /// - public static ISceneScheduler ThreadPoolScheduler { get; private set; } - - static ThreadScheduler() - { - MainScheduler = new MainScheduler(); - } - - internal static void Update() - { - MainScheduler.Update(); - } - - internal static void AddMainScheduler(Scene scene) - { - MainScheduler.Add(scene); - } - - internal static void AddToMultiThreadScheduler(Scene scene) - { - if (MultiThreadScheduler == null) - { -#if FANTASY_SINGLETHREAD || FANTASY_WEBGL - MultiThreadScheduler = MainScheduler; -#else - MultiThreadScheduler = new MultiThreadScheduler(); -#endif - } - - MultiThreadScheduler.Add(scene); - } - - internal static void AddToThreadPoolScheduler(Scene scene) - { - if (ThreadPoolScheduler == null) - { -#if FANTASY_SINGLETHREAD || FANTASY_WEBGL - ThreadPoolScheduler = MainScheduler; -#else - ThreadPoolScheduler = new ThreadPoolScheduler(); -#endif - } - - ThreadPoolScheduler.Add(scene); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Scene/SubScene.cs b/Fantasy/Fantays.Console/Runtime/Core/Scene/SubScene.cs deleted file mode 100644 index 438b8ba..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Scene/SubScene.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Fantasy.Entitas; -using Fantasy.Network; -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - -namespace Fantasy -{ - /// - /// 代表一个Scene下的子Scene - /// - public sealed partial class SubScene : Scene - { - /// - /// 子Scene的根Scene - /// - public Scene RootScene { get; internal set; } - /// - /// 存储当前Scene下管理的实体。 - /// - private readonly Dictionary _entities = new Dictionary(); - - internal void Initialize(Scene rootScene) - { - EntityPool = rootScene.EntityPool; - EntityListPool = rootScene.EntityListPool; - EntitySortedDictionaryPool = rootScene.EntitySortedDictionaryPool; - SceneUpdate = rootScene.SceneUpdate; - TimerComponent = rootScene.TimerComponent; - EventComponent = rootScene.EventComponent; - EntityComponent = rootScene.EntityComponent; - MessagePoolComponent = rootScene.MessagePoolComponent; - CoroutineLockComponent = rootScene.CoroutineLockComponent; - MessageDispatcherComponent = rootScene.MessageDispatcherComponent; - #if FANTASY_NET - NetworkMessagingComponent = rootScene.NetworkMessagingComponent; - SingleCollectionComponent = rootScene.SingleCollectionComponent; - TerminusComponent = rootScene.TerminusComponent; - #endif - ThreadSynchronizationContext = rootScene.ThreadSynchronizationContext; - } - - /// - /// 当子Scene销毁时执行 - /// - public override void Dispose() - { - if (IsDisposed) - { - return; - } - - ThreadSynchronizationContext.Post(() => - { - if (IsDisposed) - { - return; - } - - foreach (var (runtimeId, entity) in _entities.ToList()) - { - if (runtimeId != entity.RuntimeId) - { - continue; - } - entity.Dispose(); - } - - _entities.Clear(); - base.Dispose(); - }); - } - - /// - /// 添加一个实体到当前Scene下 - /// - /// 实体实例 - public override void AddEntity(Entity entity) - { - _entities.Add(entity.RuntimeId, entity); - RootScene.AddEntity(entity); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 返回的实体 - public override Entity GetEntity(long runTimeId) - { - return _entities.GetValueOrDefault(runTimeId); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 实体实例 - /// 返回一个bool值来提示是否查找到这个实体 - public override bool TryGetEntity(long runTimeId, out Entity entity) - { - return _entities.TryGetValue(runTimeId, out entity); - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 要查询实体的泛型类型 - /// 返回的实体 - public override T GetEntity(long runTimeId) - { - return _entities.TryGetValue(runTimeId, out var entity) ? (T)entity : null; - } - - /// - /// 根据RunTimeId查询一个实体 - /// - /// 实体的RunTimeId - /// 实体实例 - /// 要查询实体的泛型类型 - /// 返回一个bool值来提示是否查找到这个实体 - public override bool TryGetEntity(long runTimeId, out T entity) - { - if (_entities.TryGetValue(runTimeId, out var getEntity)) - { - entity = (T)getEntity; - return true; - } - - entity = null; - return false; - } - - /// - /// 删除一个实体,仅是删除不会指定实体的销毁方法 - /// - /// 实体的RunTimeId - /// 返回一个bool值来提示是否删除了这个实体 - public override bool RemoveEntity(long runTimeId) - { - return _entities.Remove(runTimeId) && RootScene.RemoveEntity(runTimeId); - } - - /// - /// 删除一个实体,仅是删除不会指定实体的销毁方法 - /// - /// 实体实例 - /// 返回一个bool值来提示是否删除了这个实体 - public override bool RemoveEntity(Entity entity) - { - return RemoveEntity(entity.RuntimeId); - } - -#if FANTASY_NET - /// - /// 根据runTimeId获得Session - /// - /// - /// - /// - public override Session GetSession(long runTimeId) - { - return RootScene.GetSession(runTimeId); - } - #endif - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/BsonPackHelperNet.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/BsonPackHelperNet.cs deleted file mode 100644 index bb5293b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/BsonPackHelperNet.cs +++ /dev/null @@ -1,311 +0,0 @@ -#if FANTASY_NET -using System.Buffers; -using System.Collections; -using System.ComponentModel; -using System.Reflection; -using Fantasy.Assembly; -using Fantasy.Entitas; -using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Conventions; -using MongoDB.Bson.Serialization.Serializers; -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. - -namespace Fantasy.Serialize -{ - /// - /// BSON帮助方法 - /// - public class BsonPackHelper : ISerialize - { - /// - /// 序列化器的名字 - /// - public string SerializeName { get; } = "Bson"; - - /// - /// 构造函数 - /// - public BsonPackHelper() - { - // 清除掉注册过的LookupClassMap。 - - var classMapRegistryField = typeof(BsonClassMap).GetField("__classMaps", BindingFlags.Static | BindingFlags.NonPublic); - - if (classMapRegistryField != null) - { - ((Dictionary)classMapRegistryField.GetValue(null)).Clear(); - } - - // 清除掉注册过的ConventionRegistry。 - - var registryField = typeof(ConventionRegistry).GetField("_lookup", BindingFlags.Static | BindingFlags.NonPublic); - - if (registryField != null) - { - var registry = registryField.GetValue(null); - var dictionaryField = registry.GetType().GetField("_conventions", BindingFlags.Instance | BindingFlags.NonPublic); - if (dictionaryField != null) - { - ((IDictionary)dictionaryField.GetValue(registry)).Clear(); - } - } - - // 初始化ConventionRegistry、注册IgnoreExtraElements。 - - ConventionRegistry.Register("IgnoreExtraElements", new ConventionPack { new IgnoreExtraElementsConvention(true) }, type => true); - - // 注册一个自定义的序列化器。 - - // BsonSerializer.TryRegisterSerializer(typeof(float2), new StructBsonSerialize()); - // BsonSerializer.TryRegisterSerializer(typeof(float3), new StructBsonSerialize()); - // BsonSerializer.TryRegisterSerializer(typeof(float4), new StructBsonSerialize()); - // BsonSerializer.TryRegisterSerializer(typeof(quaternion), new StructBsonSerialize()); - BsonSerializer.RegisterSerializer(new ObjectSerializer(x => true)); - - // 注册LookupClassMap。 - - foreach (var type in AssemblySystem.ForEach()) - { - if (type.IsInterface || type.IsAbstract || type.IsGenericType || !typeof(Entity).IsAssignableFrom(type)) - { - continue; - } - - BsonClassMap.LookupClassMap(type); - } - } - - /// - /// 反序列化 - /// - /// - /// - /// - public T Deserialize(byte[] bytes) - { - var @object = BsonSerializer.Deserialize(bytes); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - public T Deserialize(MemoryStreamBuffer buffer) - { - var @object = BsonSerializer.Deserialize(buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - public object Deserialize(Type type, byte[] bytes) - { - var @object = BsonSerializer.Deserialize(bytes, type); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - public object Deserialize(Type type, MemoryStreamBuffer buffer) - { - var @object = BsonSerializer.Deserialize(buffer, type); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - public unsafe T Deserialize(byte[] bytes, int index, int count) - { - T @object; - - fixed (byte* ptr = &bytes[index]) - { - using var stream = new UnmanagedMemoryStream(ptr, count); - @object = BsonSerializer.Deserialize(stream); - } - - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - public unsafe object Deserialize(Type type, byte[] bytes, int index, int count) - { - object @object; - - fixed (byte* ptr = &bytes[index]) - { - using var stream = new UnmanagedMemoryStream(ptr, count); - @object = BsonSerializer.Deserialize(stream, type); - } - - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - - /// - /// 序列化 - /// - /// - /// - /// - public void Serialize(T @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using IBsonWriter bsonWriter = - new BsonBinaryWriter((MemoryStream)buffer, BsonBinaryWriterSettings.Defaults); - BsonSerializer.Serialize(bsonWriter, @object); - } - - /// - /// 序列化 - /// - /// - /// - public void Serialize(object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using IBsonWriter bsonWriter = - new BsonBinaryWriter((MemoryStream)buffer, BsonBinaryWriterSettings.Defaults); - BsonSerializer.Serialize(bsonWriter, @object.GetType(), @object); - } - - /// - /// 序列化 - /// - /// - /// - /// - public void Serialize(Type type, object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using IBsonWriter bsonWriter = - new BsonBinaryWriter((MemoryStream)buffer, BsonBinaryWriterSettings.Defaults); - BsonSerializer.Serialize(bsonWriter, type, @object); - } - - /// - /// 序列化并返回的长度 - /// - /// - /// - /// - /// - public int SerializeAndReturnLength(Type type, object @object, MemoryStreamBuffer buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using IBsonWriter bsonWriter = new BsonBinaryWriter(buffer, BsonBinaryWriterSettings.Defaults); - BsonSerializer.Serialize(bsonWriter, type, @object); - return (int)buffer.Length; - } - - /// - /// 序列化 - /// - /// - /// - public static byte[] Serialize(object @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - return @object.ToBson(@object.GetType()); - } - - /// - /// 序列化 - /// - /// - /// - /// - public static byte[] Serialize(T @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - return @object.ToBson(); - } - - /// - /// 克隆 - /// - /// - /// - /// - public T Clone(T t) - { - return Deserialize(Serialize(t)); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/BsonPackHelperUnity.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/BsonPackHelperUnity.cs deleted file mode 100644 index df44fcb..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/BsonPackHelperUnity.cs +++ /dev/null @@ -1,60 +0,0 @@ -#if FANTASY_UNITY -using System; -using System.Buffers; -namespace Fantasy.Serialize -{ - public class BsonPackHelper : ISerialize - { - public string SerializeName { get; } = "Bson"; - public T Deserialize(byte[] bytes) - { - throw new NotImplementedException(); - } - - public T Deserialize(MemoryStreamBuffer buffer) - { - throw new NotImplementedException(); - } - - public object Deserialize(Type type, byte[] bytes) - { - throw new NotImplementedException(); - } - - public object Deserialize(Type type, MemoryStreamBuffer buffer) - { - throw new NotImplementedException(); - } - - public T Deserialize(byte[] bytes, int index, int count) - { - throw new NotImplementedException(); - } - - public object Deserialize(Type type, byte[] bytes, int index, int count) - { - throw new NotImplementedException(); - } - - public void Serialize(T @object, IBufferWriter buffer) - { - throw new NotImplementedException(); - } - - public void Serialize(object @object, IBufferWriter buffer) - { - throw new NotImplementedException(); - } - - public void Serialize(Type type, object @object, IBufferWriter buffer) - { - throw new NotImplementedException(); - } - - public T Clone(T t) - { - throw new NotImplementedException(); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/StructBsonSerialize.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/StructBsonSerialize.cs deleted file mode 100644 index 15d8663..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/StructBsonSerialize.cs +++ /dev/null @@ -1,65 +0,0 @@ -#if FANTASY_NET -using System.Reflection; -using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Serializers; - -namespace Fantasy.Serialize; - -/// -/// 提供对结构体类型进行 BSON 序列化和反序列化的辅助类。 -/// -/// 要序列化和反序列化的结构体类型。 -public class StructBsonSerialize : StructSerializerBase where TValue : struct -{ - /// - /// 将结构体对象序列化为 BSON 数据。 - /// - /// 序列化上下文。 - /// 序列化参数。 - /// 要序列化的结构体对象。 - public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TValue value) - { - var nominalType = args.NominalType; - var bsonWriter = context.Writer; - bsonWriter.WriteStartDocument(); - var fields = nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - foreach (var field in fields) - { - bsonWriter.WriteName(field.Name); - BsonSerializer.Serialize(bsonWriter, field.FieldType, field.GetValue(value)); - } - bsonWriter.WriteEndDocument(); - } - - /// - /// 将 BSON 数据反序列化为结构体对象。 - /// - /// 反序列化上下文。 - /// 反序列化参数。 - /// 反序列化得到的结构体对象。 - public override TValue Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) - { - //boxing is required for SetValue to work - object obj = new TValue(); - var actualType = args.NominalType; - var bsonReader = context.Reader; - bsonReader.ReadStartDocument(); - while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) - { - var name = bsonReader.ReadName(Utf8NameDecoder.Instance); - - var field = actualType.GetField(name, - BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - if (field != null) - { - var value = BsonSerializer.Deserialize(bsonReader, field.FieldType); - field.SetValue(obj, value); - } - } - bsonReader.ReadEndDocument(); - return (TValue) obj; - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/SupportInitializeChecker.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/SupportInitializeChecker.cs deleted file mode 100644 index 82c6829..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/BsonPack/SupportInitializeChecker.cs +++ /dev/null @@ -1,17 +0,0 @@ -#if FANTASY_NET -using System.ComponentModel; -using Fantasy.Entitas; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Serialize; - -public static class SupportInitializeChecker where T : Entity -{ - public static bool IsSupported { get; } - - static SupportInitializeChecker() - { - IsSupported = typeof(ISupportInitialize).IsAssignableFrom(typeof(T)); - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/Interface/ASerialize.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/Interface/ASerialize.cs deleted file mode 100644 index 7487b86..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/Interface/ASerialize.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.ComponentModel; -using System.Runtime.Serialization; -using Fantasy.Pool; -#if FANTASY_NET || FANTASY_UNITY || FANTASY_CONSOLE -using MongoDB.Bson.Serialization.Attributes; -#endif -using Newtonsoft.Json; -using ProtoBuf; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Serialize -{ - public abstract class ASerialize : ISupportInitialize, IDisposable - { - public virtual void Dispose() { } - public virtual void BeginInit() { } - public virtual void EndInit() { } - public virtual void AfterDeserialization() => EndInit(); - } - - public abstract class AMessage : ASerialize, IPool - { -#if FANTASY_NET || FANTASY_UNITY || FANTASY_CONSOLE - [BsonIgnore] - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - private Scene _scene; - protected Scene GetScene() - { - return _scene; - } - - public void SetScene(Scene scene) - { - _scene = scene; - } -#endif -#if FANTASY_NET - [BsonIgnore] -#endif - [JsonIgnore] - [IgnoreDataMember] - [ProtoIgnore] - private bool _isPool; - - public bool IsPool() - { - return _isPool; - } - - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/Interface/ISerialize.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/Interface/ISerialize.cs deleted file mode 100644 index a3a9159..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/Interface/ISerialize.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Buffers; - -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Fantasy.Serialize -{ - public interface ISerialize - { - /// - /// 序列化器的名字,用于在协议里指定用什么协议序列化使用 - /// - string SerializeName { get; } - /// - /// 反序列化 - /// - /// - /// - /// - T Deserialize(byte[] bytes); - /// - /// 反序列化 - /// - /// - /// - /// - T Deserialize(MemoryStreamBuffer buffer); - /// - /// 反序列化 - /// - /// - /// - /// - object Deserialize(Type type, byte[] bytes); - /// - /// 反序列化 - /// - /// - /// - /// - object Deserialize(Type type, MemoryStreamBuffer buffer); - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - T Deserialize(byte[] bytes, int index, int count); - /// - /// 反序列化 - /// - /// - /// - /// - /// - /// - object Deserialize(Type type, byte[] bytes, int index, int count); - /// - /// 序列化 - /// - /// - /// - /// - void Serialize(T @object, IBufferWriter buffer); - /// - /// 序列化 - /// - /// - /// - void Serialize(object @object, IBufferWriter buffer); - /// - /// 序列化 - /// - /// - /// - /// - void Serialize(Type type, object @object, IBufferWriter buffer); - /// - /// 克隆 - /// - /// - /// - /// - T Clone(T t); - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/MemoryStreamBuffer.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/MemoryStreamBuffer.cs deleted file mode 100644 index 23919b4..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/MemoryStreamBuffer.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - -namespace Fantasy.Serialize -{ - public enum MemoryStreamBufferSource - { - None = 0, - Pack = 1, - UnPack = 2, - } - - public sealed class MemoryStreamBuffer : MemoryStream, IBufferWriter - { - public MemoryStreamBufferSource MemoryStreamBufferSource; - public MemoryStreamBuffer() { } - - public MemoryStreamBuffer(MemoryStreamBufferSource memoryStreamBufferSource, int capacity) : base(capacity) - { - MemoryStreamBufferSource = memoryStreamBufferSource; - } - public MemoryStreamBuffer(byte[] buffer): base(buffer) { } - - public void Advance(int count) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), count, "The value of 'count' cannot be negative."); - } - - var newLength = Position + count; - - if (newLength != Length) - { - SetLength(newLength); - } - - Position = newLength; - } - - public Memory GetMemory(int sizeHint = 0) - { - if (sizeHint < 0) - { - throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint, "The value of 'count' cannot be negative."); - } - - if (Length - Position <= sizeHint) - { - SetLength(Position + sizeHint); - } - - return new Memory(GetBuffer(), (int)Position, (int)(Length - Position)); - } - - public Span GetSpan(int sizeHint = 0) - { - if (sizeHint < 0) - { - throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint, "The value of 'count' cannot be negative."); - } - - if (Length - Position <= sizeHint) - { - SetLength(Position + sizeHint); - } - - return new Span(GetBuffer(), (int)Position, (int)(Length - Position)); - } - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/ProtoBufPackHelper/IProto.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/ProtoBufPackHelper/IProto.cs deleted file mode 100644 index 2267dd2..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/ProtoBufPackHelper/IProto.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Fantasy.Serialize -{ - /// - /// 代表是一个ProtoBuf协议 - /// - public interface IProto - { - } -} \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperNet.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperNet.cs deleted file mode 100644 index dc3886b..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperNet.cs +++ /dev/null @@ -1,223 +0,0 @@ -#if FANTASY_NET || FANTASY_EXPORTER -using System.Buffers; -using Fantasy.Assembly; -using ProtoBuf.Meta; -namespace Fantasy.Serialize -{ - /// - /// ProtoBufP帮助类,Net平台使用 - /// - public sealed class ProtoBufPackHelper : ISerialize - { - /// - /// 序列化器的名字 - /// - public string SerializeName { get; } = "ProtoBuf"; - - /// - /// 构造函数 - /// - public ProtoBufPackHelper () - { -#if FANTASY_NET - RuntimeTypeModel.Default.AutoAddMissingTypes = true; - RuntimeTypeModel.Default.AllowParseableTypes = true; - RuntimeTypeModel.Default.AutoAddMissingTypes = true; - RuntimeTypeModel.Default.AutoCompile = true; - RuntimeTypeModel.Default.UseImplicitZeroDefaults = true; - RuntimeTypeModel.Default.InferTagFromNameDefault = true; - - foreach (var type in AssemblySystem.ForEach(typeof(IProto))) - { - RuntimeTypeModel.Default.Add(type, true); - } - - RuntimeTypeModel.Default.CompileInPlace(); -#endif - } - - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public T Deserialize(byte[] bytes) - { - var memory = new ReadOnlyMemory(bytes); - var @object = RuntimeTypeModel.Default.Deserialize(memory); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public T Deserialize(MemoryStreamBuffer buffer) - { - var @object = RuntimeTypeModel.Default.Deserialize(buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public object Deserialize(Type type, byte[] bytes) - { - var memory = new ReadOnlyMemory(bytes); - var @object = RuntimeTypeModel.Default.Deserialize(type, memory); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public object Deserialize(Type type, MemoryStreamBuffer buffer) - { - var @object = RuntimeTypeModel.Default.Deserialize(type, buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - /// - /// - public T Deserialize(byte[] bytes, int index, int count) - { - var memory = new ReadOnlyMemory(bytes, index, count); - var @object = RuntimeTypeModel.Default.Deserialize(memory); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - /// - /// - public object Deserialize(Type type, byte[] bytes, int index, int count) - { - var memory = new ReadOnlyMemory(bytes, index, count); - var @object = RuntimeTypeModel.Default.Deserialize(type, memory); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - /// - public void Serialize(T @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize(buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - public void Serialize(object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize(buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - /// - public void Serialize(Type type, object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize(buffer, @object); - } - internal byte[] Serialize(object @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using (var buffer = new MemoryStream()) - { - RuntimeTypeModel.Default.Serialize(buffer, @object); - return buffer.ToArray(); - } - } - private byte[] Serialize(T @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using (var buffer = new MemoryStream()) - { - RuntimeTypeModel.Default.Serialize(buffer, @object); - return buffer.ToArray(); - } - } - /// - /// 克隆 - /// - /// - /// - /// - public T Clone(T t) - { - return Deserialize(Serialize(t)); - } - } -} -#endif diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperUnity.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperUnity.cs deleted file mode 100644 index 6df5903..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/ProtoBufPackHelper/ProtoBufPackHelperUnity.cs +++ /dev/null @@ -1,202 +0,0 @@ -#if FANTASY_UNITY || FANTASY_CONSOLE -using System; -using System.Buffers; -using System.IO; -using Fantasy.Assembly; -using ProtoBuf; -using ProtoBuf.Meta; - -namespace Fantasy.Serialize -{ - /// - /// ProtoBufP帮助类,Unity平台使用 - /// - public sealed class ProtoBufPackHelper : ISerialize - { - /// - /// 序列化器的名字 - /// - public string SerializeName { get; } = "ProtoBuf"; - - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public unsafe T Deserialize(byte[] bytes) - { - fixed (byte* ptr = bytes) - { - using var stream = new UnmanagedMemoryStream(ptr, bytes.Length); - var @object = ProtoBuf.Serializer.Deserialize(stream); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public T Deserialize(MemoryStreamBuffer buffer) - { - var @object = ProtoBuf.Serializer.Deserialize(buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public unsafe object Deserialize(Type type, byte[] bytes) - { - fixed (byte* ptr = bytes) - { - using var stream = new UnmanagedMemoryStream(ptr, bytes.Length); - var @object = ProtoBuf.Serializer.Deserialize(type, stream); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - public object Deserialize(Type type, MemoryStreamBuffer buffer) - { - var @object = ProtoBuf.Serializer.Deserialize(type, buffer); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - - return @object; - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - /// - /// - public unsafe T Deserialize(byte[] bytes, int index, int count) - { - fixed (byte* ptr = &bytes[index]) - { - using var stream = new UnmanagedMemoryStream(ptr, count); - var @object = ProtoBuf.Serializer.Deserialize(stream); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - } - /// - /// 使用ProtoBuf反序列化数据到实例 - /// - /// - /// - /// - /// - /// - public unsafe object Deserialize(Type type, byte[] bytes, int index, int count) - { - fixed (byte* ptr = &bytes[index]) - { - using var stream = new UnmanagedMemoryStream(ptr, count); - var @object = ProtoBuf.Serializer.Deserialize(type, stream); - if (@object is ASerialize aSerialize) - { - aSerialize.AfterDeserialization(); - } - return @object; - } - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - /// - public void Serialize(T @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize((MemoryStream)buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - public void Serialize(object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize((MemoryStream)buffer, @object); - } - /// - /// 使用ProtoBuf序列化某一个实例到IBufferWriter中 - /// - /// - /// - /// - public void Serialize(Type type, object @object, IBufferWriter buffer) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - RuntimeTypeModel.Default.Serialize((MemoryStream)buffer, @object); - } - private byte[] Serialize(T @object) - { - if (@object is ASerialize aSerialize) - { - aSerialize.BeginInit(); - } - - using (var buffer = new MemoryStream()) - { - RuntimeTypeModel.Default.Serialize(buffer, @object); - return buffer.ToArray(); - } - } - /// - /// 克隆 - /// - /// - /// - /// - public T Clone(T t) - { - return Deserialize(Serialize(t)); - } - } -} -#endif \ No newline at end of file diff --git a/Fantasy/Fantays.Console/Runtime/Core/Serialize/SerializerManager.cs b/Fantasy/Fantays.Console/Runtime/Core/Serialize/SerializerManager.cs deleted file mode 100644 index 2272074..0000000 --- a/Fantasy/Fantays.Console/Runtime/Core/Serialize/SerializerManager.cs +++ /dev/null @@ -1,152 +0,0 @@ -using System; -using System.Collections.Generic; -using Fantasy.Assembly; -using Fantasy.Helper; -#if !FANTASY_EXPORTER -using Fantasy.Network; -#endif -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -namespace Fantasy.Serialize -{ - /// - /// 框架内置的序列化器类型 - /// - public static class FantasySerializerType - { - /// - /// ProtoBuf在SerializerManager的数组下标 - /// - public const int ProtoBuf = 0; - /// - /// Bson在SerializerManager的数组下标 - /// - public const int Bson = 1; - } - - /// - /// 管理序列化静态方法,主要是优化网络协议时使用。 - /// - public static class SerializerManager - { - private static ISerialize[] _serializers; - private static bool _isInitialized = false; - -#if FANTASY_NET || FANTASY_UNITY - /// - /// 初始化方法 - /// - public static void Initialize() - { - if (_isInitialized) - { - return; - } - - try - { - var sort = new SortedList(); - - foreach (var serializerType in AssemblySystem.ForEach(typeof(ISerialize))) - { - var serializer = (ISerialize)Activator.CreateInstance(serializerType); - var computeHash64 = HashCodeHelper.ComputeHash64(serializer.SerializeName); - sort.Add(computeHash64, serializer); - } - - var index = 1; - _serializers = new ISerialize[sort.Count]; - - foreach (var (_, serialize) in sort) - { - var serializerIndex = 0; - - switch (serialize) - { - case ProtoBufPackHelper: - { - serializerIndex = FantasySerializerType.ProtoBuf; - break; - } - case BsonPackHelper: - { - serializerIndex = FantasySerializerType.Bson; - break; - } - default: - { - serializerIndex = ++index; - break; - } - } - - _serializers[serializerIndex] = serialize; - } - - _isInitialized = true; - Log.Info($"初始化序列化器成功,数量为:{_serializers.Length}"); - } - catch (Exception e) - { - Log.Error(e); - Dispose(); - } - } -#else - /// - /// 初始化方法 - /// - public static void Initialize() - { - if (_isInitialized) - { - return; - } - - _serializers = new ISerialize[1]; - _serializers[0] = new ProtoBufPackHelper(); - } -#endif - - /// - /// 销毁方法 - /// - public static void Dispose() - { - _isInitialized = false; - Array.Clear(_serializers, 0, _serializers.Length); - } - - /// - /// 根据协议类型获取序列化器 - /// - /// - /// - public static ISerialize GetSerializer(uint opCodeProtocolType) - { - return _serializers[opCodeProtocolType]; - } - - /// - /// 获得一个序列化器 - /// - /// - /// - /// - public static bool TryGetSerializer(uint opCodeProtocolType, out ISerialize serializer) - { - if (opCodeProtocolType < _serializers.Length) - { - serializer = _serializers[opCodeProtocolType]; - return true; - } - - serializer = default; - return false; - } - } -} \ No newline at end of file diff --git a/Hotfix/Authentication/System/AuthenticationComponentSystem.cs b/Hotfix/Authentication/System/AuthenticationComponentSystem.cs index 436a6cd..270d40d 100644 --- a/Hotfix/Authentication/System/AuthenticationComponentSystem.cs +++ b/Hotfix/Authentication/System/AuthenticationComponentSystem.cs @@ -59,7 +59,7 @@ internal static class AuthenticationComponentSystem } var scene = self.Scene; - var worldDateBase = scene.World.DataBase; //DateBase + var worldDateBase = scene.World.Database; //DateBase var usernameHashCode = userName.GetHashCode(); using (var @lock = @@ -176,7 +176,7 @@ internal static class AuthenticationComponentSystem } // 2、数据库查询该账号是否存在 - var worldDateBase = scene.World.DataBase; + var worldDateBase = scene.World.Database; var isExist = await worldDateBase.Exist(d => d.Username == username); if (isExist) { @@ -239,7 +239,7 @@ internal static class AuthenticationComponentSystem using (var @lock = await scene.CoroutineLockComponent.Wait((int)LockType.AuthenticationRemoveLock, accountId)) { - var worldDateBase = scene.World.DataBase; + var worldDateBase = scene.World.Database; await worldDateBase.Remove(accountId); Log.Info($"Remove source:{source} accountId:{accountId}"); return 0; diff --git a/Hotfix/CustomSystem/IRunSystem.cs b/Hotfix/CustomSystem/IRunSystem.cs deleted file mode 100644 index 8c9fb69..0000000 --- a/Hotfix/CustomSystem/IRunSystem.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Fantasy.Entitas; -using Fantasy.Entitas.Interface; - -namespace Fantasy; - -// 这个是一个自定义系统类型,用于决定系统类型。 -// 也可以用枚举,看个人怎么使用了。 -public static class CustomSystemType -{ - public const int RunSystem = 1; -} - -// 这个是一个自定义系统,用于处理自定义事件。 -public abstract class RunSystem : CustomSystem where T : Entity -{ - /// - /// 自定义事件类型,用于决定事件的类型。 - /// - public override int CustomEventType => CustomSystemType.RunSystem; - - /// - /// 不知道为什么这样定义的,就照搬就可以了。 - /// - /// - protected abstract override void Custom(T self); - - /// - /// 不知道为什么这样定义的,就照搬就可以了。 - /// - /// - public override Type EntitiesType() => typeof(T); -} - -// 下面是一个测试自定义系统。 -// 首先定义一个组件用来测试自定义系统。 -public class TestCustomSystemComponent : Entity -{ -} - -// 现在给TestCustomSystemComponent组件添加一个自定义系统。 -// 现在添加的就是上面定义的RunSystem自定义系统。 -public class TestCustomSystemComponentRunSystem : RunSystem -{ - protected override void Custom(TestCustomSystemComponent self) - { - Log.Debug($"执行了TestCustomSystemComponentRunSystem"); - } -} -// 执行方法 -// 在任何实体下获得Scene下面的EntityComponent.CustomSystem方法。 -// 比如下面这个 -// 第一个参数是你要执行自定义系统的实体实例 -// 第二个参数是自定义系统类型 -// scene.EntityComponent.CustomSystem(testCustomSystemComponent, CustomSystemType.RunSystem); -// 你可以在OnCreateSceneEvent.cs的Handler方法里找到执行这个的例子。 \ No newline at end of file diff --git a/Hotfix/Game/Cache/System/PlayerBasicCacheManageComponentSystem.cs b/Hotfix/Game/Cache/System/PlayerBasicCacheManageComponentSystem.cs index b138f4c..9208e72 100644 --- a/Hotfix/Game/Cache/System/PlayerBasicCacheManageComponentSystem.cs +++ b/Hotfix/Game/Cache/System/PlayerBasicCacheManageComponentSystem.cs @@ -100,7 +100,7 @@ public static class PlayerBasicCacheManageComponentSystem var ret = new List(); //TODO:需要考虑如果数量过大是否需要分页 List players = - await manage.Scene.World.DataBase.QueryByPage(d => ids.Contains(d.Id), 1, ids.Count); + await manage.Scene.World.Database.QueryByPage(d => ids.Contains(d.Id), 1, ids.Count); foreach (var player in players) { var cache = manage.UpdateCache(player); diff --git a/Hotfix/Game/Item/PlayerItemContainerComponentSystem.cs b/Hotfix/Game/Item/PlayerItemContainerComponentSystem.cs index f31f1e4..4e94425 100644 --- a/Hotfix/Game/Item/PlayerItemContainerComponentSystem.cs +++ b/Hotfix/Game/Item/PlayerItemContainerComponentSystem.cs @@ -27,7 +27,7 @@ public static class PlayerItemContainerComponentSystem public static async FTask Save(this PlayerItemContainerComponent self) { - await self.Scene.World.DataBase.Save(self); + await self.Scene.World.Database.Save(self); } #endregion diff --git a/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs b/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs index f51a9da..6f18700 100644 --- a/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs +++ b/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs @@ -218,7 +218,7 @@ public static class PlayerManageComponentSystem { if (player.GetComponent() == null) { - var component = await player.Scene.World.DataBase.Query(player.Id, true); + var component = await player.Scene.World.Database.Query(player.Id, true); if (component == null) { //如果没有组件 diff --git a/Hotfix/Game/Player/Helper/PlayerHelper.cs b/Hotfix/Game/Player/Helper/PlayerHelper.cs index eb296ae..8ffff07 100644 --- a/Hotfix/Game/Player/Helper/PlayerHelper.cs +++ b/Hotfix/Game/Player/Helper/PlayerHelper.cs @@ -13,7 +13,7 @@ public static class PlayerHelper public static async FTask Save(this Player self) { //先立马保存,后续做缓存 - await self.Scene.World.DataBase.Save(self); + await self.Scene.World.Database.Save(self); } /// @@ -24,7 +24,7 @@ public static class PlayerHelper /// public static async FTask LoadDataBase(Scene scene, long accountId) { - var account = await scene.World.DataBase.First(d => d.Id == accountId); + var account = await scene.World.Database.First(d => d.Id == accountId); if (account == null) { return null; diff --git a/Hotfix/Game/Wallet/PlayerWalletComponentSystem.cs b/Hotfix/Game/Wallet/PlayerWalletComponentSystem.cs index de91049..fee3f9b 100644 --- a/Hotfix/Game/Wallet/PlayerWalletComponentSystem.cs +++ b/Hotfix/Game/Wallet/PlayerWalletComponentSystem.cs @@ -9,7 +9,7 @@ public static class PlayerWalletComponentSystem public static async FTask Save(this PlayerWalletComponent self) { - await self.Scene.World.DataBase.Save(self); + await self.Scene.World.Database.Save(self); } #endregion diff --git a/Hotfix/Hotfix.csproj b/Hotfix/Hotfix.csproj index ae3d4eb..e60aa11 100644 --- a/Hotfix/Hotfix.csproj +++ b/Hotfix/Hotfix.csproj @@ -1,24 +1,15 @@ - + - - enable - enable - default - net9.0 - + + net9.0 + Hotfix + latest + enable + enable + - - - - + + + - - - - - - - - - - + \ No newline at end of file diff --git a/Hotfix/OnCreateSceneEvent.cs b/Hotfix/OnCreateSceneEvent.cs index ff89e97..3188443 100644 --- a/Hotfix/OnCreateSceneEvent.cs +++ b/Hotfix/OnCreateSceneEvent.cs @@ -1,187 +1,224 @@ -using System.Diagnostics; using Fantasy; using Fantasy.Async; -using Fantasy.Entitas; using Fantasy.Event; -using Fantasy.Helper; -using Fantasy.Serialize; +using NB; +using NB.Authentication; +using NB.Chat; using NB.Game; +using NB.Gate; using NB.Map; -using NBF; -using ProtoBuf; -namespace NB; - -public sealed class SubSceneTestComponent : Entity -{ - public override void Dispose() - { - Log.Debug("销毁SubScene下的SubSceneTestComponent"); - base.Dispose(); - } -} +namespace NBF; public sealed class OnCreateSceneEvent : AsyncEventSystem { - private static long _addressableSceneRunTimeId; + private static long _addressableSceneRuntimeId; - /// - /// Handles the OnCreateScene event. - /// - /// The OnCreateScene object. - /// A task representing the asynchronous operation. protected override async FTask Handler(OnCreateScene self) { - // var epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; - // - // { - // var now = TimeHelper.Transition(new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc)); - // var epochThisYear = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000 - epoch1970; - // var time = (uint)((now - epochThisYear) / 1000); - // Log.Debug($"time = {time} now = {now} epochThisYear = {epochThisYear}"); - // } - // - // { - // var now = TimeHelper.Transition(new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc)); - // var epochThisYear = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000 - epoch1970; - // var time = (uint)((now - epochThisYear) / 1000); - // Log.Debug($"time = {time} now = {now} epochThisYear = {epochThisYear}"); - // } - var scene = self.Scene; + // 在这里执行你的初始化逻辑 + Log.Info($"Scene created: SceneType={scene.SceneType}, SceneId={scene.Id} SceneConfigId={scene.SceneConfigId}"); switch (scene.SceneType) { - case 6666: - { - var subSceneTestComponent = scene.AddComponent(); - Log.Debug("增加了SubSceneTestComponent"); - scene.EntityComponent.CustomSystem(subSceneTestComponent, CustomSystemType.RunSystem); - break; - } case SceneType.Addressable: { - // scene.AddComponent(); - _addressableSceneRunTimeId = scene.RuntimeId; + // 保存 Addressable 场景的 RuntimeId,供其他场景使用 + _addressableSceneRuntimeId = scene.RuntimeId; + await InitializeAddressableScene(scene); break; } - case SceneType.Map: + case SceneType.Authentication: { - Log.Debug($"Map Scene SceneRuntimeId:{scene.RuntimeId}"); - - var roomCode = RoomHelper.GenerateCode(scene.SceneConfigId, 1); - Log.Info($"测试 roomCode:{roomCode}"); - // uint serverId = 25255; - // for (int i = 1; i < 65535; i++) - // { - // var roomId = RoomHelper.GenerateCode(serverId, i); - // RoomHelper.ParseCode(roomId, out var pId, out var rId); - // Log.Info($"生成id测试,房间id={roomId} 原始服务id:{serverId} 原始房间id={i} 解析={pId} {rId}"); - // } - - break; - } - case SceneType.Social: - { - break; - } - case SceneType.Game: - { - var rod = RodConfig.Get(30001); - Log.Info("rod config id="+rod.Id); - // // Begins transaction - // using (var session = mongoClient.StartSession()) - // { - // session.StartTransaction(); - // try - // { - // // Creates sample data - // var book = new Book - // { - // Title = "Beloved", - // Author = "Toni Morrison", - // InStock = true - // }; - // var film = new Film - // { - // Title = "Star Wars", - // Director = "George Lucas", - // InStock = true - // }; - // // Inserts sample data - // books.InsertOne(session, book); - // films.InsertOne(session, film); - // // Commits our transaction - // session.CommitTransaction(); - // } - // catch (Exception e) - // { - // Console.WriteLine("Error writing to MongoDB: " + e.Message); - // return; - // } - // // Prints a success message if no error thrown - // Console.WriteLine("Successfully committed transaction!"); - // } - - // var client = self.Scene.World.DataBase; - - // List tasks = new List(); - // Stopwatch stopwatch = new Stopwatch(); - // stopwatch.Start(); - // for (int i = 0; i < 100; i++) - // { - // var accountId = scene.EntityIdFactory.Create; - // var account = PlayerFactory.Create(scene, accountId); - // - // account.Level = 99; - // account.NickName = $"测试号{i + 1}"; - // account.Country = "cn"; - // account.Exp = 999; - // account.Head = "xxx.png"; - // tasks.Add(account.Save()); - // } - // await FTask.WaitAll(tasks); - // // self.Scene.World.DataBase.InsertBatch() - // - // stopwatch.Stop(); - // Log.Info($"创建100个号入库耗时={stopwatch.ElapsedMilliseconds}ms"); - - + await InitializeAuthenticationScene(scene); break; } case SceneType.Gate: { - // var tasks = new List(2000); - // var session = scene.GetSession(_addressableSceneRunTimeId); - // var sceneNetworkMessagingComponent = scene.NetworkMessagingComponent; - // var g2ATestRequest = new G2A_TestRequest(); - // - // async FTask Call() - // { - // await sceneNetworkMessagingComponent.CallInnerRouteBySession(session,_addressableSceneRunTimeId,g2ATestRequest); - // } - // - // for (int i = 0; i < 100000000000; i++) - // { - // tasks.Clear(); - // for (int j = 0; j < tasks.Capacity; ++j) - // { - // tasks.Add(Call()); - // } - // await FTask.WaitAll(tasks); - // } - - // 执行自定义系统 - var testCustomSystemComponent = scene.AddComponent(); - scene.EntityComponent.CustomSystem(testCustomSystemComponent, CustomSystemType.RunSystem); - // // 测试配置表 - // var instanceList = UnitConfigData.Instance.List; - // var unitConfig = instanceList[0]; - // Log.Debug(instanceList[0].Dic[1]); + // Gate 场景初始化 + await InitializeGateScene(scene); + break; + } + case SceneType.Map: + { + await InitializeMapScene(scene); + break; + } + case SceneType.Social: + { + // Gate 场景初始化 + await InitializeSocialScene(scene); + break; + } + case SceneType.Game: + { + await InitializeGameScene(scene); break; } } await FTask.CompletedTask; } + + private async FTask InitializeAuthenticationScene(Scene scene) + { + // 用于鉴权服务器注册和登录相关逻辑的组件 + scene.AddComponent().UpdatePosition(); + // 用于颁发ToKen证书相关的逻辑。 + scene.AddComponent(); + await FTask.CompletedTask; + } + + private async FTask InitializeGateScene(Scene scene) + { + // Gate 场景特定的初始化逻辑 + Log.Info($"初始化 Gate 场景: {scene.Id}"); + // 用于管理网关所有连接的组件 + scene.AddComponent(); + // 用于验证JWT是否合法的组件 + scene.AddComponent(); + + await FTask.CompletedTask; + + // var roomCode = RoomHelper.GenerateCode(scene.SceneConfigId, 1); + // Log.Info($"测试 roomCode:{roomCode}"); + // uint serverId = 25255; + // for (int i = 1; i < 65535; i++) + // { + // var roomId = RoomHelper.GenerateCode(serverId, i); + // RoomHelper.ParseCode(roomId, out var pId, out var rId); + // Log.Info($"生成id测试,房间id={roomId} 原始服务id:{serverId} 原始房间id={i} 解析={pId} {rId}"); + // } + + // var tasks = new List(2000); + // var session = scene.GetSession(_addressableSceneRunTimeId); + // var sceneNetworkMessagingComponent = scene.NetworkMessagingComponent; + // var g2ATestRequest = new G2A_TestRequest(); + // + // async FTask Call() + // { + // await sceneNetworkMessagingComponent.CallInnerRouteBySession(session,_addressableSceneRunTimeId,g2ATestRequest); + // } + // + // for (int i = 0; i < 100000000000; i++) + // { + // tasks.Clear(); + // for (int j = 0; j < tasks.Capacity; ++j) + // { + // tasks.Add(Call()); + // } + // await FTask.WaitAll(tasks); + // } + + // // 测试配置表 + // var instanceList = UnitConfigData.Instance.List; + // var unitConfig = instanceList[0]; + // Log.Debug(instanceList[0].Dic[1]); + } + + private async FTask InitializeMapScene(Scene scene) + { + // Map 场景特定的初始化逻辑 + Log.Info($"初始化 Map 场景: {scene.Id}"); + Log.Info("创建地图场景==="); + scene.AddComponent(); + var roomManageComponent = scene.AddComponent(); + scene.AddComponent(); + + var room = roomManageComponent.Create(361499030775398402); + if (room != null) + { + roomManageComponent.TestRoomCode = room.Code; + Log.Info($"测试房间代码 = {room.Code}"); + } + + await FTask.CompletedTask; + } + + private async FTask InitializeSocialScene(Scene scene) + { + Log.Info($"初始化 Social 场景: {scene.Id}"); + //用于管理玩家的组件 + scene.AddComponent(); + scene.AddComponent(); + scene.AddComponent(); + await FTask.CompletedTask; + } + + private async FTask InitializeGameScene(Scene scene) + { + // Chat 场景特定的初始化逻辑 + Log.Info($"初始化 Game 场景: {scene.Id}"); + //用于管理玩家的组件 + scene.AddComponent(); + scene.AddComponent(); + await FTask.CompletedTask; + + // var rod = RodConfig.Get(30001); + // Log.Info("rod config id=" + rod.Id); + // // Begins transaction + // using (var session = mongoClient.StartSession()) + // { + // session.StartTransaction(); + // try + // { + // // Creates sample data + // var book = new Book + // { + // Title = "Beloved", + // Author = "Toni Morrison", + // InStock = true + // }; + // var film = new Film + // { + // Title = "Star Wars", + // Director = "George Lucas", + // InStock = true + // }; + // // Inserts sample data + // books.InsertOne(session, book); + // films.InsertOne(session, film); + // // Commits our transaction + // session.CommitTransaction(); + // } + // catch (Exception e) + // { + // Console.WriteLine("Error writing to MongoDB: " + e.Message); + // return; + // } + // // Prints a success message if no error thrown + // Console.WriteLine("Successfully committed transaction!"); + // } + + // var client = self.Scene.World.Database; + + // List tasks = new List(); + // Stopwatch stopwatch = new Stopwatch(); + // stopwatch.Start(); + // for (int i = 0; i < 100; i++) + // { + // var accountId = scene.EntityIdFactory.Create; + // var account = PlayerFactory.Create(scene, accountId); + // + // account.Level = 99; + // account.NickName = $"测试号{i + 1}"; + // account.Country = "cn"; + // account.Exp = 999; + // account.Head = "xxx.png"; + // tasks.Add(account.Save()); + // } + // await FTask.WaitAll(tasks); + // // self.Scene.World.Database.InsertBatch() + // + // stopwatch.Stop(); + // Log.Info($"创建100个号入库耗时={stopwatch.ElapsedMilliseconds}ms"); + } + + private async FTask InitializeAddressableScene(Scene scene) + { + // Addressable 场景特定的初始化逻辑 + Log.Info($"初始化 Addressable 场景: {scene.Id}"); + await FTask.CompletedTask; + } } \ No newline at end of file diff --git a/Hotfix/OnSceneCreate_Init.cs b/Hotfix/OnSceneCreate_Init.cs deleted file mode 100644 index fc47b32..0000000 --- a/Hotfix/OnSceneCreate_Init.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Fantasy; -using Fantasy.Async; -using Fantasy.Event; -using NB.Authentication; -using NB.Chat; -using NB.Game; -using NB.Gate; -using NB.Map; - -namespace NB; - -public class OnSceneCreate_Init : AsyncEventSystem -{ - protected override async FTask Handler(OnCreateScene self) - { - var scene = self.Scene; - - switch (scene.SceneType) - { - case SceneType.Authentication: - { - // 用于鉴权服务器注册和登录相关逻辑的组件 - scene.AddComponent().UpdatePosition(); - // 用于颁发ToKen证书相关的逻辑。 - scene.AddComponent(); - break; - } - case SceneType.Gate: - { - // 用于管理网关所有连接的组件 - scene.AddComponent(); - // 用于验证JWT是否合法的组件 - scene.AddComponent(); - break; - } - case SceneType.Game: - { - //用于管理玩家的组件 - scene.AddComponent(); - scene.AddComponent(); - break; - } - case SceneType.Social: - { - //用于管理玩家的组件 - scene.AddComponent(); - scene.AddComponent(); - scene.AddComponent(); - break; - } - case SceneType.Map: - { - Log.Info("创建地图场景==="); - scene.AddComponent(); - var roomManageComponent = scene.AddComponent(); - scene.AddComponent(); - - var room = roomManageComponent.Create(361499030775398402); - if (room != null) - { - roomManageComponent.TestRoomCode = room.Code; - Log.Info($"测试房间代码 = {room.Code}"); - } - - break; - } - } - - await FTask.CompletedTask; - } -} \ No newline at end of file diff --git a/Hotfix/Social/Chat/System/ChatChannelCenterComponentSystem.cs b/Hotfix/Social/Chat/System/ChatChannelCenterComponentSystem.cs index d2e2ef5..805c9e8 100644 --- a/Hotfix/Social/Chat/System/ChatChannelCenterComponentSystem.cs +++ b/Hotfix/Social/Chat/System/ChatChannelCenterComponentSystem.cs @@ -36,7 +36,7 @@ public static class ChatChannelCenterComponentSystem } //查数据库 - channel = await self.Scene.World.DataBase.Query(channelId, true); + channel = await self.Scene.World.Database.Query(channelId, true); if (channel != null) { self.Channels.Add(channel.Id, channel); @@ -58,7 +58,7 @@ public static class ChatChannelCenterComponentSystem channel.CreateTime = TimeHelper.Now; self.Channels.Add(channel.Id, channel); //保存到数据库 - await self.Scene.World.DataBase.Save(channel); + await self.Scene.World.Database.Save(channel); return channel; } diff --git a/Hotfix/Social/Chat/System/ChatUnitManageComponentSystem.cs b/Hotfix/Social/Chat/System/ChatUnitManageComponentSystem.cs index 61f7720..fd3f01c 100644 --- a/Hotfix/Social/Chat/System/ChatUnitManageComponentSystem.cs +++ b/Hotfix/Social/Chat/System/ChatUnitManageComponentSystem.cs @@ -114,7 +114,7 @@ public static class ChatUnitManageComponentSystem { if (socialUnit.GetComponent() == null) { - var mailComponent = await socialUnit.Scene.World.DataBase.Query(socialUnit.Id, true); + var mailComponent = await socialUnit.Scene.World.Database.Query(socialUnit.Id, true); if (mailComponent == null) { //如果没有邮件组件 diff --git a/Hotfix/Social/Mail/Helper/MailConversationHelper.cs b/Hotfix/Social/Mail/Helper/MailConversationHelper.cs index e6c89d7..56696df 100644 --- a/Hotfix/Social/Mail/Helper/MailConversationHelper.cs +++ b/Hotfix/Social/Mail/Helper/MailConversationHelper.cs @@ -16,7 +16,7 @@ public static class MailConversationHelper public static async FTask LoadDataBase(Scene scene, long firstId, long secondId) { var conversation = - await scene.World.DataBase.First(d => d.FirstId == firstId && d.SecondId == secondId); + await scene.World.Database.First(d => d.FirstId == firstId && d.SecondId == secondId); if (conversation == null) { return null; @@ -33,6 +33,6 @@ public static class MailConversationHelper /// public static async FTask DeleteDataBase(Scene scene,long id) { - await scene.World.DataBase.Remove(id); + await scene.World.Database.Remove(id); } } \ No newline at end of file diff --git a/Hotfix/Social/Mail/System/MailComponentSystem.cs b/Hotfix/Social/Mail/System/MailComponentSystem.cs index 354866c..bbf80fa 100644 --- a/Hotfix/Social/Mail/System/MailComponentSystem.cs +++ b/Hotfix/Social/Mail/System/MailComponentSystem.cs @@ -48,7 +48,7 @@ public static class MailComponentSystem }); } - await self.Scene.World.DataBase.Save(self); + await self.Scene.World.Database.Save(self); Log.Info($"MailComponent Add id:{self.Id} mailId:{mail.Id} count:{self.Mails.Count}"); } @@ -72,7 +72,7 @@ public static class MailComponentSystem }); } - await self.Scene.World.DataBase.Save(self); + await self.Scene.World.Database.Save(self); Log.Info($"MailComponent Remove id:{self.Id} mailId:{mail.Id} count:{self.Mails.Count}"); return 0; } diff --git a/Hotfix/Social/Mail/System/MailConversationSystem.cs b/Hotfix/Social/Mail/System/MailConversationSystem.cs index 96c5abf..edebe9b 100644 --- a/Hotfix/Social/Mail/System/MailConversationSystem.cs +++ b/Hotfix/Social/Mail/System/MailConversationSystem.cs @@ -58,7 +58,7 @@ public static class MailConversationSystem if (forceSave) { self.UpdateTime = TimeHelper.Now; - await self.Scene.World.DataBase.Save(self); + await self.Scene.World.Database.Save(self); } else { diff --git a/Hotfix/Social/Mail/System/MailManageComponentSystem.cs b/Hotfix/Social/Mail/System/MailManageComponentSystem.cs index eed9fb4..598e7c5 100644 --- a/Hotfix/Social/Mail/System/MailManageComponentSystem.cs +++ b/Hotfix/Social/Mail/System/MailManageComponentSystem.cs @@ -84,7 +84,7 @@ public static class MailManageComponentSystem public static async FTask> GetConversations(this MailManageComponent self, long id) { List players = - await self.Scene.World.DataBase.QueryByPageOrderBy( + await self.Scene.World.Database.QueryByPageOrderBy( d => d.FirstId == id || d.SecondId == id, 1, 50, d => d.UpdateTime); diff --git a/Hotfix/bin/Debug/net9.0/Entity.dll b/Hotfix/bin/Debug/net9.0/Entity.dll new file mode 100644 index 0000000..e3649fb Binary files /dev/null and b/Hotfix/bin/Debug/net9.0/Entity.dll differ diff --git a/Hotfix/bin/Debug/net9.0/Entity.pdb b/Hotfix/bin/Debug/net9.0/Entity.pdb new file mode 100644 index 0000000..aa1be2e Binary files /dev/null and b/Hotfix/bin/Debug/net9.0/Entity.pdb differ diff --git a/Hotfix/bin/Debug/net9.0/Fantasy.config b/Hotfix/bin/Debug/net9.0/Fantasy.config new file mode 100644 index 0000000..b50d8ab --- /dev/null +++ b/Hotfix/bin/Debug/net9.0/Fantasy.config @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Hotfix/bin/Debug/net9.0/Fantasy.xsd b/Hotfix/bin/Debug/net9.0/Fantasy.xsd new file mode 100644 index 0000000..6a64f66 --- /dev/null +++ b/Hotfix/bin/Debug/net9.0/Fantasy.xsd @@ -0,0 +1,345 @@ + + + + + + + Fantasy框架配置文件根元素 + + + + + + 配置表路径设置 + + + + + 网络运行时配置 + + + + + 会话运行时配置 + + + + + 服务器配置 + + + + + + + + + + + 配置表文件路径 + + + + + + + + + + 机器配置列表 + + + + + 进程配置列表 + + + + + 世界配置列表 + + + + + 场景配置列表 + + + + + 单位配置列表 + + + + + + + + + + + + + + + + 机器ID + + + + + 外网IP地址 + + + + + 外网绑定IP地址 + + + + + 内网绑定IP地址 + + + + + + + + + + + + + + + 进程ID + + + + + 所属机器ID + + + + + 启动分组 + + + + + + + + + + + + + + + + 数据库类型 + + + + + + + + + + + + + + + + + + 数据库名称 + + + + + 数据库连接字符串 + + + + + + + + + 世界中配置的数据库 + + + + + + + + 世界ID + + + + + 世界名称 + + + + + + + + + + + + + + + 场景ID + + + + + 进程配置ID + + + + + 世界配置ID + + + + + 场景运行模式 + + + + + + + + + + + + 场景类型字符串 + + + + + 网络协议类型 + + + + + + + + + + + + + + 外网端口 + + + + + 内网端口 + + + + + + + + + 服务器内部网络协议 + + + + + + + + + + + 消息体最大长度(字节),默认1048560字节(约1.02MB) + + + + + + + + + Session idle check timeout (in milliseconds) + + + + + Session idle check interval (in milliseconds) + + + + + + + + + + + + + + + + 单位字典数据 + + + + + + 单位ID + + + + + 单位名称 + + + + + 单位模型 + + + + + + + + + + + 字典键 + + + + + 字典值 + + + + + + + + \ No newline at end of file diff --git a/Hotfix/bin/Debug/net9.0/Hotfix.deps.json b/Hotfix/bin/Debug/net9.0/Hotfix.deps.json new file mode 100644 index 0000000..6032ae1 --- /dev/null +++ b/Hotfix/bin/Debug/net9.0/Hotfix.deps.json @@ -0,0 +1,424 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v9.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v9.0": { + "Hotfix/1.0.0": { + "dependencies": { + "Entity": "1.0.0" + }, + "runtime": { + "Hotfix.dll": {} + } + }, + "CommandLineParser/2.9.1": { + "runtime": { + "lib/netstandard2.0/CommandLine.dll": { + "assemblyVersion": "2.9.1.0", + "fileVersion": "2.9.1.0" + } + } + }, + "DnsClient/1.6.1": { + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0" + }, + "runtime": { + "lib/net5.0/DnsClient.dll": { + "assemblyVersion": "1.6.1.0", + "fileVersion": "1.6.1.0" + } + } + }, + "Fantasy-Net/2025.2.0": { + "dependencies": { + "CommandLineParser": "2.9.1", + "MongoDB.Bson": "3.5.0", + "MongoDB.Driver": "3.5.0", + "Newtonsoft.Json": "13.0.4", + "protobuf-net": "3.2.56" + }, + "runtime": { + "lib/net9.0/Fantasy-Net.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {}, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" + } + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.NETCore.Platforms/5.0.0": {}, + "Microsoft.Win32.Registry/5.0.0": { + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "MongoDB.Bson/3.5.0": { + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "5.0.0" + }, + "runtime": { + "lib/net6.0/MongoDB.Bson.dll": { + "assemblyVersion": "3.5.0.0", + "fileVersion": "3.5.0.0" + } + } + }, + "MongoDB.Driver/3.5.0": { + "dependencies": { + "DnsClient": "1.6.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "MongoDB.Bson": "3.5.0", + "SharpCompress": "0.30.1", + "Snappier": "1.0.0", + "System.Buffers": "4.5.1", + "ZstdSharp.Port": "0.7.3" + }, + "runtime": { + "lib/net6.0/MongoDB.Driver.dll": { + "assemblyVersion": "3.5.0.0", + "fileVersion": "3.5.0.0" + } + } + }, + "Newtonsoft.Json/13.0.4": { + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.4.30916" + } + } + }, + "protobuf-net/3.2.56": { + "dependencies": { + "protobuf-net.Core": "3.2.56" + }, + "runtime": { + "lib/net8.0/protobuf-net.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.2.56.57311" + } + } + }, + "protobuf-net.Core/3.2.56": { + "runtime": { + "lib/net8.0/protobuf-net.Core.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.2.56.57311" + } + } + }, + "SharpCompress/0.30.1": { + "runtime": { + "lib/net5.0/SharpCompress.dll": { + "assemblyVersion": "0.30.1.0", + "fileVersion": "0.30.1.0" + } + } + }, + "Snappier/1.0.0": { + "runtime": { + "lib/net5.0/Snappier.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "System.Buffers/4.5.1": {}, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.14.0", + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "runtime": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "System.Memory/4.5.5": {}, + "System.Runtime.CompilerServices.Unsafe/5.0.0": {}, + "System.Security.AccessControl/5.0.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Principal.Windows/5.0.0": {}, + "ZstdSharp.Port/0.7.3": { + "runtime": { + "lib/net7.0/ZstdSharp.dll": { + "assemblyVersion": "0.7.3.0", + "fileVersion": "0.7.3.0" + } + } + }, + "Entity/1.0.0": { + "dependencies": { + "Fantasy-Net": "2025.2.0", + "Microsoft.IdentityModel.Tokens": "8.14.0", + "System.IdentityModel.Tokens.Jwt": "8.14.0", + "ThirdParty": "1.0.0" + }, + "runtime": { + "Entity.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "ThirdParty/1.0.0": { + "runtime": { + "ThirdParty.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + } + } + }, + "libraries": { + "Hotfix/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "CommandLineParser/2.9.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-OE0sl1/sQ37bjVsPKKtwQlWDgqaxWgtme3xZz7JssWUzg5JpMIyHgCTY9MVMxOg48fJ1AgGT3tgdH5m/kQ5xhA==", + "path": "commandlineparser/2.9.1", + "hashPath": "commandlineparser.2.9.1.nupkg.sha512" + }, + "DnsClient/1.6.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4H/f2uYJOZ+YObZjpY9ABrKZI+JNw3uizp6oMzTXwDw6F+2qIPhpRl/1t68O/6e98+vqNiYGu+lswmwdYUy3gg==", + "path": "dnsclient/1.6.1", + "hashPath": "dnsclient.1.6.1.nupkg.sha512" + }, + "Fantasy-Net/2025.2.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-vCkduwxkMlH8GozyS+ZlWGLC4nGjFGaL13Ah4w5HL55XAJaAhe+RX+gbSRNBeJf1Uu0cjG2MgVyS4NX7bXdN4g==", + "path": "fantasy-net/2025.2.0", + "hashPath": "fantasy-net.2025.2.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "path": "microsoft.extensions.logging.abstractions/8.0.0", + "hashPath": "microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==", + "path": "microsoft.identitymodel.abstractions/8.14.0", + "hashPath": "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==", + "path": "microsoft.identitymodel.jsonwebtokens/8.14.0", + "hashPath": "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==", + "path": "microsoft.identitymodel.logging/8.14.0", + "hashPath": "microsoft.identitymodel.logging.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==", + "path": "microsoft.identitymodel.tokens/8.14.0", + "hashPath": "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==", + "path": "microsoft.netcore.platforms/5.0.0", + "hashPath": "microsoft.netcore.platforms.5.0.0.nupkg.sha512" + }, + "Microsoft.Win32.Registry/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "path": "microsoft.win32.registry/5.0.0", + "hashPath": "microsoft.win32.registry.5.0.0.nupkg.sha512" + }, + "MongoDB.Bson/3.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-JGNK6BanLDEifgkvPLqVFCPus5EDCy416pxf1dxUBRSVd3D9+NB3AvMVX190eXlk5/UXuCxpsQv7jWfNKvppBQ==", + "path": "mongodb.bson/3.5.0", + "hashPath": "mongodb.bson.3.5.0.nupkg.sha512" + }, + "MongoDB.Driver/3.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ST90u7psyMkNNOWFgSkexsrB3kPn7Ynl2DlMFj2rJyYuc6SIxjmzu4ufy51yzM+cPVE1SvVcdb5UFobrRw6cMg==", + "path": "mongodb.driver/3.5.0", + "hashPath": "mongodb.driver.3.5.0.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.4": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pdgNNMai3zv51W5aq268sujXUyx7SNdE2bj1wZcWjAQrKMFZV260lbqYop1d2GM67JI1huLRwxo9ZqnfF/lC6A==", + "path": "newtonsoft.json/13.0.4", + "hashPath": "newtonsoft.json.13.0.4.nupkg.sha512" + }, + "protobuf-net/3.2.56": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4IPJeTYAMNewlN8MDaFkcmR/9hLhJeo9eARnTh104zh7mf+vXT2gu5MUfUnkSQU+CH578Q6vcdU7LQDQPG6eaw==", + "path": "protobuf-net/3.2.56", + "hashPath": "protobuf-net.3.2.56.nupkg.sha512" + }, + "protobuf-net.Core/3.2.56": { + "type": "package", + "serviceable": true, + "sha512": "sha512-d6QOukTpDzs7zZv9tPnBZMtvHDNeHJQXUhMx54g4urUQsXK3oo9U70H9HvklYq7hlQ4A7AHJl7EVEqyCXXIl8Q==", + "path": "protobuf-net.core/3.2.56", + "hashPath": "protobuf-net.core.3.2.56.nupkg.sha512" + }, + "SharpCompress/0.30.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XqD4TpfyYGa7QTPzaGlMVbcecKnXy4YmYLDWrU+JIj7IuRNl7DH2END+Ll7ekWIY8o3dAMWLFDE1xdhfIWD1nw==", + "path": "sharpcompress/0.30.1", + "hashPath": "sharpcompress.0.30.1.nupkg.sha512" + }, + "Snappier/1.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rFtK2KEI9hIe8gtx3a0YDXdHOpedIf9wYCEYtBEmtlyiWVX3XlCNV03JrmmAi/Cdfn7dxK+k0sjjcLv4fpHnqA==", + "path": "snappier/1.0.0", + "hashPath": "snappier.1.0.0.nupkg.sha512" + }, + "System.Buffers/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==", + "path": "system.buffers/4.5.1", + "hashPath": "system.buffers.4.5.1.nupkg.sha512" + }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-EYGgN/S+HK7S6F3GaaPLFAfK0UzMrkXFyWCvXpQWFYmZln3dqtbyIO7VuTM/iIIPMzkelg8ZLlBPvMhxj6nOAA==", + "path": "system.identitymodel.tokens.jwt/8.14.0", + "hashPath": "system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512" + }, + "System.Memory/4.5.5": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "path": "system.memory/4.5.5", + "hashPath": "system.memory.4.5.5.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==", + "path": "system.runtime.compilerservices.unsafe/5.0.0", + "hashPath": "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512" + }, + "System.Security.AccessControl/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "path": "system.security.accesscontrol/5.0.0", + "hashPath": "system.security.accesscontrol.5.0.0.nupkg.sha512" + }, + "System.Security.Principal.Windows/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==", + "path": "system.security.principal.windows/5.0.0", + "hashPath": "system.security.principal.windows.5.0.0.nupkg.sha512" + }, + "ZstdSharp.Port/0.7.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-U9Ix4l4cl58Kzz1rJzj5hoVTjmbx1qGMwzAcbv1j/d3NzrFaESIurQyg+ow4mivCgkE3S413y+U9k4WdnEIkRA==", + "path": "zstdsharp.port/0.7.3", + "hashPath": "zstdsharp.port.0.7.3.nupkg.sha512" + }, + "Entity/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ThirdParty/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Hotfix/bin/Debug/net9.0/Hotfix.dll b/Hotfix/bin/Debug/net9.0/Hotfix.dll new file mode 100644 index 0000000..88aaba0 Binary files /dev/null and b/Hotfix/bin/Debug/net9.0/Hotfix.dll differ diff --git a/Hotfix/bin/Debug/net9.0/Hotfix.pdb b/Hotfix/bin/Debug/net9.0/Hotfix.pdb new file mode 100644 index 0000000..cd22eb7 Binary files /dev/null and b/Hotfix/bin/Debug/net9.0/Hotfix.pdb differ diff --git a/Hotfix/bin/Debug/net9.0/ThirdParty.dll b/Hotfix/bin/Debug/net9.0/ThirdParty.dll new file mode 100644 index 0000000..c68db15 Binary files /dev/null and b/Hotfix/bin/Debug/net9.0/ThirdParty.dll differ diff --git a/Hotfix/bin/Debug/net9.0/ThirdParty.pdb b/Hotfix/bin/Debug/net9.0/ThirdParty.pdb new file mode 100644 index 0000000..6d74378 Binary files /dev/null and b/Hotfix/bin/Debug/net9.0/ThirdParty.pdb differ diff --git a/Hotfix/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs b/Hotfix/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs new file mode 100644 index 0000000..feda5e9 --- /dev/null +++ b/Hotfix/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")] diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.AssemblyInfo.cs b/Hotfix/obj/Debug/net9.0/Hotfix.AssemblyInfo.cs new file mode 100644 index 0000000..f92161d --- /dev/null +++ b/Hotfix/obj/Debug/net9.0/Hotfix.AssemblyInfo.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("Hotfix")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+7b10d4cb317c9f310649a9cb4afe3882d4b12624")] +[assembly: System.Reflection.AssemblyProductAttribute("Hotfix")] +[assembly: System.Reflection.AssemblyTitleAttribute("Hotfix")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// 由 MSBuild WriteCodeFragment 类生成。 + diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.AssemblyInfoInputs.cache b/Hotfix/obj/Debug/net9.0/Hotfix.AssemblyInfoInputs.cache new file mode 100644 index 0000000..8cd76cb --- /dev/null +++ b/Hotfix/obj/Debug/net9.0/Hotfix.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +1a6c20277d8c32971e19ca0e610451e7396ebd99499eddc93137e652e7e5490e diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.GeneratedMSBuildEditorConfig.editorconfig b/Hotfix/obj/Debug/net9.0/Hotfix.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 0000000..b1b0734 --- /dev/null +++ b/Hotfix/obj/Debug/net9.0/Hotfix.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,15 @@ +is_global = true +build_property.TargetFramework = net9.0 +build_property.TargetPlatformMinVersion = +build_property.UsingMicrosoftNETSdkWeb = +build_property.ProjectTypeGuids = +build_property.InvariantGlobalization = +build_property.PlatformNeutralAssembly = +build_property.EnforceExtendedAnalyzerRules = +build_property._SupportedPlatformList = Linux,macOS,Windows +build_property.RootNamespace = Hotfix +build_property.ProjectDir = D:\work\Fishing2Server\Hotfix\ +build_property.EnableComHosting = +build_property.EnableGeneratedComInterfaceComImportInterop = +build_property.EffectiveAnalysisLevelStyle = 9.0 +build_property.EnableCodeStyleSeverity = diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.GlobalUsings.g.cs b/Hotfix/obj/Debug/net9.0/Hotfix.GlobalUsings.g.cs new file mode 100644 index 0000000..8578f3d --- /dev/null +++ b/Hotfix/obj/Debug/net9.0/Hotfix.GlobalUsings.g.cs @@ -0,0 +1,8 @@ +// +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Net.Http; +global using global::System.Threading; +global using global::System.Threading.Tasks; diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.assets.cache b/Hotfix/obj/Debug/net9.0/Hotfix.assets.cache new file mode 100644 index 0000000..d9f8097 Binary files /dev/null and b/Hotfix/obj/Debug/net9.0/Hotfix.assets.cache differ diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.csproj.AssemblyReference.cache b/Hotfix/obj/Debug/net9.0/Hotfix.csproj.AssemblyReference.cache new file mode 100644 index 0000000..10cdce2 Binary files /dev/null and b/Hotfix/obj/Debug/net9.0/Hotfix.csproj.AssemblyReference.cache differ diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.csproj.CoreCompileInputs.cache b/Hotfix/obj/Debug/net9.0/Hotfix.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..e786331 --- /dev/null +++ b/Hotfix/obj/Debug/net9.0/Hotfix.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +41f40879fae108427ac2e9e835099cef2ff8300cd2385f9434498ed95c00e0de diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.csproj.FileListAbsolute.txt b/Hotfix/obj/Debug/net9.0/Hotfix.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..ed45fa8 --- /dev/null +++ b/Hotfix/obj/Debug/net9.0/Hotfix.csproj.FileListAbsolute.txt @@ -0,0 +1,19 @@ +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\bin\Debug\net9.0\Fantasy.config +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\bin\Debug\net9.0\Fantasy.xsd +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\bin\Debug\net9.0\Hotfix.deps.json +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\bin\Debug\net9.0\Hotfix.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\bin\Debug\net9.0\Hotfix.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\bin\Debug\net9.0\Entity.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\bin\Debug\net9.0\Entity.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\Hotfix.csproj.AssemblyReference.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\Hotfix.GeneratedMSBuildEditorConfig.editorconfig +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\Hotfix.AssemblyInfoInputs.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\Hotfix.AssemblyInfo.cs +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\Hotfix.csproj.CoreCompileInputs.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\Hotfix.csproj.Up2Date +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\Hotfix.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\refint\Hotfix.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\Hotfix.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\obj\Debug\net9.0\ref\Hotfix.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\bin\Debug\net9.0\ThirdParty.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\bin\Debug\net9.0\ThirdParty.pdb diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.csproj.Up2Date b/Hotfix/obj/Debug/net9.0/Hotfix.csproj.Up2Date new file mode 100644 index 0000000..e69de29 diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.dll b/Hotfix/obj/Debug/net9.0/Hotfix.dll new file mode 100644 index 0000000..88aaba0 Binary files /dev/null and b/Hotfix/obj/Debug/net9.0/Hotfix.dll differ diff --git a/Hotfix/obj/Debug/net9.0/Hotfix.pdb b/Hotfix/obj/Debug/net9.0/Hotfix.pdb new file mode 100644 index 0000000..cd22eb7 Binary files /dev/null and b/Hotfix/obj/Debug/net9.0/Hotfix.pdb differ diff --git a/Hotfix/obj/Debug/net9.0/ref/Hotfix.dll b/Hotfix/obj/Debug/net9.0/ref/Hotfix.dll new file mode 100644 index 0000000..fadec29 Binary files /dev/null and b/Hotfix/obj/Debug/net9.0/ref/Hotfix.dll differ diff --git a/Hotfix/obj/Debug/net9.0/refint/Hotfix.dll b/Hotfix/obj/Debug/net9.0/refint/Hotfix.dll new file mode 100644 index 0000000..fadec29 Binary files /dev/null and b/Hotfix/obj/Debug/net9.0/refint/Hotfix.dll differ diff --git a/Hotfix/obj/Hotfix.csproj.nuget.dgspec.json b/Hotfix/obj/Hotfix.csproj.nuget.dgspec.json new file mode 100644 index 0000000..992ac06 --- /dev/null +++ b/Hotfix/obj/Hotfix.csproj.nuget.dgspec.json @@ -0,0 +1,225 @@ +{ + "format": 1, + "restore": { + "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj": {} + }, + "projects": { + "D:\\work\\Fishing2Server\\Entity\\Entity.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj", + "projectName": "Entity", + "projectPath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\Entity\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net9.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "projectReferences": { + "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "dependencies": { + "Fantasy-Net": { + "target": "Package", + "version": "[2025.2.0, )" + }, + "Microsoft.IdentityModel.Tokens": { + "target": "Package", + "version": "[8.14.0, )" + }, + "System.IdentityModel.Tokens.Jwt": { + "target": "Package", + "version": "[8.14.0, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + }, + "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj", + "projectName": "Hotfix", + "projectPath": "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\Hotfix\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net9.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "projectReferences": { + "D:\\work\\Fishing2Server\\Entity\\Entity.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + }, + "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "projectName": "ThirdParty", + "projectPath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\ThirdParty\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net8.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/Hotfix/obj/Hotfix.csproj.nuget.g.props b/Hotfix/obj/Hotfix.csproj.nuget.g.props new file mode 100644 index 0000000..fbb082f --- /dev/null +++ b/Hotfix/obj/Hotfix.csproj.nuget.g.props @@ -0,0 +1,16 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + $(UserProfile)\.nuget\packages\ + C:\Users\FIREBAT\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages + PackageReference + 6.14.0 + + + + + + \ No newline at end of file diff --git a/Hotfix/obj/Hotfix.csproj.nuget.g.targets b/Hotfix/obj/Hotfix.csproj.nuget.g.targets new file mode 100644 index 0000000..eb7028d --- /dev/null +++ b/Hotfix/obj/Hotfix.csproj.nuget.g.targets @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Hotfix/obj/project.assets.json b/Hotfix/obj/project.assets.json new file mode 100644 index 0000000..a67807c --- /dev/null +++ b/Hotfix/obj/project.assets.json @@ -0,0 +1,1218 @@ +{ + "version": 3, + "targets": { + "net9.0": { + "CommandLineParser/2.9.1": { + "type": "package", + "compile": { + "lib/netstandard2.0/CommandLine.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/CommandLine.dll": { + "related": ".xml" + } + } + }, + "DnsClient/1.6.1": { + "type": "package", + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0" + }, + "compile": { + "lib/net5.0/DnsClient.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net5.0/DnsClient.dll": { + "related": ".xml" + } + } + }, + "Fantasy-Net/2025.2.0": { + "type": "package", + "dependencies": { + "CommandLineParser": "2.9.1", + "MongoDB.Bson": "3.5.0", + "MongoDB.Driver": "3.5.0", + "Newtonsoft.Json": "13.0.4", + "protobuf-net": "3.2.56" + }, + "compile": { + "lib/net9.0/Fantasy-Net.dll": {} + }, + "runtime": { + "lib/net9.0/Fantasy-Net.dll": {} + }, + "frameworkReferences": [ + "Microsoft.AspNetCore.App" + ], + "build": { + "buildTransitive/Fantasy-Net.targets": {} + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { + "type": "package", + "compile": { + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "related": ".xml" + } + }, + "build": { + "buildTransitive/net6.0/_._": {} + } + }, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "type": "package", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" + }, + "compile": { + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "related": ".xml" + } + }, + "build": { + "buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets": {} + } + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "type": "package", + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "related": ".xml" + } + } + }, + "Microsoft.NETCore.Platforms/5.0.0": { + "type": "package", + "compile": { + "lib/netstandard1.0/_._": {} + }, + "runtime": { + "lib/netstandard1.0/_._": {} + } + }, + "Microsoft.Win32.Registry/5.0.0": { + "type": "package", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/Microsoft.Win32.Registry.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Win32.Registry.dll": { + "related": ".xml" + } + }, + "runtimeTargets": { + "runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "MongoDB.Bson/3.5.0": { + "type": "package", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "5.0.0" + }, + "compile": { + "lib/net6.0/MongoDB.Bson.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/MongoDB.Bson.dll": { + "related": ".xml" + } + } + }, + "MongoDB.Driver/3.5.0": { + "type": "package", + "dependencies": { + "DnsClient": "1.6.1", + "Microsoft.Extensions.Logging.Abstractions": "2.0.0", + "MongoDB.Bson": "3.5.0", + "SharpCompress": "0.30.1", + "Snappier": "1.0.0", + "System.Buffers": "4.5.1", + "ZstdSharp.Port": "0.7.3" + }, + "compile": { + "lib/net6.0/MongoDB.Driver.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/MongoDB.Driver.dll": { + "related": ".xml" + } + } + }, + "Newtonsoft.Json/13.0.4": { + "type": "package", + "compile": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + }, + "protobuf-net/3.2.56": { + "type": "package", + "dependencies": { + "protobuf-net.Core": "3.2.56" + }, + "compile": { + "lib/net8.0/protobuf-net.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/protobuf-net.dll": { + "related": ".xml" + } + } + }, + "protobuf-net.Core/3.2.56": { + "type": "package", + "compile": { + "lib/net8.0/protobuf-net.Core.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/protobuf-net.Core.dll": { + "related": ".xml" + } + } + }, + "SharpCompress/0.30.1": { + "type": "package", + "compile": { + "lib/net5.0/SharpCompress.dll": {} + }, + "runtime": { + "lib/net5.0/SharpCompress.dll": {} + } + }, + "Snappier/1.0.0": { + "type": "package", + "compile": { + "lib/net5.0/Snappier.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net5.0/Snappier.dll": { + "related": ".xml" + } + } + }, + "System.Buffers/4.5.1": { + "type": "package", + "compile": { + "ref/netcoreapp2.0/_._": {} + }, + "runtime": { + "lib/netcoreapp2.0/_._": {} + } + }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.14.0", + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "compile": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "related": ".xml" + } + } + }, + "System.Memory/4.5.5": { + "type": "package", + "compile": { + "ref/netcoreapp2.1/_._": {} + }, + "runtime": { + "lib/netcoreapp2.1/_._": {} + } + }, + "System.Runtime.CompilerServices.Unsafe/5.0.0": { + "type": "package", + "compile": { + "ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "related": ".xml" + } + } + }, + "System.Security.AccessControl/5.0.0": { + "type": "package", + "dependencies": { + "Microsoft.NETCore.Platforms": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/System.Security.AccessControl.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/System.Security.AccessControl.dll": { + "related": ".xml" + } + }, + "runtimeTargets": { + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "System.Security.Principal.Windows/5.0.0": { + "type": "package", + "compile": { + "ref/netcoreapp3.0/System.Security.Principal.Windows.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/System.Security.Principal.Windows.dll": { + "related": ".xml" + } + }, + "runtimeTargets": { + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": { + "assetType": "runtime", + "rid": "unix" + }, + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "ZstdSharp.Port/0.7.3": { + "type": "package", + "compile": { + "lib/net7.0/ZstdSharp.dll": {} + }, + "runtime": { + "lib/net7.0/ZstdSharp.dll": {} + } + }, + "Entity/1.0.0": { + "type": "project", + "framework": ".NETCoreApp,Version=v9.0", + "dependencies": { + "Fantasy-Net": "2025.2.0", + "Microsoft.IdentityModel.Tokens": "8.14.0", + "System.IdentityModel.Tokens.Jwt": "8.14.0", + "ThirdParty": "1.0.0" + }, + "compile": { + "bin/placeholder/Entity.dll": {} + }, + "runtime": { + "bin/placeholder/Entity.dll": {} + } + }, + "ThirdParty/1.0.0": { + "type": "project", + "framework": ".NETCoreApp,Version=v8.0", + "compile": { + "bin/placeholder/ThirdParty.dll": {} + }, + "runtime": { + "bin/placeholder/ThirdParty.dll": {} + } + } + } + }, + "libraries": { + "CommandLineParser/2.9.1": { + "sha512": "OE0sl1/sQ37bjVsPKKtwQlWDgqaxWgtme3xZz7JssWUzg5JpMIyHgCTY9MVMxOg48fJ1AgGT3tgdH5m/kQ5xhA==", + "type": "package", + "path": "commandlineparser/2.9.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "CommandLine20.png", + "License.md", + "README.md", + "commandlineparser.2.9.1.nupkg.sha512", + "commandlineparser.nuspec", + "lib/net40/CommandLine.dll", + "lib/net40/CommandLine.xml", + "lib/net45/CommandLine.dll", + "lib/net45/CommandLine.xml", + "lib/net461/CommandLine.dll", + "lib/net461/CommandLine.xml", + "lib/netstandard2.0/CommandLine.dll", + "lib/netstandard2.0/CommandLine.xml" + ] + }, + "DnsClient/1.6.1": { + "sha512": "4H/f2uYJOZ+YObZjpY9ABrKZI+JNw3uizp6oMzTXwDw6F+2qIPhpRl/1t68O/6e98+vqNiYGu+lswmwdYUy3gg==", + "type": "package", + "path": "dnsclient/1.6.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "dnsclient.1.6.1.nupkg.sha512", + "dnsclient.nuspec", + "icon.png", + "lib/net45/DnsClient.dll", + "lib/net45/DnsClient.xml", + "lib/net471/DnsClient.dll", + "lib/net471/DnsClient.xml", + "lib/net5.0/DnsClient.dll", + "lib/net5.0/DnsClient.xml", + "lib/netstandard1.3/DnsClient.dll", + "lib/netstandard1.3/DnsClient.xml", + "lib/netstandard2.0/DnsClient.dll", + "lib/netstandard2.0/DnsClient.xml", + "lib/netstandard2.1/DnsClient.dll", + "lib/netstandard2.1/DnsClient.xml" + ] + }, + "Fantasy-Net/2025.2.0": { + "sha512": "vCkduwxkMlH8GozyS+ZlWGLC4nGjFGaL13Ah4w5HL55XAJaAhe+RX+gbSRNBeJf1Uu0cjG2MgVyS4NX7bXdN4g==", + "type": "package", + "path": "fantasy-net/2025.2.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE", + "README.md", + "analyzers/dotnet/cs/Fantasy.SourceGenerator.dll", + "build/Fantasy-Net.props", + "build/Fantasy-Net.targets", + "build/Fantasy.config", + "build/Fantasy.xsd", + "buildTransitive/Fantasy-Net.targets", + "buildTransitive/Fantasy.config", + "buildTransitive/Fantasy.xsd", + "fantasy-net.2025.2.0.nupkg.sha512", + "fantasy-net.nuspec", + "icon.png", + "lib/net8.0/Fantasy-Net.dll", + "lib/net9.0/Fantasy-Net.dll" + ] + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { + "sha512": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "type": "package", + "path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "PACKAGE.md", + "THIRD-PARTY-NOTICES.TXT", + "buildTransitive/net461/Microsoft.Extensions.DependencyInjection.Abstractions.targets", + "buildTransitive/net462/_._", + "buildTransitive/net6.0/_._", + "buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.Abstractions.targets", + "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512", + "microsoft.extensions.dependencyinjection.abstractions.nuspec", + "useSharedDesignerContext.txt" + ] + }, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "sha512": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "type": "package", + "path": "microsoft.extensions.logging.abstractions/8.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "PACKAGE.md", + "THIRD-PARTY-NOTICES.TXT", + "analyzers/dotnet/roslyn3.11/cs/Microsoft.Extensions.Logging.Generators.dll", + "analyzers/dotnet/roslyn3.11/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/Microsoft.Extensions.Logging.Generators.dll", + "analyzers/dotnet/roslyn4.0/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/Microsoft.Extensions.Logging.Generators.dll", + "analyzers/dotnet/roslyn4.4/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", + "buildTransitive/net461/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/net462/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/netcoreapp2.0/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.targets", + "lib/net462/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net462/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/net6.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net6.0/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net7.0/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.xml", + "microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512", + "microsoft.extensions.logging.abstractions.nuspec", + "useSharedDesignerContext.txt" + ] + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "sha512": "iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==", + "type": "package", + "path": "microsoft.identitymodel.abstractions/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Abstractions.dll", + "lib/net462/Microsoft.IdentityModel.Abstractions.xml", + "lib/net472/Microsoft.IdentityModel.Abstractions.dll", + "lib/net472/Microsoft.IdentityModel.Abstractions.xml", + "lib/net6.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net6.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/net8.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net8.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net9.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.xml", + "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512", + "microsoft.identitymodel.abstractions.nuspec" + ] + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "sha512": "4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==", + "type": "package", + "path": "microsoft.identitymodel.jsonwebtokens/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net462/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net472/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net472/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512", + "microsoft.identitymodel.jsonwebtokens.nuspec" + ] + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "sha512": "eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==", + "type": "package", + "path": "microsoft.identitymodel.logging/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Logging.dll", + "lib/net462/Microsoft.IdentityModel.Logging.xml", + "lib/net472/Microsoft.IdentityModel.Logging.dll", + "lib/net472/Microsoft.IdentityModel.Logging.xml", + "lib/net6.0/Microsoft.IdentityModel.Logging.dll", + "lib/net6.0/Microsoft.IdentityModel.Logging.xml", + "lib/net8.0/Microsoft.IdentityModel.Logging.dll", + "lib/net8.0/Microsoft.IdentityModel.Logging.xml", + "lib/net9.0/Microsoft.IdentityModel.Logging.dll", + "lib/net9.0/Microsoft.IdentityModel.Logging.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Logging.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Logging.xml", + "microsoft.identitymodel.logging.8.14.0.nupkg.sha512", + "microsoft.identitymodel.logging.nuspec" + ] + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "sha512": "lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==", + "type": "package", + "path": "microsoft.identitymodel.tokens/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Tokens.dll", + "lib/net462/Microsoft.IdentityModel.Tokens.xml", + "lib/net472/Microsoft.IdentityModel.Tokens.dll", + "lib/net472/Microsoft.IdentityModel.Tokens.xml", + "lib/net6.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net6.0/Microsoft.IdentityModel.Tokens.xml", + "lib/net8.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net8.0/Microsoft.IdentityModel.Tokens.xml", + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net9.0/Microsoft.IdentityModel.Tokens.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.xml", + "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512", + "microsoft.identitymodel.tokens.nuspec" + ] + }, + "Microsoft.NETCore.Platforms/5.0.0": { + "sha512": "VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==", + "type": "package", + "path": "microsoft.netcore.platforms/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/netstandard1.0/_._", + "microsoft.netcore.platforms.5.0.0.nupkg.sha512", + "microsoft.netcore.platforms.nuspec", + "runtime.json", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "Microsoft.Win32.Registry/5.0.0": { + "sha512": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "type": "package", + "path": "microsoft.win32.registry/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/Microsoft.Win32.Registry.dll", + "lib/net461/Microsoft.Win32.Registry.dll", + "lib/net461/Microsoft.Win32.Registry.xml", + "lib/netstandard1.3/Microsoft.Win32.Registry.dll", + "lib/netstandard2.0/Microsoft.Win32.Registry.dll", + "lib/netstandard2.0/Microsoft.Win32.Registry.xml", + "microsoft.win32.registry.5.0.0.nupkg.sha512", + "microsoft.win32.registry.nuspec", + "ref/net46/Microsoft.Win32.Registry.dll", + "ref/net461/Microsoft.Win32.Registry.dll", + "ref/net461/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/Microsoft.Win32.Registry.dll", + "ref/netstandard1.3/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/de/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/es/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/fr/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/it/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/ja/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/ko/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/ru/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/zh-hans/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/zh-hant/Microsoft.Win32.Registry.xml", + "ref/netstandard2.0/Microsoft.Win32.Registry.dll", + "ref/netstandard2.0/Microsoft.Win32.Registry.xml", + "runtimes/win/lib/net46/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/net461/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/net461/Microsoft.Win32.Registry.xml", + "runtimes/win/lib/netstandard1.3/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.xml", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "MongoDB.Bson/3.5.0": { + "sha512": "JGNK6BanLDEifgkvPLqVFCPus5EDCy416pxf1dxUBRSVd3D9+NB3AvMVX190eXlk5/UXuCxpsQv7jWfNKvppBQ==", + "type": "package", + "path": "mongodb.bson/3.5.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net472/MongoDB.Bson.dll", + "lib/net472/MongoDB.Bson.xml", + "lib/net6.0/MongoDB.Bson.dll", + "lib/net6.0/MongoDB.Bson.xml", + "lib/netstandard2.1/MongoDB.Bson.dll", + "lib/netstandard2.1/MongoDB.Bson.xml", + "mongodb.bson.3.5.0.nupkg.sha512", + "mongodb.bson.nuspec", + "packageIcon.png" + ] + }, + "MongoDB.Driver/3.5.0": { + "sha512": "ST90u7psyMkNNOWFgSkexsrB3kPn7Ynl2DlMFj2rJyYuc6SIxjmzu4ufy51yzM+cPVE1SvVcdb5UFobrRw6cMg==", + "type": "package", + "path": "mongodb.driver/3.5.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net472/MongoDB.Driver.dll", + "lib/net472/MongoDB.Driver.xml", + "lib/net6.0/MongoDB.Driver.dll", + "lib/net6.0/MongoDB.Driver.xml", + "lib/netstandard2.1/MongoDB.Driver.dll", + "lib/netstandard2.1/MongoDB.Driver.xml", + "mongodb.driver.3.5.0.nupkg.sha512", + "mongodb.driver.nuspec", + "packageIcon.png" + ] + }, + "Newtonsoft.Json/13.0.4": { + "sha512": "pdgNNMai3zv51W5aq268sujXUyx7SNdE2bj1wZcWjAQrKMFZV260lbqYop1d2GM67JI1huLRwxo9ZqnfF/lC6A==", + "type": "package", + "path": "newtonsoft.json/13.0.4", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "README.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/net6.0/Newtonsoft.Json.dll", + "lib/net6.0/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.4.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "protobuf-net/3.2.56": { + "sha512": "4IPJeTYAMNewlN8MDaFkcmR/9hLhJeo9eARnTh104zh7mf+vXT2gu5MUfUnkSQU+CH578Q6vcdU7LQDQPG6eaw==", + "type": "package", + "path": "protobuf-net/3.2.56", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net462/protobuf-net.dll", + "lib/net462/protobuf-net.xml", + "lib/net8.0/protobuf-net.dll", + "lib/net8.0/protobuf-net.xml", + "lib/netstandard2.0/protobuf-net.dll", + "lib/netstandard2.0/protobuf-net.xml", + "lib/netstandard2.1/protobuf-net.dll", + "lib/netstandard2.1/protobuf-net.xml", + "protobuf-net.3.2.56.nupkg.sha512", + "protobuf-net.nuspec", + "protobuf-net.png", + "readme.md" + ] + }, + "protobuf-net.Core/3.2.56": { + "sha512": "d6QOukTpDzs7zZv9tPnBZMtvHDNeHJQXUhMx54g4urUQsXK3oo9U70H9HvklYq7hlQ4A7AHJl7EVEqyCXXIl8Q==", + "type": "package", + "path": "protobuf-net.core/3.2.56", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net462/protobuf-net.Core.dll", + "lib/net462/protobuf-net.Core.xml", + "lib/net8.0/protobuf-net.Core.dll", + "lib/net8.0/protobuf-net.Core.xml", + "lib/netstandard2.0/protobuf-net.Core.dll", + "lib/netstandard2.0/protobuf-net.Core.xml", + "lib/netstandard2.1/protobuf-net.Core.dll", + "lib/netstandard2.1/protobuf-net.Core.xml", + "protobuf-net.core.3.2.56.nupkg.sha512", + "protobuf-net.core.nuspec", + "protobuf-net.png", + "readme.md" + ] + }, + "SharpCompress/0.30.1": { + "sha512": "XqD4TpfyYGa7QTPzaGlMVbcecKnXy4YmYLDWrU+JIj7IuRNl7DH2END+Ll7ekWIY8o3dAMWLFDE1xdhfIWD1nw==", + "type": "package", + "path": "sharpcompress/0.30.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net461/SharpCompress.dll", + "lib/net5.0/SharpCompress.dll", + "lib/netcoreapp3.1/SharpCompress.dll", + "lib/netstandard2.0/SharpCompress.dll", + "lib/netstandard2.1/SharpCompress.dll", + "sharpcompress.0.30.1.nupkg.sha512", + "sharpcompress.nuspec" + ] + }, + "Snappier/1.0.0": { + "sha512": "rFtK2KEI9hIe8gtx3a0YDXdHOpedIf9wYCEYtBEmtlyiWVX3XlCNV03JrmmAi/Cdfn7dxK+k0sjjcLv4fpHnqA==", + "type": "package", + "path": "snappier/1.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "COPYING.txt", + "lib/net5.0/Snappier.dll", + "lib/net5.0/Snappier.xml", + "lib/netcoreapp3.0/Snappier.dll", + "lib/netcoreapp3.0/Snappier.xml", + "lib/netstandard2.0/Snappier.dll", + "lib/netstandard2.0/Snappier.xml", + "lib/netstandard2.1/Snappier.dll", + "lib/netstandard2.1/Snappier.xml", + "snappier.1.0.0.nupkg.sha512", + "snappier.nuspec" + ] + }, + "System.Buffers/4.5.1": { + "sha512": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==", + "type": "package", + "path": "system.buffers/4.5.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Buffers.dll", + "lib/net461/System.Buffers.xml", + "lib/netcoreapp2.0/_._", + "lib/netstandard1.1/System.Buffers.dll", + "lib/netstandard1.1/System.Buffers.xml", + "lib/netstandard2.0/System.Buffers.dll", + "lib/netstandard2.0/System.Buffers.xml", + "lib/uap10.0.16299/_._", + "ref/net45/System.Buffers.dll", + "ref/net45/System.Buffers.xml", + "ref/netcoreapp2.0/_._", + "ref/netstandard1.1/System.Buffers.dll", + "ref/netstandard1.1/System.Buffers.xml", + "ref/netstandard2.0/System.Buffers.dll", + "ref/netstandard2.0/System.Buffers.xml", + "ref/uap10.0.16299/_._", + "system.buffers.4.5.1.nupkg.sha512", + "system.buffers.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "sha512": "EYGgN/S+HK7S6F3GaaPLFAfK0UzMrkXFyWCvXpQWFYmZln3dqtbyIO7VuTM/iIIPMzkelg8ZLlBPvMhxj6nOAA==", + "type": "package", + "path": "system.identitymodel.tokens.jwt/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/System.IdentityModel.Tokens.Jwt.dll", + "lib/net462/System.IdentityModel.Tokens.Jwt.xml", + "lib/net472/System.IdentityModel.Tokens.Jwt.dll", + "lib/net472/System.IdentityModel.Tokens.Jwt.xml", + "lib/net6.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net6.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/net8.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net8.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net9.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.xml", + "system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512", + "system.identitymodel.tokens.jwt.nuspec" + ] + }, + "System.Memory/4.5.5": { + "sha512": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "type": "package", + "path": "system.memory/4.5.5", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Memory.dll", + "lib/net461/System.Memory.xml", + "lib/netcoreapp2.1/_._", + "lib/netstandard1.1/System.Memory.dll", + "lib/netstandard1.1/System.Memory.xml", + "lib/netstandard2.0/System.Memory.dll", + "lib/netstandard2.0/System.Memory.xml", + "ref/netcoreapp2.1/_._", + "system.memory.4.5.5.nupkg.sha512", + "system.memory.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Runtime.CompilerServices.Unsafe/5.0.0": { + "sha512": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==", + "type": "package", + "path": "system.runtime.compilerservices.unsafe/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net45/System.Runtime.CompilerServices.Unsafe.dll", + "lib/net45/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netstandard1.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netstandard1.0/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/net461/System.Runtime.CompilerServices.Unsafe.dll", + "ref/net461/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard1.0/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard1.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard2.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.xml", + "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512", + "system.runtime.compilerservices.unsafe.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.AccessControl/5.0.0": { + "sha512": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "type": "package", + "path": "system.security.accesscontrol/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/System.Security.AccessControl.dll", + "lib/net461/System.Security.AccessControl.dll", + "lib/net461/System.Security.AccessControl.xml", + "lib/netstandard1.3/System.Security.AccessControl.dll", + "lib/netstandard2.0/System.Security.AccessControl.dll", + "lib/netstandard2.0/System.Security.AccessControl.xml", + "lib/uap10.0.16299/_._", + "ref/net46/System.Security.AccessControl.dll", + "ref/net461/System.Security.AccessControl.dll", + "ref/net461/System.Security.AccessControl.xml", + "ref/netstandard1.3/System.Security.AccessControl.dll", + "ref/netstandard1.3/System.Security.AccessControl.xml", + "ref/netstandard1.3/de/System.Security.AccessControl.xml", + "ref/netstandard1.3/es/System.Security.AccessControl.xml", + "ref/netstandard1.3/fr/System.Security.AccessControl.xml", + "ref/netstandard1.3/it/System.Security.AccessControl.xml", + "ref/netstandard1.3/ja/System.Security.AccessControl.xml", + "ref/netstandard1.3/ko/System.Security.AccessControl.xml", + "ref/netstandard1.3/ru/System.Security.AccessControl.xml", + "ref/netstandard1.3/zh-hans/System.Security.AccessControl.xml", + "ref/netstandard1.3/zh-hant/System.Security.AccessControl.xml", + "ref/netstandard2.0/System.Security.AccessControl.dll", + "ref/netstandard2.0/System.Security.AccessControl.xml", + "ref/uap10.0.16299/_._", + "runtimes/win/lib/net46/System.Security.AccessControl.dll", + "runtimes/win/lib/net461/System.Security.AccessControl.dll", + "runtimes/win/lib/net461/System.Security.AccessControl.xml", + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll", + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.xml", + "runtimes/win/lib/netstandard1.3/System.Security.AccessControl.dll", + "runtimes/win/lib/uap10.0.16299/_._", + "system.security.accesscontrol.5.0.0.nupkg.sha512", + "system.security.accesscontrol.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.Principal.Windows/5.0.0": { + "sha512": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==", + "type": "package", + "path": "system.security.principal.windows/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/System.Security.Principal.Windows.dll", + "lib/net461/System.Security.Principal.Windows.dll", + "lib/net461/System.Security.Principal.Windows.xml", + "lib/netstandard1.3/System.Security.Principal.Windows.dll", + "lib/netstandard2.0/System.Security.Principal.Windows.dll", + "lib/netstandard2.0/System.Security.Principal.Windows.xml", + "lib/uap10.0.16299/_._", + "ref/net46/System.Security.Principal.Windows.dll", + "ref/net461/System.Security.Principal.Windows.dll", + "ref/net461/System.Security.Principal.Windows.xml", + "ref/netcoreapp3.0/System.Security.Principal.Windows.dll", + "ref/netcoreapp3.0/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/System.Security.Principal.Windows.dll", + "ref/netstandard1.3/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/de/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/es/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/fr/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/it/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ja/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ko/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ru/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/zh-hans/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/zh-hant/System.Security.Principal.Windows.xml", + "ref/netstandard2.0/System.Security.Principal.Windows.dll", + "ref/netstandard2.0/System.Security.Principal.Windows.xml", + "ref/uap10.0.16299/_._", + "runtimes/unix/lib/netcoreapp2.0/System.Security.Principal.Windows.dll", + "runtimes/unix/lib/netcoreapp2.0/System.Security.Principal.Windows.xml", + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll", + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.xml", + "runtimes/win/lib/net46/System.Security.Principal.Windows.dll", + "runtimes/win/lib/net461/System.Security.Principal.Windows.dll", + "runtimes/win/lib/net461/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netcoreapp2.0/System.Security.Principal.Windows.dll", + "runtimes/win/lib/netcoreapp2.0/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll", + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netstandard1.3/System.Security.Principal.Windows.dll", + "runtimes/win/lib/uap10.0.16299/_._", + "system.security.principal.windows.5.0.0.nupkg.sha512", + "system.security.principal.windows.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "ZstdSharp.Port/0.7.3": { + "sha512": "U9Ix4l4cl58Kzz1rJzj5hoVTjmbx1qGMwzAcbv1j/d3NzrFaESIurQyg+ow4mivCgkE3S413y+U9k4WdnEIkRA==", + "type": "package", + "path": "zstdsharp.port/0.7.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net461/ZstdSharp.dll", + "lib/net5.0/ZstdSharp.dll", + "lib/net6.0/ZstdSharp.dll", + "lib/net7.0/ZstdSharp.dll", + "lib/netcoreapp3.1/ZstdSharp.dll", + "lib/netstandard2.0/ZstdSharp.dll", + "lib/netstandard2.1/ZstdSharp.dll", + "zstdsharp.port.0.7.3.nupkg.sha512", + "zstdsharp.port.nuspec" + ] + }, + "Entity/1.0.0": { + "type": "project", + "path": "../Entity/Entity.csproj", + "msbuildProject": "../Entity/Entity.csproj" + }, + "ThirdParty/1.0.0": { + "type": "project", + "path": "../ThirdParty/ThirdParty.csproj", + "msbuildProject": "../ThirdParty/ThirdParty.csproj" + } + }, + "projectFileDependencyGroups": { + "net9.0": [ + "Entity >= 1.0.0" + ] + }, + "packageFolders": { + "C:\\Users\\FIREBAT\\.nuget\\packages\\": {}, + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj", + "projectName": "Hotfix", + "projectPath": "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\Hotfix\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net9.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "projectReferences": { + "D:\\work\\Fishing2Server\\Entity\\Entity.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/Hotfix/obj/project.nuget.cache b/Hotfix/obj/project.nuget.cache new file mode 100644 index 0000000..177994e --- /dev/null +++ b/Hotfix/obj/project.nuget.cache @@ -0,0 +1,34 @@ +{ + "version": 2, + "dgSpecHash": "X6oCWCLPCsk=", + "success": true, + "projectFilePath": "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj", + "expectedPackageFiles": [ + "C:\\Users\\FIREBAT\\.nuget\\packages\\commandlineparser\\2.9.1\\commandlineparser.2.9.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\dnsclient\\1.6.1\\dnsclient.1.6.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\fantasy-net\\2025.2.0\\fantasy-net.2025.2.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\8.0.0\\microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\8.0.0\\microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.abstractions\\8.14.0\\microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.jsonwebtokens\\8.14.0\\microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.logging\\8.14.0\\microsoft.identitymodel.logging.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.tokens\\8.14.0\\microsoft.identitymodel.tokens.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.netcore.platforms\\5.0.0\\microsoft.netcore.platforms.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.win32.registry\\5.0.0\\microsoft.win32.registry.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\mongodb.bson\\3.5.0\\mongodb.bson.3.5.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\mongodb.driver\\3.5.0\\mongodb.driver.3.5.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\newtonsoft.json\\13.0.4\\newtonsoft.json.13.0.4.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\protobuf-net\\3.2.56\\protobuf-net.3.2.56.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\protobuf-net.core\\3.2.56\\protobuf-net.core.3.2.56.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\sharpcompress\\0.30.1\\sharpcompress.0.30.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\snappier\\1.0.0\\snappier.1.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.buffers\\4.5.1\\system.buffers.4.5.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.identitymodel.tokens.jwt\\8.14.0\\system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.memory\\4.5.5\\system.memory.4.5.5.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\5.0.0\\system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.security.accesscontrol\\5.0.0\\system.security.accesscontrol.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.security.principal.windows\\5.0.0\\system.security.principal.windows.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\zstdsharp.port\\0.7.3\\zstdsharp.port.0.7.3.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/Hotfix/obj/project.packagespec.json b/Hotfix/obj/project.packagespec.json new file mode 100644 index 0000000..7ed4dbd --- /dev/null +++ b/Hotfix/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj","projectName":"Hotfix","projectPath":"D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj","outputPath":"D:\\work\\Fishing2Server\\Hotfix\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"],"originalTargetFrameworks":["net9.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net9.0":{"targetAlias":"net9.0","projectReferences":{"D:\\work\\Fishing2Server\\Entity\\Entity.csproj":{"projectPath":"D:\\work\\Fishing2Server\\Entity\\Entity.csproj"}}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"},"SdkAnalysisLevel":"9.0.300"}"frameworks":{"net9.0":{"targetAlias":"net9.0","imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/Hotfix/obj/rider.project.model.nuget.info b/Hotfix/obj/rider.project.model.nuget.info new file mode 100644 index 0000000..8cd404e --- /dev/null +++ b/Hotfix/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17628533859080463 \ No newline at end of file diff --git a/Hotfix/obj/rider.project.restore.info b/Hotfix/obj/rider.project.restore.info new file mode 100644 index 0000000..3a75255 --- /dev/null +++ b/Hotfix/obj/rider.project.restore.info @@ -0,0 +1 @@ +17628541514897177 \ No newline at end of file diff --git a/Main/Fantasy.config b/Main/Fantasy.config deleted file mode 100644 index 20e6eb1..0000000 --- a/Main/Fantasy.config +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Main/Fantasy.json b/Main/Fantasy.json deleted file mode 100644 index f999bc2..0000000 --- a/Main/Fantasy.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} \ No newline at end of file diff --git a/Main/Fantasy.xsd b/Main/Fantasy.xsd deleted file mode 100644 index 06b1ecf..0000000 --- a/Main/Fantasy.xsd +++ /dev/null @@ -1,302 +0,0 @@ - - - - - - - Fantasy框架配置文件根元素 - - - - - - 配置表路径设置 - - - - - ID生成器配置 - - - - - 网络运行时配置 - - - - - 会话运行时配置 - - - - - 服务器配置 - - - - - - - - - - - 配置表文件路径 - - - - - - - - - ID生成器规则类型 - - - - - - 默认生成器,Scene最大为65535个 - - - - - ID中包含World,可解决合区ID重复问题,但Scene数量限制到255个 - - - - - - - - - - - - - 机器配置列表 - - - - - 进程配置列表 - - - - - 世界配置列表 - - - - - 场景配置列表 - - - - - - - - - - - - - - - - 机器ID - - - - - 外网IP地址 - - - - - 外网绑定IP地址 - - - - - 内网绑定IP地址 - - - - - - - - - - - - - - - 进程ID - - - - - 所属机器ID - - - - - 启动分组 - - - - - - - - - - - - - - - 世界ID - - - - - 世界名称 - - - - - 数据库连接字符串 - - - - - 数据库名称 - - - - - 数据库类型 - - - - - - - - - - - - - - - - - - - - - 场景ID - - - - - 进程配置ID - - - - - 世界配置ID - - - - - 场景运行模式 - - - - - - - - - - - - 场景类型字符串 - - - - - 网络协议类型 - - - - - - - - - - - - - - 外网端口 - - - - - 内网端口 - - - - - 场景类型数值 - - - - - - - - - 服务器内部网络协议 - - - - - - - - - - - 消息体最大长度(字节),默认1048560字节(约1.02MB) - - - - - - - - - Session idle check timeout (in milliseconds) - - - - - Session idle check interval (in milliseconds) - - - - - \ No newline at end of file diff --git a/Main/Main.csproj b/Main/Main.csproj index 8bdb6b4..062c0e0 100644 --- a/Main/Main.csproj +++ b/Main/Main.csproj @@ -1,41 +1,28 @@ - + - - Exe - enable - enable - default - net9.0 - - - - ../Bin/Debug/ - - - - ../Bin/Release/ - - - - - - - - - - - Always - - - Always - - - Always - - - - - - - - + + Exe + net9.0 + Main + latest + enable + enable + false + true + + + + + + + + + + + Always + + + Always + + + \ No newline at end of file diff --git a/Main/Program.cs b/Main/Program.cs index e56ef4f..e7d2765 100644 --- a/Main/Program.cs +++ b/Main/Program.cs @@ -1,33 +1,32 @@ -using Fantasy; -using Fantasy.ConfigTable; -using Fantasy.Helper; -using Fantasy.IdFactory; -using Fantasy.Platform.Net; +// ================================================================================ +// Fantasy.Net 服务器应用程序入口 +// ================================================================================ +// 本文件是 Fantasy.Net 分布式游戏服务器的主入口点 +// +// 初始化流程: +// 1. 强制加载引用程序集,触发 ModuleInitializer 执行 +// 2. 配置日志基础设施(NLog) +// 3. 启动 Fantasy.Net 框架 +// ================================================================================ +using Fantasy; +using NBF.ConfigTable; - -// 设置ID生成规则 -IdFactoryHelper.Initialize(IdFactoryType.World); -// // 获取配置文件 -// // 比如通过远程获取这个配置文件,这样可以多组服务器共享一套配置了 -// var machineConfigText = await FileHelper.GetTextByRelativePath("../../../Config/Json/Server/MachineConfigData.Json"); -// var processConfigText = await FileHelper.GetTextByRelativePath("../../../Config/Json/Server/ProcessConfigData.Json"); -// var worldConfigText = await FileHelper.GetTextByRelativePath("../../../Config/Json/Server/WorldConfigData.Json"); -// var sceneConfigText = await FileHelper.GetTextByRelativePath("../../../Config/Json/Server/SceneConfigData.Json"); -// // 初始化配置文件 -// // 如果重复初始化方法会覆盖掉上一次的数据,非常适合热重载时使用 -// MachineConfigData.Initialize(machineConfigText); -// ProcessConfigData.Initialize(processConfigText); -// WorldConfigData.Initialize(worldConfigText); -// SceneConfigData.Initialize(sceneConfigText); - -//解析配置文件 -var gameConfigText = await FileHelper.GetTextByRelativePath("../../../Config/Json/configs.Json"); -ConfigTableHelper.Initialize(gameConfigText,NB.AssemblyHelper.Assemblies); - -// 注册日志模块到框架 -// 开发者可以自己注册日志系统到框架,只要实现Fantasy.ILog接口就可以。 -// 这里用的是NLog日志系统注册到框架中。 -Log.Register(new Fantasy.NLog("Server")); - -await Entry.Start(NB.AssemblyHelper.Assemblies); +try +{ + // 初始化引用的程序集,确保 ModuleInitializer 执行 + // .NET 采用延迟加载机制 - 仅当类型被引用时才加载程序集 + // 通过访问 AssemblyMarker 强制加载程序集并调用 ModuleInitializer + // 注意:Native AOT 不存在延迟加载问题,所有程序集在编译时打包 + AssemblyHelper.Initialize(); + ConfigTableHelper.Initialize(); + // 配置 NLog 日志基础设施 + var logger = new Fantasy.NLog("Server"); + // 使用 NLog 日志系统启动 Fantasy.Net 框架 + await Fantasy.Platform.Net.Entry.Start(logger); +} +catch (Exception ex) +{ + Console.Error.WriteLine($"服务器初始化过程中发生致命错误:{ex}"); + Environment.Exit(1); +} diff --git a/Main/Properties/launchSettings.json b/Main/Properties/launchSettings.json index c31a6c9..c385745 100644 --- a/Main/Properties/launchSettings.json +++ b/Main/Properties/launchSettings.json @@ -1,11 +1,26 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { - "Main": { + "Develop": { "commandName": "Project", -// "workingDirectory": "$(OutputPath)", - "environmentVariables": {}, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, "commandLineArgs": "--m Develop" + }, + "Release-Gate": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Production" + }, + "commandLineArgs": "--m Release --pid 1" + }, + "Release-Game": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Production" + }, + "commandLineArgs": "--m Release --pid 2" } } } \ No newline at end of file diff --git a/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111114.Info.log b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111114.Info.log new file mode 100644 index 0000000..108f9d4 --- /dev/null +++ b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111114.Info.log @@ -0,0 +1,48 @@ +2025-11-11 14:39:56.8481 + +========================================================================== + + ███████╗ █████╗ ███╗ ██╗████████╗ █████╗ ██████╗ ██╗ ██╗ + ██╔════╝██╔══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔════╝ ╚██╗ ██╔╝ + █████╗ ███████║██╔██╗ ██║ ██║ ███████║╚█████╗ ╚████╔╝ + ██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██╔══██║╚════██║ ╚██╔╝ + ██║ ██║ ██║██║ ╚████║ ██║ ██║ ██║██████╔╝ ██║ + ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ + + Version : Fantasy 2.0 Official version +========================================================================== + +2025-11-11 14:39:57.0402 Current inner network protocol:TCP +2025-11-11 14:39:57.0402 Max Message Size(byte):1048560 +2025-11-11 14:39:57.0402 Current session idle timeout:8000 +2025-11-11 14:39:57.0402 Session-check interval:5000 +2025-11-11 14:39:58.8391 SceneConfigId = 1001 networkTarget = Inner TCPServer Listen 127.0.0.1:11002 +2025-11-11 14:39:59.5787 SceneConfigId = 1001 networkTarget = Outer KCPServer Listen 127.0.0.1:20000 +2025-11-11 14:39:59.5787 Process:1 Startup Complete SceneCount:1 +2025-11-11 14:51:01.5083 + +========================================================================== + + ███████╗ █████╗ ███╗ ██╗████████╗ █████╗ ██████╗ ██╗ ██╗ + ██╔════╝██╔══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔════╝ ╚██╗ ██╔╝ + █████╗ ███████║██╔██╗ ██║ ██║ ███████║╚█████╗ ╚████╔╝ + ██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██╔══██║╚════██║ ╚██╔╝ + ██║ ██║ ██║██║ ╚████║ ██║ ██║ ██║██████╔╝ ██║ + ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ + + Version : Fantasy 2.0 Official version +========================================================================== + +2025-11-11 14:51:01.6269 Current inner network protocol:TCP +2025-11-11 14:51:01.6269 Max Message Size(byte):1048560 +2025-11-11 14:51:01.6269 Current session idle timeout:8000 +2025-11-11 14:51:01.6269 Session-check interval:5000 +2025-11-11 14:51:02.8337 SceneConfigId = 1001 networkTarget = Inner TCPServer Listen 127.0.0.1:11001 +2025-11-11 14:51:03.4919 SceneConfigId = 1001 networkTarget = Outer KCPServer Listen 127.0.0.1:20001 +2025-11-11 14:51:04.1272 SceneConfigId = 1002 networkTarget = Inner TCPServer Listen 127.0.0.1:11011 +2025-11-11 14:51:04.7592 SceneConfigId = 1003 networkTarget = Inner TCPServer Listen 127.0.0.1:11021 +2025-11-11 14:51:05.3647 SceneConfigId = 1003 networkTarget = Outer KCPServer Listen 127.0.0.1:20000 +2025-11-11 14:51:06.0023 SceneConfigId = 1004 networkTarget = Inner TCPServer Listen 127.0.0.1:11031 +2025-11-11 14:51:06.6302 SceneConfigId = 1006 networkTarget = Inner TCPServer Listen 127.0.0.1:11051 +2025-11-11 14:51:07.2603 SceneConfigId = 1007 networkTarget = Inner TCPServer Listen 127.0.0.1:11061 +2025-11-11 14:51:07.2603 Process:1 Startup Complete SceneCount:6 diff --git a/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111115.Debug.log b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111115.Debug.log new file mode 100644 index 0000000..e69de29 diff --git a/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111115.Info.log b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111115.Info.log new file mode 100644 index 0000000..5e2e96f --- /dev/null +++ b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111115.Info.log @@ -0,0 +1,105 @@ +2025-11-11 15:09:56.1103 + +========================================================================== + + ███████╗ █████╗ ███╗ ██╗████████╗ █████╗ ██████╗ ██╗ ██╗ + ██╔════╝██╔══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔════╝ ╚██╗ ██╔╝ + █████╗ ███████║██╔██╗ ██║ ██║ ███████║╚█████╗ ╚████╔╝ + ██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██╔══██║╚════██║ ╚██╔╝ + ██║ ██║ ██║██║ ╚████║ ██║ ██║ ██║██████╔╝ ██║ + ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ + + Version : Fantasy 2.0 Official version +========================================================================== + +2025-11-11 15:09:56.2193 Current inner network protocol:TCP +2025-11-11 15:09:56.2193 Max Message Size(byte):1048560 +2025-11-11 15:09:56.2193 Current session idle timeout:8000 +2025-11-11 15:09:56.2193 Session-check interval:5000 +2025-11-11 15:09:57.3814 SceneConfigId = 1001 networkTarget = Inner TCPServer Listen 127.0.0.1:11001 +2025-11-11 15:09:58.0219 SceneConfigId = 1001 networkTarget = Outer KCPServer Listen 127.0.0.1:20001 +2025-11-11 15:09:58.0219 (OnCreateSceneEvent.cs:12) Scene created: SceneType=1, SceneId=67371008 +2025-11-11 15:09:58.6649 SceneConfigId = 1002 networkTarget = Inner TCPServer Listen 127.0.0.1:11011 +2025-11-11 15:09:58.6649 (OnCreateSceneEvent.cs:12) Scene created: SceneType=1, SceneId=134479872 +2025-11-11 15:09:59.3427 SceneConfigId = 1003 networkTarget = Inner TCPServer Listen 127.0.0.1:11021 +2025-11-11 15:09:59.9745 SceneConfigId = 1003 networkTarget = Outer KCPServer Listen 127.0.0.1:20000 +2025-11-11 15:09:59.9745 (OnCreateSceneEvent.cs:12) Scene created: SceneType=2, SceneId=201588736 +2025-11-11 15:09:59.9978 (OnCreateSceneEvent.cs:53) 初始化 Gate 场景: 201588736 +2025-11-11 15:10:00.6414 SceneConfigId = 1004 networkTarget = Inner TCPServer Listen 127.0.0.1:11031 +2025-11-11 15:10:00.6647 (OnCreateSceneEvent.cs:12) Scene created: SceneType=3, SceneId=268697600 +2025-11-11 15:10:01.3079 SceneConfigId = 1006 networkTarget = Inner TCPServer Listen 127.0.0.1:11051 +2025-11-11 15:10:01.3316 (OnCreateSceneEvent.cs:12) Scene created: SceneType=4, SceneId=402915328 +2025-11-11 15:10:01.9900 SceneConfigId = 1007 networkTarget = Inner TCPServer Listen 127.0.0.1:11061 +2025-11-11 15:10:01.9900 Process:1 Startup Complete SceneCount:6 +2025-11-11 15:10:01.9900 (OnCreateSceneEvent.cs:12) Scene created: SceneType=5, SceneId=470024192 +2025-11-11 15:15:12.1015 + +========================================================================== + + ███████╗ █████╗ ███╗ ██╗████████╗ █████╗ ██████╗ ██╗ ██╗ + ██╔════╝██╔══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔════╝ ╚██╗ ██╔╝ + █████╗ ███████║██╔██╗ ██║ ██║ ███████║╚█████╗ ╚████╔╝ + ██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██╔══██║╚════██║ ╚██╔╝ + ██║ ██║ ██║██║ ╚████║ ██║ ██║ ██║██████╔╝ ██║ + ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ + + Version : Fantasy 2.0 Official version +========================================================================== + +2025-11-11 15:15:12.2186 Current inner network protocol:TCP +2025-11-11 15:15:12.2186 Max Message Size(byte):1048560 +2025-11-11 15:15:12.2186 Current session idle timeout:8000 +2025-11-11 15:15:12.2186 Session-check interval:5000 +2025-11-11 15:15:13.4932 SceneConfigId = 1001 networkTarget = Inner TCPServer Listen 127.0.0.1:11001 +2025-11-11 15:15:14.1458 SceneConfigId = 1001 networkTarget = Outer KCPServer Listen 127.0.0.1:20001 +2025-11-11 15:15:14.1567 (OnCreateSceneEvent.cs:12) Scene created: SceneType=1, SceneId=67371008 SceneConfigId=1001 +2025-11-11 15:15:14.7815 SceneConfigId = 1002 networkTarget = Inner TCPServer Listen 127.0.0.1:11011 +2025-11-11 15:15:14.7815 (OnCreateSceneEvent.cs:12) Scene created: SceneType=1, SceneId=134479872 SceneConfigId=1002 +2025-11-11 15:15:15.4072 SceneConfigId = 1003 networkTarget = Inner TCPServer Listen 127.0.0.1:11021 +2025-11-11 15:15:16.0081 SceneConfigId = 1003 networkTarget = Outer KCPServer Listen 127.0.0.1:20000 +2025-11-11 15:15:16.0081 (OnCreateSceneEvent.cs:12) Scene created: SceneType=2, SceneId=201588736 SceneConfigId=1003 +2025-11-11 15:15:16.0325 (OnCreateSceneEvent.cs:53) 初始化 Gate 场景: 201588736 +2025-11-11 15:15:16.6539 SceneConfigId = 1004 networkTarget = Inner TCPServer Listen 127.0.0.1:11031 +2025-11-11 15:15:16.6539 (OnCreateSceneEvent.cs:12) Scene created: SceneType=3, SceneId=268697600 SceneConfigId=1004 +2025-11-11 15:15:17.3013 SceneConfigId = 1006 networkTarget = Inner TCPServer Listen 127.0.0.1:11051 +2025-11-11 15:15:17.3031 (OnCreateSceneEvent.cs:12) Scene created: SceneType=4, SceneId=402915328 SceneConfigId=1006 +2025-11-11 15:15:17.9310 SceneConfigId = 1007 networkTarget = Inner TCPServer Listen 127.0.0.1:11061 +2025-11-11 15:15:17.9310 Process:1 Startup Complete SceneCount:6 +2025-11-11 15:15:17.9310 (OnCreateSceneEvent.cs:12) Scene created: SceneType=5, SceneId=470024192 SceneConfigId=1007 +2025-11-11 15:21:16.0456 + +========================================================================== + + ███████╗ █████╗ ███╗ ██╗████████╗ █████╗ ██████╗ ██╗ ██╗ + ██╔════╝██╔══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔════╝ ╚██╗ ██╔╝ + █████╗ ███████║██╔██╗ ██║ ██║ ███████║╚█████╗ ╚████╔╝ + ██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██╔══██║╚════██║ ╚██╔╝ + ██║ ██║ ██║██║ ╚████║ ██║ ██║ ██║██████╔╝ ██║ + ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ + + Version : Fantasy 2.0 Official version +========================================================================== + +2025-11-11 15:21:16.1627 Current inner network protocol:TCP +2025-11-11 15:21:16.1627 Max Message Size(byte):1048560 +2025-11-11 15:21:16.1627 Current session idle timeout:8000 +2025-11-11 15:21:16.1627 Session-check interval:5000 +2025-11-11 15:21:17.3250 SceneConfigId = 1001 networkTarget = Inner TCPServer Listen 127.0.0.1:11001 +2025-11-11 15:21:17.9730 SceneConfigId = 1001 networkTarget = Outer KCPServer Listen 127.0.0.1:20001 +2025-11-11 15:21:17.9852 (OnCreateSceneEvent.cs:13) Scene created: SceneType=1, SceneId=67371008 SceneConfigId=1001 +2025-11-11 15:21:18.6143 SceneConfigId = 1002 networkTarget = Inner TCPServer Listen 127.0.0.1:11011 +2025-11-11 15:21:18.6143 (OnCreateSceneEvent.cs:13) Scene created: SceneType=1, SceneId=134479872 SceneConfigId=1002 +2025-11-11 15:21:19.2440 SceneConfigId = 1003 networkTarget = Inner TCPServer Listen 127.0.0.1:11021 +2025-11-11 15:21:19.8390 SceneConfigId = 1003 networkTarget = Outer KCPServer Listen 127.0.0.1:20000 +2025-11-11 15:21:19.8626 (OnCreateSceneEvent.cs:13) Scene created: SceneType=2, SceneId=201588736 SceneConfigId=1003 +2025-11-11 15:21:19.8626 (OnCreateSceneEvent.cs:173) 初始化 Addressable 场景: 201588736 +2025-11-11 15:21:20.4949 SceneConfigId = 1004 networkTarget = Inner TCPServer Listen 127.0.0.1:11031 +2025-11-11 15:21:20.4949 (OnCreateSceneEvent.cs:13) Scene created: SceneType=3, SceneId=268697600 SceneConfigId=1004 +2025-11-11 15:21:20.5214 (OnCreateSceneEvent.cs:52) 初始化 Gate 场景: 268697600 +2025-11-11 15:21:21.1476 SceneConfigId = 1006 networkTarget = Inner TCPServer Listen 127.0.0.1:11051 +2025-11-11 15:21:21.1476 (OnCreateSceneEvent.cs:13) Scene created: SceneType=4, SceneId=402915328 SceneConfigId=1006 +2025-11-11 15:21:21.1704 (OnCreateSceneEvent.cs:107) 初始化 Game 场景: 402915328 +2025-11-11 15:21:21.7961 SceneConfigId = 1007 networkTarget = Inner TCPServer Listen 127.0.0.1:11061 +2025-11-11 15:21:21.7961 Process:1 Startup Complete SceneCount:6 +2025-11-11 15:21:21.7961 (OnCreateSceneEvent.cs:13) Scene created: SceneType=5, SceneId=470024192 SceneConfigId=1007 +2025-11-11 15:21:21.7961 (OnCreateSceneEvent.cs:94) 初始化 Map 场景: 470024192 diff --git a/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111115.Warn.log b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111115.Warn.log new file mode 100644 index 0000000..a6f0cc8 --- /dev/null +++ b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111115.Warn.log @@ -0,0 +1,10 @@ +2025-11-11 15:09:58.0219 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 1 +2025-11-11 15:09:58.6893 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 1 +2025-11-11 15:10:00.6647 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 3 +2025-11-11 15:10:01.3316 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 4 +2025-11-11 15:10:01.9900 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 5 +2025-11-11 15:15:14.1567 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 1 +2025-11-11 15:15:14.7815 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 1 +2025-11-11 15:15:16.6783 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 3 +2025-11-11 15:15:17.3031 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 4 +2025-11-11 15:15:17.9310 (OnCreateSceneEvent.cs:42) 未处理的 SceneType: 5 diff --git a/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111116.Info.log b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111116.Info.log new file mode 100644 index 0000000..0555e0d --- /dev/null +++ b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111116.Info.log @@ -0,0 +1,39 @@ +2025-11-11 16:50:19.9307 + +========================================================================== + + ███████╗ █████╗ ███╗ ██╗████████╗ █████╗ ██████╗ ██╗ ██╗ + ██╔════╝██╔══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔════╝ ╚██╗ ██╔╝ + █████╗ ███████║██╔██╗ ██║ ██║ ███████║╚█████╗ ╚████╔╝ + ██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██╔══██║╚════██║ ╚██╔╝ + ██║ ██║ ██║██║ ╚████║ ██║ ██║ ██║██████╔╝ ██║ + ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ + + Version : Fantasy 2.0 Official version +========================================================================== + +2025-11-11 16:50:20.0695 Current inner network protocol:TCP +2025-11-11 16:50:20.0695 Max Message Size(byte):1048560 +2025-11-11 16:50:20.0695 Current session idle timeout:8000 +2025-11-11 16:50:20.0695 Session-check interval:5000 +2025-11-11 16:50:21.8247 SceneConfigId = 1001 networkTarget = Inner TCPServer Listen 127.0.0.1:11001 +2025-11-11 16:50:22.6382 SceneConfigId = 1001 networkTarget = Outer KCPServer Listen 127.0.0.1:20001 +2025-11-11 16:50:22.6535 (OnCreateSceneEvent.cs:15) Scene created: SceneType=1, SceneId=67371008 SceneConfigId=1001 +2025-11-11 16:50:22.6535 (OnCreateSceneEvent.cs:178) 初始化 Addressable 场景: 67371008 +2025-11-11 16:50:23.5178 SceneConfigId = 1002 networkTarget = Inner TCPServer Listen 127.0.0.1:11011 +2025-11-11 16:50:23.5230 (OnCreateSceneEvent.cs:15) Scene created: SceneType=1, SceneId=134479872 SceneConfigId=1002 +2025-11-11 16:50:23.5230 (OnCreateSceneEvent.cs:178) 初始化 Addressable 场景: 134479872 +2025-11-11 16:50:24.3026 SceneConfigId = 1003 networkTarget = Inner TCPServer Listen 127.0.0.1:11021 +2025-11-11 16:50:24.9543 SceneConfigId = 1003 networkTarget = Outer KCPServer Listen 127.0.0.1:20000 +2025-11-11 16:50:24.9543 (OnCreateSceneEvent.cs:15) Scene created: SceneType=2, SceneId=201588736 SceneConfigId=1003 +2025-11-11 16:50:24.9543 (OnCreateSceneEvent.cs:57) 初始化 Gate 场景: 201588736 +2025-11-11 16:50:25.6167 SceneConfigId = 1004 networkTarget = Inner TCPServer Listen 127.0.0.1:11031 +2025-11-11 16:50:25.6167 (OnCreateSceneEvent.cs:15) Scene created: SceneType=3, SceneId=268697600 SceneConfigId=1004 +2025-11-11 16:50:25.6404 (OnCreateSceneEvent.cs:112) 初始化 Game 场景: 268697600 +2025-11-11 16:50:26.2863 SceneConfigId = 1006 networkTarget = Inner TCPServer Listen 127.0.0.1:11051 +2025-11-11 16:50:26.2863 (OnCreateSceneEvent.cs:15) Scene created: SceneType=4, SceneId=402915328 SceneConfigId=1006 +2025-11-11 16:50:26.2863 (OnCreateSceneEvent.cs:105) 初始化 Social 场景: 402915328 +2025-11-11 16:50:26.9385 SceneConfigId = 1007 networkTarget = Inner TCPServer Listen 127.0.0.1:11061 +2025-11-11 16:50:26.9385 Process:1 Startup Complete SceneCount:6 +2025-11-11 16:50:26.9385 (OnCreateSceneEvent.cs:15) Scene created: SceneType=5, SceneId=470024192 SceneConfigId=1007 +2025-11-11 16:50:26.9385 (OnCreateSceneEvent.cs:99) 初始化 Map 场景: 470024192 diff --git a/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111117.Debug.log b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111117.Debug.log new file mode 100644 index 0000000..23396fc --- /dev/null +++ b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111117.Debug.log @@ -0,0 +1,5 @@ +2025-11-11 17:41:21.9158 (C2A_LoginRequestHandler.cs:66) Login 当前的服务器是:1001 +2025-11-11 17:41:22.4012 (PlayerManageComponentSystem.cs:44) 检查账号是否在缓存中 +2025-11-11 17:41:22.4377 (PlayerManageComponentSystem.cs:59) 检查到账号在数据库中 +2025-11-11 17:41:22.5206 (PlayerManageComponentSystem.cs:71) 把当前账号添加到缓存中 +2025-11-11 17:41:22.5812 (C2G_LoginRequestHandler.cs:44) 当前的Gate服务器:1003 accountId:445703427981574146 diff --git a/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111117.Error.log b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111117.Error.log new file mode 100644 index 0000000..024585a --- /dev/null +++ b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111117.Error.log @@ -0,0 +1,5 @@ +2025-11-11 17:37:04.6575 System.NullReferenceException: Object reference not set to an instance of an object. + at NB.Authentication.AuthenticationComponentSystem.Login(AuthenticationComponent self, String userName, String password) in D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\Authentication\System\AuthenticationComponentSystem.cs:line 101 + at NB.Authentication.AuthenticationHelper.Login(Scene scene, String userName, String password) in D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\Authentication\System\AuthenticationHelper.cs:line 18 + at NB.Authentication.Handler.C2A_LoginRequestHandler.Run(Session session, C2A_LoginRequest request, A2C_LoginResponse response, Action reply) in D:\work\Fishing2ServerNew\Fishing2\Server\Hotfix\Authentication\Handler\C2A_LoginRequestHandler.cs:line 25 + at Fantasy.Network.Interface.MessageRPC`2.Handle(Session session, UInt32 rpcId, UInt32 messageTypeCode, Object message) diff --git a/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111117.Info.log b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111117.Info.log new file mode 100644 index 0000000..7721ca1 --- /dev/null +++ b/Main/bin/Debug/Logs/Server/Server20251111/Server..2025111117.Info.log @@ -0,0 +1,105 @@ +2025-11-11 17:31:29.7488 + +========================================================================== + + ███████╗ █████╗ ███╗ ██╗████████╗ █████╗ ██████╗ ██╗ ██╗ + ██╔════╝██╔══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔════╝ ╚██╗ ██╔╝ + █████╗ ███████║██╔██╗ ██║ ██║ ███████║╚█████╗ ╚████╔╝ + ██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██╔══██║╚════██║ ╚██╔╝ + ██║ ██║ ██║██║ ╚████║ ██║ ██║ ██║██████╔╝ ██║ + ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ + + Version : Fantasy 2.0 Official version +========================================================================== + +2025-11-11 17:31:29.8486 Current inner network protocol:TCP +2025-11-11 17:31:29.8486 Max Message Size(byte):1048560 +2025-11-11 17:31:29.8486 Current session idle timeout:8000 +2025-11-11 17:31:29.8486 Session-check interval:5000 +2025-11-11 17:31:31.0914 SceneConfigId = 1001 networkTarget = Inner TCPServer Listen 127.0.0.1:11001 +2025-11-11 17:31:31.7608 SceneConfigId = 1001 networkTarget = Outer KCPServer Listen 127.0.0.1:20001 +2025-11-11 17:31:31.7934 (OnCreateSceneEvent.cs:21) Scene created: SceneType=1, SceneId=67371008 SceneConfigId=1001 +2025-11-11 17:31:31.7934 (AuthenticationComponentSystem.cs:40) 鉴权服务器启动成功!Position:0 AuthenticationCount:1 +2025-11-11 17:31:32.5156 SceneConfigId = 1002 networkTarget = Inner TCPServer Listen 127.0.0.1:11011 +2025-11-11 17:31:32.5395 (OnCreateSceneEvent.cs:21) Scene created: SceneType=2, SceneId=134479872 SceneConfigId=1002 +2025-11-11 17:31:32.5395 (OnCreateSceneEvent.cs:221) 初始化 Addressable 场景: 134479872 +2025-11-11 17:31:33.2217 SceneConfigId = 1003 networkTarget = Inner TCPServer Listen 127.0.0.1:11021 +2025-11-11 17:31:33.8288 SceneConfigId = 1003 networkTarget = Outer KCPServer Listen 127.0.0.1:20000 +2025-11-11 17:31:33.8288 (OnCreateSceneEvent.cs:21) Scene created: SceneType=3, SceneId=201588736 SceneConfigId=1003 +2025-11-11 17:31:33.8540 (OnCreateSceneEvent.cs:76) 初始化 Gate 场景: 201588736 +2025-11-11 17:31:34.4841 SceneConfigId = 1004 networkTarget = Inner TCPServer Listen 127.0.0.1:11031 +2025-11-11 17:31:34.4841 (OnCreateSceneEvent.cs:21) Scene created: SceneType=4, SceneId=268697600 SceneConfigId=1004 +2025-11-11 17:31:34.5094 (OnCreateSceneEvent.cs:152) 初始化 Game 场景: 268697600 +2025-11-11 17:31:35.1456 SceneConfigId = 1006 networkTarget = Inner TCPServer Listen 127.0.0.1:11051 +2025-11-11 17:31:35.1456 (OnCreateSceneEvent.cs:21) Scene created: SceneType=5, SceneId=402915328 SceneConfigId=1006 +2025-11-11 17:31:35.1700 (OnCreateSceneEvent.cs:141) 初始化 Social 场景: 402915328 +2025-11-11 17:31:35.8223 SceneConfigId = 1007 networkTarget = Inner TCPServer Listen 127.0.0.1:11061 +2025-11-11 17:31:35.8223 Process:1 Startup Complete SceneCount:6 +2025-11-11 17:31:35.8223 (OnCreateSceneEvent.cs:21) Scene created: SceneType=6, SceneId=470024192 SceneConfigId=1007 +2025-11-11 17:31:35.8223 (OnCreateSceneEvent.cs:123) 初始化 Map 场景: 470024192 +2025-11-11 17:31:35.8223 (OnCreateSceneEvent.cs:124) 创建地图场景=== +2025-11-11 17:31:35.8223 (OnCreateSceneEvent.cs:133) 测试房间代码 = 13AHVL +2025-11-11 17:37:04.3480 (C2A_LoginRequestHandler.cs:24) 登录服场景 67371008 4311744512 1001 +2025-11-11 17:41:05.5613 + +========================================================================== + + ███████╗ █████╗ ███╗ ██╗████████╗ █████╗ ██████╗ ██╗ ██╗ + ██╔════╝██╔══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔════╝ ╚██╗ ██╔╝ + █████╗ ███████║██╔██╗ ██║ ██║ ███████║╚█████╗ ╚████╔╝ + ██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██╔══██║╚════██║ ╚██╔╝ + ██║ ██║ ██║██║ ╚████║ ██║ ██║ ██║██████╔╝ ██║ + ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ + + Version : Fantasy 2.0 Official version +========================================================================== + +2025-11-11 17:41:05.6797 Current inner network protocol:TCP +2025-11-11 17:41:05.6797 Max Message Size(byte):1048560 +2025-11-11 17:41:05.6797 Current session idle timeout:8000 +2025-11-11 17:41:05.6797 Session-check interval:5000 +2025-11-11 17:41:06.3043 dbName:fantasy_main Initialize the db database and connect to the target. +2025-11-11 17:41:06.7567 dbName:fantasy_main Database connection successful. +2025-11-11 17:41:07.4480 SceneConfigId = 1001 networkTarget = Inner TCPServer Listen 127.0.0.1:11001 +2025-11-11 17:41:08.0920 SceneConfigId = 1001 networkTarget = Outer KCPServer Listen 127.0.0.1:20001 +2025-11-11 17:41:08.0983 dbName:fantasy_main Initialize the db database and connect to the target. +2025-11-11 17:41:08.0983 dbName:fantasy_main Database connection successful. +2025-11-11 17:41:08.0983 (OnCreateSceneEvent.cs:21) Scene created: SceneType=1, SceneId=67371008 SceneConfigId=1001 +2025-11-11 17:41:08.0983 (AuthenticationComponentSystem.cs:40) 鉴权服务器启动成功!Position:0 AuthenticationCount:1 +2025-11-11 17:41:08.7704 SceneConfigId = 1002 networkTarget = Inner TCPServer Listen 127.0.0.1:11011 +2025-11-11 17:41:08.7704 (OnCreateSceneEvent.cs:21) Scene created: SceneType=2, SceneId=134479872 SceneConfigId=1002 +2025-11-11 17:41:08.7704 dbName:fantasy_main Initialize the db database and connect to the target. +2025-11-11 17:41:08.7704 (OnCreateSceneEvent.cs:221) 初始化 Addressable 场景: 134479872 +2025-11-11 17:41:08.7704 dbName:fantasy_main Database connection successful. +2025-11-11 17:41:09.4204 SceneConfigId = 1003 networkTarget = Inner TCPServer Listen 127.0.0.1:11021 +2025-11-11 17:41:10.0569 SceneConfigId = 1003 networkTarget = Outer KCPServer Listen 127.0.0.1:20000 +2025-11-11 17:41:10.0569 (OnCreateSceneEvent.cs:21) Scene created: SceneType=3, SceneId=201588736 SceneConfigId=1003 +2025-11-11 17:41:10.0809 dbName:fantasy_main Initialize the db database and connect to the target. +2025-11-11 17:41:10.0809 (OnCreateSceneEvent.cs:76) 初始化 Gate 场景: 201588736 +2025-11-11 17:41:10.0809 dbName:fantasy_main Database connection successful. +2025-11-11 17:41:10.7352 SceneConfigId = 1004 networkTarget = Inner TCPServer Listen 127.0.0.1:11031 +2025-11-11 17:41:10.7578 (OnCreateSceneEvent.cs:21) Scene created: SceneType=4, SceneId=268697600 SceneConfigId=1004 +2025-11-11 17:41:10.7578 dbName:fantasy_main Initialize the db database and connect to the target. +2025-11-11 17:41:10.7578 (OnCreateSceneEvent.cs:152) 初始化 Game 场景: 268697600 +2025-11-11 17:41:10.7578 dbName:fantasy_main Database connection successful. +2025-11-11 17:41:11.4079 SceneConfigId = 1006 networkTarget = Inner TCPServer Listen 127.0.0.1:11051 +2025-11-11 17:41:11.4089 (OnCreateSceneEvent.cs:21) Scene created: SceneType=5, SceneId=402915328 SceneConfigId=1006 +2025-11-11 17:41:11.4089 dbName:fantasy_main Initialize the db database and connect to the target. +2025-11-11 17:41:11.4089 (OnCreateSceneEvent.cs:141) 初始化 Social 场景: 402915328 +2025-11-11 17:41:11.4089 dbName:fantasy_main Database connection successful. +2025-11-11 17:41:12.0503 SceneConfigId = 1007 networkTarget = Inner TCPServer Listen 127.0.0.1:11061 +2025-11-11 17:41:12.0503 Process:1 Startup Complete SceneCount:6 +2025-11-11 17:41:12.0503 (OnCreateSceneEvent.cs:21) Scene created: SceneType=6, SceneId=470024192 SceneConfigId=1007 +2025-11-11 17:41:12.0503 (OnCreateSceneEvent.cs:123) 初始化 Map 场景: 470024192 +2025-11-11 17:41:12.0503 (OnCreateSceneEvent.cs:124) 创建地图场景=== +2025-11-11 17:41:12.0503 (OnCreateSceneEvent.cs:133) 测试房间代码 = 13AHVL +2025-11-11 17:41:21.0963 (C2A_LoginRequestHandler.cs:24) 登录服场景 67371008 4311744512 1001 +2025-11-11 17:41:22.5377 (G2Common_EnterRequestHandler.cs:52) 登录到游戏服成功,id=-7928855407626289152 +2025-11-11 17:41:22.5720 (G2Common_EnterRequestHandler.cs:68) 登录到社交服成功,id=-7928856498547982336 +2025-11-11 17:41:22.5720 (G2Common_EnterRequestHandler.cs:84) 登录到地图服成功,id=-7928856494253015040 +2025-11-11 17:41:27.5033 (GateLoginHelper.cs:63) 断线的session id=-7928854312409628672 +2025-11-11 17:41:27.5033 (G2Common_ExitRequestHandler.cs:43) 退出游戏服成功== +2025-11-11 17:41:27.5033 (ChatUnitManageComponentSystem.cs:62) 退出当前聊天服== +2025-11-11 17:41:27.5033 (G2Common_ExitRequestHandler.cs:51) 退出聊天服成功== +2025-11-11 17:41:27.5214 (G2Common_ExitRequestHandler.cs:57) 退出房间服成功== +2025-11-11 17:41:27.5214 (GateUnitManageComponentSystem.cs:49) accountId:445703427981574146 下线成功 diff --git a/Tools/NetworkProtocol/CommandLine.dll b/Main/bin/Debug/net9.0/CommandLine.dll similarity index 100% rename from Tools/NetworkProtocol/CommandLine.dll rename to Main/bin/Debug/net9.0/CommandLine.dll diff --git a/Main/bin/Debug/net9.0/DnsClient.dll b/Main/bin/Debug/net9.0/DnsClient.dll new file mode 100644 index 0000000..39aa546 Binary files /dev/null and b/Main/bin/Debug/net9.0/DnsClient.dll differ diff --git a/Main/bin/Debug/net9.0/Entity.dll b/Main/bin/Debug/net9.0/Entity.dll new file mode 100644 index 0000000..e3649fb Binary files /dev/null and b/Main/bin/Debug/net9.0/Entity.dll differ diff --git a/Main/bin/Debug/net9.0/Entity.pdb b/Main/bin/Debug/net9.0/Entity.pdb new file mode 100644 index 0000000..aa1be2e Binary files /dev/null and b/Main/bin/Debug/net9.0/Entity.pdb differ diff --git a/Main/bin/Debug/net9.0/Fantasy-Net.dll b/Main/bin/Debug/net9.0/Fantasy-Net.dll new file mode 100644 index 0000000..9961ffb Binary files /dev/null and b/Main/bin/Debug/net9.0/Fantasy-Net.dll differ diff --git a/Main/bin/Debug/net9.0/Fantasy.config b/Main/bin/Debug/net9.0/Fantasy.config new file mode 100644 index 0000000..b50d8ab --- /dev/null +++ b/Main/bin/Debug/net9.0/Fantasy.config @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Main/bin/Debug/net9.0/Fantasy.xsd b/Main/bin/Debug/net9.0/Fantasy.xsd new file mode 100644 index 0000000..6a64f66 --- /dev/null +++ b/Main/bin/Debug/net9.0/Fantasy.xsd @@ -0,0 +1,345 @@ + + + + + + + Fantasy框架配置文件根元素 + + + + + + 配置表路径设置 + + + + + 网络运行时配置 + + + + + 会话运行时配置 + + + + + 服务器配置 + + + + + + + + + + + 配置表文件路径 + + + + + + + + + + 机器配置列表 + + + + + 进程配置列表 + + + + + 世界配置列表 + + + + + 场景配置列表 + + + + + 单位配置列表 + + + + + + + + + + + + + + + + 机器ID + + + + + 外网IP地址 + + + + + 外网绑定IP地址 + + + + + 内网绑定IP地址 + + + + + + + + + + + + + + + 进程ID + + + + + 所属机器ID + + + + + 启动分组 + + + + + + + + + + + + + + + + 数据库类型 + + + + + + + + + + + + + + + + + + 数据库名称 + + + + + 数据库连接字符串 + + + + + + + + + 世界中配置的数据库 + + + + + + + + 世界ID + + + + + 世界名称 + + + + + + + + + + + + + + + 场景ID + + + + + 进程配置ID + + + + + 世界配置ID + + + + + 场景运行模式 + + + + + + + + + + + + 场景类型字符串 + + + + + 网络协议类型 + + + + + + + + + + + + + + 外网端口 + + + + + 内网端口 + + + + + + + + + 服务器内部网络协议 + + + + + + + + + + + 消息体最大长度(字节),默认1048560字节(约1.02MB) + + + + + + + + + Session idle check timeout (in milliseconds) + + + + + Session idle check interval (in milliseconds) + + + + + + + + + + + + + + + + 单位字典数据 + + + + + + 单位ID + + + + + 单位名称 + + + + + 单位模型 + + + + + + + + + + + 字典键 + + + + + 字典值 + + + + + + + + \ No newline at end of file diff --git a/Main/bin/Debug/net9.0/Hotfix.dll b/Main/bin/Debug/net9.0/Hotfix.dll new file mode 100644 index 0000000..88aaba0 Binary files /dev/null and b/Main/bin/Debug/net9.0/Hotfix.dll differ diff --git a/Main/bin/Debug/net9.0/Hotfix.pdb b/Main/bin/Debug/net9.0/Hotfix.pdb new file mode 100644 index 0000000..cd22eb7 Binary files /dev/null and b/Main/bin/Debug/net9.0/Hotfix.pdb differ diff --git a/Main/bin/Debug/net9.0/Main.deps.json b/Main/bin/Debug/net9.0/Main.deps.json new file mode 100644 index 0000000..180e507 --- /dev/null +++ b/Main/bin/Debug/net9.0/Main.deps.json @@ -0,0 +1,457 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v9.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v9.0": { + "Main/1.0.0": { + "dependencies": { + "Entity": "1.0.0", + "Hotfix": "1.0.0", + "NLog": "6.0.6" + }, + "runtime": { + "Main.dll": {} + } + }, + "CommandLineParser/2.9.1": { + "runtime": { + "lib/netstandard2.0/CommandLine.dll": { + "assemblyVersion": "2.9.1.0", + "fileVersion": "2.9.1.0" + } + } + }, + "DnsClient/1.6.1": { + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0" + }, + "runtime": { + "lib/net5.0/DnsClient.dll": { + "assemblyVersion": "1.6.1.0", + "fileVersion": "1.6.1.0" + } + } + }, + "Fantasy-Net/2025.2.0": { + "dependencies": { + "CommandLineParser": "2.9.1", + "MongoDB.Bson": "3.5.0", + "MongoDB.Driver": "3.5.0", + "Newtonsoft.Json": "13.0.4", + "protobuf-net": "3.2.56" + }, + "runtime": { + "lib/net9.0/Fantasy-Net.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {}, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" + } + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.NETCore.Platforms/5.0.0": {}, + "Microsoft.Win32.Registry/5.0.0": { + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "MongoDB.Bson/3.5.0": { + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "5.0.0" + }, + "runtime": { + "lib/net6.0/MongoDB.Bson.dll": { + "assemblyVersion": "3.5.0.0", + "fileVersion": "3.5.0.0" + } + } + }, + "MongoDB.Driver/3.5.0": { + "dependencies": { + "DnsClient": "1.6.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "MongoDB.Bson": "3.5.0", + "SharpCompress": "0.30.1", + "Snappier": "1.0.0", + "System.Buffers": "4.5.1", + "ZstdSharp.Port": "0.7.3" + }, + "runtime": { + "lib/net6.0/MongoDB.Driver.dll": { + "assemblyVersion": "3.5.0.0", + "fileVersion": "3.5.0.0" + } + } + }, + "Newtonsoft.Json/13.0.4": { + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.4.30916" + } + } + }, + "NLog/6.0.6": { + "runtime": { + "lib/netstandard2.1/NLog.dll": { + "assemblyVersion": "6.0.0.0", + "fileVersion": "6.0.6.4706" + } + } + }, + "protobuf-net/3.2.56": { + "dependencies": { + "protobuf-net.Core": "3.2.56" + }, + "runtime": { + "lib/net8.0/protobuf-net.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.2.56.57311" + } + } + }, + "protobuf-net.Core/3.2.56": { + "runtime": { + "lib/net8.0/protobuf-net.Core.dll": { + "assemblyVersion": "3.0.0.0", + "fileVersion": "3.2.56.57311" + } + } + }, + "SharpCompress/0.30.1": { + "runtime": { + "lib/net5.0/SharpCompress.dll": { + "assemblyVersion": "0.30.1.0", + "fileVersion": "0.30.1.0" + } + } + }, + "Snappier/1.0.0": { + "runtime": { + "lib/net5.0/Snappier.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "System.Buffers/4.5.1": {}, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.14.0", + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "runtime": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "System.Memory/4.5.5": {}, + "System.Runtime.CompilerServices.Unsafe/5.0.0": {}, + "System.Security.AccessControl/5.0.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Principal.Windows/5.0.0": {}, + "ZstdSharp.Port/0.7.3": { + "runtime": { + "lib/net7.0/ZstdSharp.dll": { + "assemblyVersion": "0.7.3.0", + "fileVersion": "0.7.3.0" + } + } + }, + "Entity/1.0.0": { + "dependencies": { + "Fantasy-Net": "2025.2.0", + "Microsoft.IdentityModel.Tokens": "8.14.0", + "System.IdentityModel.Tokens.Jwt": "8.14.0", + "ThirdParty": "1.0.0" + }, + "runtime": { + "Entity.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "Hotfix/1.0.0": { + "dependencies": { + "Entity": "1.0.0" + }, + "runtime": { + "Hotfix.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "ThirdParty/1.0.0": { + "runtime": { + "ThirdParty.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + } + } + }, + "libraries": { + "Main/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "CommandLineParser/2.9.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-OE0sl1/sQ37bjVsPKKtwQlWDgqaxWgtme3xZz7JssWUzg5JpMIyHgCTY9MVMxOg48fJ1AgGT3tgdH5m/kQ5xhA==", + "path": "commandlineparser/2.9.1", + "hashPath": "commandlineparser.2.9.1.nupkg.sha512" + }, + "DnsClient/1.6.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4H/f2uYJOZ+YObZjpY9ABrKZI+JNw3uizp6oMzTXwDw6F+2qIPhpRl/1t68O/6e98+vqNiYGu+lswmwdYUy3gg==", + "path": "dnsclient/1.6.1", + "hashPath": "dnsclient.1.6.1.nupkg.sha512" + }, + "Fantasy-Net/2025.2.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-vCkduwxkMlH8GozyS+ZlWGLC4nGjFGaL13Ah4w5HL55XAJaAhe+RX+gbSRNBeJf1Uu0cjG2MgVyS4NX7bXdN4g==", + "path": "fantasy-net/2025.2.0", + "hashPath": "fantasy-net.2025.2.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "path": "microsoft.extensions.logging.abstractions/8.0.0", + "hashPath": "microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==", + "path": "microsoft.identitymodel.abstractions/8.14.0", + "hashPath": "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==", + "path": "microsoft.identitymodel.jsonwebtokens/8.14.0", + "hashPath": "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==", + "path": "microsoft.identitymodel.logging/8.14.0", + "hashPath": "microsoft.identitymodel.logging.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==", + "path": "microsoft.identitymodel.tokens/8.14.0", + "hashPath": "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==", + "path": "microsoft.netcore.platforms/5.0.0", + "hashPath": "microsoft.netcore.platforms.5.0.0.nupkg.sha512" + }, + "Microsoft.Win32.Registry/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "path": "microsoft.win32.registry/5.0.0", + "hashPath": "microsoft.win32.registry.5.0.0.nupkg.sha512" + }, + "MongoDB.Bson/3.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-JGNK6BanLDEifgkvPLqVFCPus5EDCy416pxf1dxUBRSVd3D9+NB3AvMVX190eXlk5/UXuCxpsQv7jWfNKvppBQ==", + "path": "mongodb.bson/3.5.0", + "hashPath": "mongodb.bson.3.5.0.nupkg.sha512" + }, + "MongoDB.Driver/3.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ST90u7psyMkNNOWFgSkexsrB3kPn7Ynl2DlMFj2rJyYuc6SIxjmzu4ufy51yzM+cPVE1SvVcdb5UFobrRw6cMg==", + "path": "mongodb.driver/3.5.0", + "hashPath": "mongodb.driver.3.5.0.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.4": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pdgNNMai3zv51W5aq268sujXUyx7SNdE2bj1wZcWjAQrKMFZV260lbqYop1d2GM67JI1huLRwxo9ZqnfF/lC6A==", + "path": "newtonsoft.json/13.0.4", + "hashPath": "newtonsoft.json.13.0.4.nupkg.sha512" + }, + "NLog/6.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-eUd/LDIwPtufj5OxtzFYiwuoKpzaS87iqO9P9D05avLCk4jIoOlqMwRH0o/43LmzM+CmgVAdDrCOq/rOK0sDKw==", + "path": "nlog/6.0.6", + "hashPath": "nlog.6.0.6.nupkg.sha512" + }, + "protobuf-net/3.2.56": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4IPJeTYAMNewlN8MDaFkcmR/9hLhJeo9eARnTh104zh7mf+vXT2gu5MUfUnkSQU+CH578Q6vcdU7LQDQPG6eaw==", + "path": "protobuf-net/3.2.56", + "hashPath": "protobuf-net.3.2.56.nupkg.sha512" + }, + "protobuf-net.Core/3.2.56": { + "type": "package", + "serviceable": true, + "sha512": "sha512-d6QOukTpDzs7zZv9tPnBZMtvHDNeHJQXUhMx54g4urUQsXK3oo9U70H9HvklYq7hlQ4A7AHJl7EVEqyCXXIl8Q==", + "path": "protobuf-net.core/3.2.56", + "hashPath": "protobuf-net.core.3.2.56.nupkg.sha512" + }, + "SharpCompress/0.30.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XqD4TpfyYGa7QTPzaGlMVbcecKnXy4YmYLDWrU+JIj7IuRNl7DH2END+Ll7ekWIY8o3dAMWLFDE1xdhfIWD1nw==", + "path": "sharpcompress/0.30.1", + "hashPath": "sharpcompress.0.30.1.nupkg.sha512" + }, + "Snappier/1.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rFtK2KEI9hIe8gtx3a0YDXdHOpedIf9wYCEYtBEmtlyiWVX3XlCNV03JrmmAi/Cdfn7dxK+k0sjjcLv4fpHnqA==", + "path": "snappier/1.0.0", + "hashPath": "snappier.1.0.0.nupkg.sha512" + }, + "System.Buffers/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==", + "path": "system.buffers/4.5.1", + "hashPath": "system.buffers.4.5.1.nupkg.sha512" + }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-EYGgN/S+HK7S6F3GaaPLFAfK0UzMrkXFyWCvXpQWFYmZln3dqtbyIO7VuTM/iIIPMzkelg8ZLlBPvMhxj6nOAA==", + "path": "system.identitymodel.tokens.jwt/8.14.0", + "hashPath": "system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512" + }, + "System.Memory/4.5.5": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "path": "system.memory/4.5.5", + "hashPath": "system.memory.4.5.5.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==", + "path": "system.runtime.compilerservices.unsafe/5.0.0", + "hashPath": "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512" + }, + "System.Security.AccessControl/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "path": "system.security.accesscontrol/5.0.0", + "hashPath": "system.security.accesscontrol.5.0.0.nupkg.sha512" + }, + "System.Security.Principal.Windows/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==", + "path": "system.security.principal.windows/5.0.0", + "hashPath": "system.security.principal.windows.5.0.0.nupkg.sha512" + }, + "ZstdSharp.Port/0.7.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-U9Ix4l4cl58Kzz1rJzj5hoVTjmbx1qGMwzAcbv1j/d3NzrFaESIurQyg+ow4mivCgkE3S413y+U9k4WdnEIkRA==", + "path": "zstdsharp.port/0.7.3", + "hashPath": "zstdsharp.port.0.7.3.nupkg.sha512" + }, + "Entity/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Hotfix/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ThirdParty/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Main/bin/Debug/net9.0/Main.dll b/Main/bin/Debug/net9.0/Main.dll new file mode 100644 index 0000000..7d94324 Binary files /dev/null and b/Main/bin/Debug/net9.0/Main.dll differ diff --git a/Main/bin/Debug/net9.0/Main.exe b/Main/bin/Debug/net9.0/Main.exe new file mode 100644 index 0000000..f3fe461 Binary files /dev/null and b/Main/bin/Debug/net9.0/Main.exe differ diff --git a/Main/bin/Debug/net9.0/Main.pdb b/Main/bin/Debug/net9.0/Main.pdb new file mode 100644 index 0000000..331c676 Binary files /dev/null and b/Main/bin/Debug/net9.0/Main.pdb differ diff --git a/Tools/ProtocolTest/FantasyNetTest.runtimeconfig.json b/Main/bin/Debug/net9.0/Main.runtimeconfig.json similarity index 61% rename from Tools/ProtocolTest/FantasyNetTest.runtimeconfig.json rename to Main/bin/Debug/net9.0/Main.runtimeconfig.json index 1dc0145..27e402f 100644 --- a/Tools/ProtocolTest/FantasyNetTest.runtimeconfig.json +++ b/Main/bin/Debug/net9.0/Main.runtimeconfig.json @@ -1,18 +1,18 @@ { "runtimeOptions": { - "tfm": "net8.0", + "tfm": "net9.0", "frameworks": [ { "name": "Microsoft.NETCore.App", - "version": "8.0.0" + "version": "9.0.0" }, { - "name": "Microsoft.WindowsDesktop.App", - "version": "8.0.0" + "name": "Microsoft.AspNetCore.App", + "version": "9.0.0" } ], "configProperties": { - "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false } } } \ No newline at end of file diff --git a/Main/bin/Debug/net9.0/Microsoft.IdentityModel.Abstractions.dll b/Main/bin/Debug/net9.0/Microsoft.IdentityModel.Abstractions.dll new file mode 100644 index 0000000..f85ae59 Binary files /dev/null and b/Main/bin/Debug/net9.0/Microsoft.IdentityModel.Abstractions.dll differ diff --git a/Main/bin/Debug/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll b/Main/bin/Debug/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll new file mode 100644 index 0000000..4c4d3ab Binary files /dev/null and b/Main/bin/Debug/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll differ diff --git a/Main/bin/Debug/net9.0/Microsoft.IdentityModel.Logging.dll b/Main/bin/Debug/net9.0/Microsoft.IdentityModel.Logging.dll new file mode 100644 index 0000000..170078a Binary files /dev/null and b/Main/bin/Debug/net9.0/Microsoft.IdentityModel.Logging.dll differ diff --git a/Main/bin/Debug/net9.0/Microsoft.IdentityModel.Tokens.dll b/Main/bin/Debug/net9.0/Microsoft.IdentityModel.Tokens.dll new file mode 100644 index 0000000..009ce65 Binary files /dev/null and b/Main/bin/Debug/net9.0/Microsoft.IdentityModel.Tokens.dll differ diff --git a/Main/bin/Debug/net9.0/MongoDB.Bson.dll b/Main/bin/Debug/net9.0/MongoDB.Bson.dll new file mode 100644 index 0000000..b96f918 Binary files /dev/null and b/Main/bin/Debug/net9.0/MongoDB.Bson.dll differ diff --git a/Main/bin/Debug/net9.0/MongoDB.Driver.dll b/Main/bin/Debug/net9.0/MongoDB.Driver.dll new file mode 100644 index 0000000..1b8f536 Binary files /dev/null and b/Main/bin/Debug/net9.0/MongoDB.Driver.dll differ diff --git a/Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.config b/Main/bin/Debug/net9.0/NLog.config similarity index 100% rename from Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.config rename to Main/bin/Debug/net9.0/NLog.config diff --git a/Main/bin/Debug/net9.0/NLog.dll b/Main/bin/Debug/net9.0/NLog.dll new file mode 100644 index 0000000..7cae440 Binary files /dev/null and b/Main/bin/Debug/net9.0/NLog.dll differ diff --git a/Tools/NBConfigBuilder/Newtonsoft.Json.dll b/Main/bin/Debug/net9.0/Newtonsoft.Json.dll similarity index 100% rename from Tools/NBConfigBuilder/Newtonsoft.Json.dll rename to Main/bin/Debug/net9.0/Newtonsoft.Json.dll diff --git a/Main/bin/Debug/net9.0/SharpCompress.dll b/Main/bin/Debug/net9.0/SharpCompress.dll new file mode 100644 index 0000000..c1a7f07 Binary files /dev/null and b/Main/bin/Debug/net9.0/SharpCompress.dll differ diff --git a/Main/bin/Debug/net9.0/Snappier.dll b/Main/bin/Debug/net9.0/Snappier.dll new file mode 100644 index 0000000..9b68e85 Binary files /dev/null and b/Main/bin/Debug/net9.0/Snappier.dll differ diff --git a/Main/bin/Debug/net9.0/System.IdentityModel.Tokens.Jwt.dll b/Main/bin/Debug/net9.0/System.IdentityModel.Tokens.Jwt.dll new file mode 100644 index 0000000..5f487d8 Binary files /dev/null and b/Main/bin/Debug/net9.0/System.IdentityModel.Tokens.Jwt.dll differ diff --git a/Main/bin/Debug/net9.0/ThirdParty.dll b/Main/bin/Debug/net9.0/ThirdParty.dll new file mode 100644 index 0000000..c68db15 Binary files /dev/null and b/Main/bin/Debug/net9.0/ThirdParty.dll differ diff --git a/Main/bin/Debug/net9.0/ThirdParty.pdb b/Main/bin/Debug/net9.0/ThirdParty.pdb new file mode 100644 index 0000000..6d74378 Binary files /dev/null and b/Main/bin/Debug/net9.0/ThirdParty.pdb differ diff --git a/Main/bin/Debug/net9.0/ZstdSharp.dll b/Main/bin/Debug/net9.0/ZstdSharp.dll new file mode 100644 index 0000000..5d93f7e Binary files /dev/null and b/Main/bin/Debug/net9.0/ZstdSharp.dll differ diff --git a/Config/Json/configs.json b/Main/bin/Debug/net9.0/configs.json similarity index 100% rename from Config/Json/configs.json rename to Main/bin/Debug/net9.0/configs.json diff --git a/Tools/NBConfigBuilder/protobuf-net.Core.dll b/Main/bin/Debug/net9.0/protobuf-net.Core.dll similarity index 100% rename from Tools/NBConfigBuilder/protobuf-net.Core.dll rename to Main/bin/Debug/net9.0/protobuf-net.Core.dll diff --git a/Tools/NBConfigBuilder/protobuf-net.dll b/Main/bin/Debug/net9.0/protobuf-net.dll similarity index 100% rename from Tools/NBConfigBuilder/protobuf-net.dll rename to Main/bin/Debug/net9.0/protobuf-net.dll diff --git a/Main/configs.json b/Main/configs.json new file mode 100644 index 0000000..a0de76b --- /dev/null +++ b/Main/configs.json @@ -0,0 +1,1871 @@ +{ + "RodRingConfig": [ + { + "Id": 1, + "Model": "rod_rings/rumoi/rumoi_oxiline_spin", + "Strength": 40 + }, + { + "Id": 2, + "Model": "rod_rings/smt/smt_pure_ceramic_bolo", + "Strength": 40 + } + ], + "LureConfig": [ + { + "Id": 80001, + "Hook": [ + 700102 + ], + "EfficacyBase": 50 + }, + { + "Id": 80002, + "Hook": [ + 700102 + ], + "EfficacyBase": 50 + }, + { + "Id": 80003, + "Hook": [ + 0 + ], + "EfficacyBase": 50 + }, + { + "Id": 80004, + "Hook": [ + 0 + ], + "EfficacyBase": 50 + } + ], + "ItemConfig": [ + { + "Id": 30001, + "Model": "rods/syberia/tele_10037/tele_10037_t13", + "Type": 1, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30002, + "Model": "rods/syberia/bolo_10021/bolo_10021_LB400", + "Type": 0, + "Quality": 2, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30003, + "Model": "rods/syberia/spin_10034/spin_10034_S60H", + "Type": 0, + "Quality": 3, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30004, + "Model": "rods/syberia/carp_10046/carp_10046_360H", + "Type": 0, + "Quality": 4, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30005, + "Model": "rods/syberia/cast_10018/cast_10018_CST60MH", + "Type": 0, + "Quality": 5, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30006, + "Model": "rods/syberia/feeder_10048/feeder_10048_FD390", + "Type": 0, + "Quality": 4, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30007, + "Model": "rods/syberia/jerk_10043/jerk_10043_JR60XH", + "Type": 0, + "Quality": 3, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30008, + "Model": "rods/syberia/mark_10168/mark_10168_3LB", + "Type": 0, + "Quality": 0, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30009, + "Model": "rods/syberia/match_10025/match_10025_M130H", + "Type": 0, + "Quality": 0, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30010, + "Model": "rods/syberia/picker_10052/picker_10052_P300-MH", + "Type": 0, + "Quality": 0, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 30011, + "Model": "rods/syberia/spod_10133/spod_10133_3LB", + "Type": 0, + "Quality": 0, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40001, + "Model": "reels/syberia/spin_5002/spin_5002", + "Type": 0, + "Quality": 3, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40002, + "Model": "reels/syberia/spin_5036/spin_5036", + "Type": 0, + "Quality": 4, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40003, + "Model": "reels/syberia/bclp_5005/bclp_5005", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40004, + "Model": "reels/syberia/bclp_5032/bclp_5032", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40005, + "Model": "reels/syberia/bcr_5034/bcr_5034", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40006, + "Model": "reels/syberia/bcr_5062/bcr_5062", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40007, + "Model": "reels/syberia/c_spin_5386/c_spin_5386", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40008, + "Model": "reels/syberia/c_spin_5387/c_spin_5387", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40009, + "Model": "reels/syberia/conv_5393/conv_5393", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 40010, + "Model": "reels/syberia/conv_5396/conv_5396", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50001, + "Model": "bobbers/expressfishing/bob_25001/bob_25001", + "Type": 0, + "Quality": 1, + "Brand": 1, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50002, + "Model": "bobbers/expressfishing/bob_25002/bob_25002", + "Type": 0, + "Quality": 2, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50003, + "Model": "bobbers/expressfishing/bob_25003/bob_25003", + "Type": 0, + "Quality": 3, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50004, + "Model": "bobbers/expressfishing/bob_25004/bob_25004", + "Type": 0, + "Quality": 4, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50005, + "Model": "bobbers/expressfishing/bob_25162_25163/bob_25162", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50006, + "Model": "bobbers/expressfishing/bob_25162_25163/bob_25163", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50007, + "Model": "bobbers/expressfishing/bob_25164_25165/bob_25164", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50008, + "Model": "bobbers/expressfishing/bob_25164_25165/bob_25165", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50009, + "Model": "bobbers/expressfishing/bob_25166_25167/bob_25166", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50010, + "Model": "bobbers/expressfishing/bob_25166_25167/bob_25167", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50011, + "Model": "bobbers/expressfishing/float_ny_1/float_ny25_1", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50012, + "Model": "bobbers/expressfishing/float_ny_1/float_ny25_2", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50013, + "Model": "bobbers/expressfishing/float_ny_1/float_ny25_3", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 50014, + "Model": "bobbers/expressfishing/float_ny_1/float_ny_1", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60001, + "Model": "lines/solid_materials/mono_40340/braid_40388", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60002, + "Model": "lines/solid_materials/mono_40340/braid_40389", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60003, + "Model": "lines/solid_materials/mono_40340/braid_40390", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60004, + "Model": "lines/solid_materials/mono_40340/braid_40391", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60005, + "Model": "lines/solid_materials/mono_40340/braid_40392", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60006, + "Model": "lines/solid_materials/mono_40340/braid_40393", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60007, + "Model": "lines/solid_materials/mono_40340/braid_40394", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60008, + "Model": "lines/solid_materials/mono_40340/braid_40395", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60009, + "Model": "lines/solid_materials/mono_40340/braid_40396", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 60010, + "Model": "lines/solid_materials/mono_40340/braid_40397", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 70001, + "Model": "baits/worm_01/worm_01", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 70002, + "Model": "baits/fly/fly", + "Type": 0, + "Quality": 2, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 70003, + "Model": "baits/black_leech/black_leech", + "Type": 0, + "Quality": 2, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 70004, + "Model": "baits/bread/bread", + "Type": 0, + "Quality": 3, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80001, + "Model": "lures/express_fishing/crankbaits_1/738/crankbaits_738", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80002, + "Model": "lures/express_fishing/crankbaits_1/744/crankbaits_744", + "Type": 0, + "Quality": 2, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80003, + "Model": "lures/express_fishing/crankbaits_1/752/crankbaits_752", + "Type": 0, + "Quality": 3, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80004, + "Model": "lures/express_fishing/crankbaits_1/863/crankbaits_863", + "Type": 0, + "Quality": 4, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80005, + "Model": "lures/express_fishing/poppers_1/poppers_586/poppers_586", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80006, + "Model": "lures/express_fishing/softplastic/ef_supergrab_4/softplastic_g_1610", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80007, + "Model": "lures/express_fishing/softplastic/ef_supergrab_4/softplastic_g_1611", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80008, + "Model": "lures/express_fishing/softplastic/ef_superminnow_4/softplastic_m_1624", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80009, + "Model": "lures/express_fishing/spinnerbaits_1/594/spinnerbaits_594", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80010, + "Model": "lures/express_fishing/spinnerbaits_1/596/spinnerbaits_596", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80011, + "Model": "lures/express_fishing/spinnerbaits_1/597/spinnerbaits_597", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80012, + "Model": "lures/express_fishing/spoon_lures_1/spoon_lures_666/spoon_lures_666", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 80013, + "Model": "lures/express_fishing/spoon_lures_1/spoon_lures_1045/spoon_lures_1045", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90001, + "Model": "hooks/alliance/c_hook_20789_20794/c_hook_20789", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90002, + "Model": "hooks/berserk_hooks/clas_20421_20446/clas_20421", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90003, + "Model": "hooks/berserk_hooks/clas_20447_20472/clas_20447", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90004, + "Model": "hooks/berserk_hooks/clas_20473_20492/clas_20473", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90005, + "Model": "hooks/berserk_hooks/clas_20493_20514/clas_20493", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90006, + "Model": "hooks/berserk_hooks/clas_20515_20532/clas_20515", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90007, + "Model": "hooks/berserk_hooks/clas_20533_20550/clas_20533", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90008, + "Model": "hooks/berserk_hooks/jhead_20596_20603/jhead_20596", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90009, + "Model": "hooks/berserk_hooks/jhead_20604_20613/jhead_20604", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90010, + "Model": "hooks/berserk_hooks/jhead_20614_20622/jhead_20614", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90011, + "Model": "hooks/berserk_hooks/jhead_20959_20994/jhead_20959", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90012, + "Model": "hooks/berserk_hooks/lfish_20637_20643/lfish_20637", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90013, + "Model": "hooks/berserk_hooks/lfish_20644_20650/lfish_20644", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90014, + "Model": "hooks/berserk_hooks/mdhook_20929_20935/mdhook_20929", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90015, + "Model": "hooks/berserk_hooks/mhook_20878/mhook_20878", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90016, + "Model": "hooks/berserk_hooks/triple_20569_20577/triple_20569", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90017, + "Model": "hooks/berserk_hooks/triple_20578_20586/triple_20578", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90018, + "Model": "hooks/berserk_hooks/triple_20660_20668/triple_20660", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90019, + "Model": "hooks/berserk_hooks/triple_20669_20677/triple_20669", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 90020, + "Model": "hooks/berserk_hooks/woffset_20623_20636/woffset_20623", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100001, + "Model": "weights/Weight2_5g", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100002, + "Model": "weights/weight_olive_1g", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100003, + "Model": "sinkers/express fishing/bulsinker_30016_30056/bulsinker_30016", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100004, + "Model": "sinkers/express fishing/dsinker_30001_30005/dsinker_30001", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100005, + "Model": "sinkers/express fishing/psinker_30010_30014/psinker_30010", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100006, + "Model": "sinkers/hvz/flpsinker_30138_30339/flpsinker_30138", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100007, + "Model": "sinkers/hvz/flsinker_30110_30137/flsinker_30110", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100008, + "Model": "sinkers/hvz/horsinker_30340_30371/horsinker_30340", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100009, + "Model": "sinkers/hvz/mrksinker_30371/mrksinker_30371", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 100010, + "Model": "sinkers/hvz/trisinker_30282_30463/trisinker_30282", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + }, + { + "Id": 110001, + "Model": "Feeders/Feeder 1/FeedTrash 1", + "Type": 0, + "Quality": 1, + "Brand": 0, + "Weight": 0, + "Length": 0, + "Max": 0, + "AutoUse": 0, + "Deal": 0 + } + ], + "ReelConfig": [ + { + "Id": 40001, + "ReelType": 1, + "GearRatio": [ + "7" + ], + "Strength": 40 + }, + { + "Id": 40002, + "ReelType": 1, + "GearRatio": [ + "5" + ], + "Strength": 40 + }, + { + "Id": 40003, + "ReelType": 2, + "GearRatio": [], + "Strength": 0 + }, + { + "Id": 40004, + "ReelType": 2, + "GearRatio": [], + "Strength": 0 + }, + { + "Id": 40005, + "ReelType": 3, + "GearRatio": [], + "Strength": 0 + }, + { + "Id": 40006, + "ReelType": 3, + "GearRatio": [], + "Strength": 0 + }, + { + "Id": 40007, + "ReelType": 1, + "GearRatio": [], + "Strength": 0 + }, + { + "Id": 40008, + "ReelType": 1, + "GearRatio": [], + "Strength": 0 + }, + { + "Id": 40009, + "ReelType": 3, + "GearRatio": [], + "Strength": 0 + }, + { + "Id": 40010, + "ReelType": 3, + "GearRatio": [], + "Strength": 0 + } + ], + "LineConfig": [ + { + "Id": 60001, + "Strength": 40, + "Size": 1 + }, + { + "Id": 60002, + "Strength": 40, + "Size": 1 + } + ], + "HookConfig": [ + { + "Id": 90001, + "Zadzior": 1 + }, + { + "Id": 90002, + "Zadzior": 1 + }, + { + "Id": 90003, + "Zadzior": 1 + }, + { + "Id": 90004, + "Zadzior": 1 + }, + { + "Id": 90005, + "Zadzior": 1 + } + ], + "RodConfig": [ + { + "Id": 30001, + "RodType": 1, + "Ring": 0, + "Strength": 40, + "MaxRange": 67, + "ConstructionType": 0 + }, + { + "Id": 30002, + "RodType": 3, + "Ring": 2, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + }, + { + "Id": 30003, + "RodType": 2, + "Ring": 1, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + }, + { + "Id": 30004, + "RodType": 1, + "Ring": 1, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + }, + { + "Id": 30005, + "RodType": 2, + "Ring": 1, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + }, + { + "Id": 30006, + "RodType": 2, + "Ring": 1, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + }, + { + "Id": 30007, + "RodType": 2, + "Ring": 1, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + }, + { + "Id": 30008, + "RodType": 2, + "Ring": 1, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + }, + { + "Id": 30009, + "RodType": 2, + "Ring": 1, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + }, + { + "Id": 30010, + "RodType": 2, + "Ring": 1, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + }, + { + "Id": 30011, + "RodType": 2, + "Ring": 1, + "Strength": 40, + "MaxRange": 30, + "ConstructionType": 0 + } + ], + "FishConfig": [ + { + "Id": 210001, + "Model": [ + "Burbot_B" + ], + "Type": 0, + "SpeciesName": 10, + "MinWeight": 1, + "MaxWeight": 34, + "Accept": 2100001 + }, + { + "Id": 210002, + "Model": [ + "CarpCommon_B" + ], + "Type": 0, + "SpeciesName": 11, + "MinWeight": 1, + "MaxWeight": 34, + "Accept": 2100001 + }, + { + "Id": 210003, + "Model": [ + "CarpGrass_B" + ], + "Type": 0, + "SpeciesName": 14, + "MinWeight": 1, + "MaxWeight": 34, + "Accept": 2100001 + }, + { + "Id": 210004, + "Model": [ + "CarpCrucian_B" + ], + "Type": 0, + "SpeciesName": 16, + "MinWeight": 1, + "MaxWeight": 34, + "Accept": 2100001 + } + ], + "BasicConfig": [ + { + "Id": 1001, + "Name": "Weights/Weight2_5g", + "Val": [ + "0" + ] + } + ], + "InitConfig": [ + { + "Id": 10001, + "Amount": 100 + }, + { + "Id": 10002, + "Amount": 200 + }, + { + "Id": 30001, + "Amount": 1 + }, + { + "Id": 30002, + "Amount": 1 + }, + { + "Id": 30003, + "Amount": 1 + }, + { + "Id": 30004, + "Amount": 1 + }, + { + "Id": 30005, + "Amount": 1 + }, + { + "Id": 30006, + "Amount": 1 + }, + { + "Id": 30007, + "Amount": 1 + }, + { + "Id": 30008, + "Amount": 1 + }, + { + "Id": 30009, + "Amount": 1 + }, + { + "Id": 30010, + "Amount": 1 + }, + { + "Id": 30011, + "Amount": 1 + }, + { + "Id": 40001, + "Amount": 1 + }, + { + "Id": 40002, + "Amount": 1 + }, + { + "Id": 40003, + "Amount": 1 + }, + { + "Id": 40004, + "Amount": 1 + }, + { + "Id": 40005, + "Amount": 1 + }, + { + "Id": 40006, + "Amount": 1 + }, + { + "Id": 40007, + "Amount": 1 + }, + { + "Id": 40008, + "Amount": 1 + }, + { + "Id": 40009, + "Amount": 1 + }, + { + "Id": 40010, + "Amount": 1 + }, + { + "Id": 50001, + "Amount": 1 + }, + { + "Id": 50002, + "Amount": 1 + }, + { + "Id": 50003, + "Amount": 1 + }, + { + "Id": 50004, + "Amount": 1 + }, + { + "Id": 50005, + "Amount": 1 + }, + { + "Id": 50006, + "Amount": 1 + }, + { + "Id": 50007, + "Amount": 1 + }, + { + "Id": 50008, + "Amount": 1 + }, + { + "Id": 50009, + "Amount": 1 + }, + { + "Id": 50010, + "Amount": 1 + }, + { + "Id": 50011, + "Amount": 1 + }, + { + "Id": 50012, + "Amount": 1 + }, + { + "Id": 50013, + "Amount": 1 + }, + { + "Id": 50014, + "Amount": 1 + }, + { + "Id": 60001, + "Amount": 1 + }, + { + "Id": 60002, + "Amount": 1 + }, + { + "Id": 60003, + "Amount": 1 + }, + { + "Id": 60004, + "Amount": 1 + }, + { + "Id": 60005, + "Amount": 1 + }, + { + "Id": 60006, + "Amount": 1 + }, + { + "Id": 60007, + "Amount": 1 + }, + { + "Id": 60008, + "Amount": 1 + }, + { + "Id": 60009, + "Amount": 1 + }, + { + "Id": 60010, + "Amount": 1 + }, + { + "Id": 70001, + "Amount": 1 + }, + { + "Id": 70002, + "Amount": 1 + }, + { + "Id": 70003, + "Amount": 1 + }, + { + "Id": 70004, + "Amount": 1 + }, + { + "Id": 80001, + "Amount": 1 + }, + { + "Id": 80002, + "Amount": 1 + }, + { + "Id": 80003, + "Amount": 1 + }, + { + "Id": 80004, + "Amount": 1 + }, + { + "Id": 80005, + "Amount": 1 + }, + { + "Id": 80006, + "Amount": 1 + }, + { + "Id": 80007, + "Amount": 1 + }, + { + "Id": 80008, + "Amount": 1 + }, + { + "Id": 80009, + "Amount": 1 + }, + { + "Id": 80010, + "Amount": 1 + }, + { + "Id": 80011, + "Amount": 1 + }, + { + "Id": 80012, + "Amount": 1 + }, + { + "Id": 80013, + "Amount": 1 + }, + { + "Id": 90001, + "Amount": 1 + }, + { + "Id": 90002, + "Amount": 1 + }, + { + "Id": 90003, + "Amount": 1 + }, + { + "Id": 90004, + "Amount": 1 + }, + { + "Id": 90005, + "Amount": 1 + }, + { + "Id": 90006, + "Amount": 1 + }, + { + "Id": 90007, + "Amount": 1 + }, + { + "Id": 90008, + "Amount": 1 + }, + { + "Id": 90009, + "Amount": 1 + }, + { + "Id": 90010, + "Amount": 1 + }, + { + "Id": 90011, + "Amount": 1 + }, + { + "Id": 90012, + "Amount": 1 + }, + { + "Id": 90013, + "Amount": 1 + }, + { + "Id": 90014, + "Amount": 1 + }, + { + "Id": 90015, + "Amount": 1 + }, + { + "Id": 90016, + "Amount": 1 + }, + { + "Id": 90017, + "Amount": 1 + }, + { + "Id": 90018, + "Amount": 1 + }, + { + "Id": 90019, + "Amount": 1 + }, + { + "Id": 90020, + "Amount": 1 + }, + { + "Id": 100001, + "Amount": 1 + }, + { + "Id": 100002, + "Amount": 1 + }, + { + "Id": 100003, + "Amount": 1 + }, + { + "Id": 100004, + "Amount": 1 + }, + { + "Id": 100005, + "Amount": 1 + }, + { + "Id": 100006, + "Amount": 1 + }, + { + "Id": 100007, + "Amount": 1 + }, + { + "Id": 100008, + "Amount": 1 + }, + { + "Id": 100009, + "Amount": 1 + }, + { + "Id": 100010, + "Amount": 1 + }, + { + "Id": 110001, + "Amount": 1 + } + ], + "BobberConfig": [ + { + "Id": 50001, + "Displacement": 40, + "NightLight": 0 + }, + { + "Id": 50002, + "Displacement": 40, + "NightLight": 0 + }, + { + "Id": 50003, + "Displacement": 40, + "NightLight": 0 + }, + { + "Id": 50004, + "Displacement": 40, + "NightLight": 0 + } + ], + "FeederConfig": [ + { + "Id": 110001, + "Capacity": 100, + "Weight": 5 + } + ], + "BaitConfig": [ + { + "Id": 70001, + "EfficacyBase": 15, + "Arr": [ + 250, + 1, + 2, + 3 + ], + "ArrStr": [ + "d", + "a", + "bb", + "e|12" + ] + }, + { + "Id": 70002, + "EfficacyBase": 15, + "Arr": [ + 120, + 4, + 3 + ], + "ArrStr": [ + "120", + "4", + "3" + ] + }, + { + "Id": 70003, + "EfficacyBase": 15, + "Arr": [ + 120 + ], + "ArrStr": [ + "kkk" + ] + }, + { + "Id": 70004, + "EfficacyBase": 15, + "Arr": [ + 120 + ], + "ArrStr": [ + "11|33", + "44|2" + ] + } + ] +} \ No newline at end of file diff --git a/Main/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs b/Main/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs new file mode 100644 index 0000000..feda5e9 --- /dev/null +++ b/Main/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")] diff --git a/Main/obj/Debug/net9.0/Main.AssemblyInfo.cs b/Main/obj/Debug/net9.0/Main.AssemblyInfo.cs new file mode 100644 index 0000000..b27d473 --- /dev/null +++ b/Main/obj/Debug/net9.0/Main.AssemblyInfo.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("Main")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+7b10d4cb317c9f310649a9cb4afe3882d4b12624")] +[assembly: System.Reflection.AssemblyProductAttribute("Main")] +[assembly: System.Reflection.AssemblyTitleAttribute("Main")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// 由 MSBuild WriteCodeFragment 类生成。 + diff --git a/Main/obj/Debug/net9.0/Main.AssemblyInfoInputs.cache b/Main/obj/Debug/net9.0/Main.AssemblyInfoInputs.cache new file mode 100644 index 0000000..479ec02 --- /dev/null +++ b/Main/obj/Debug/net9.0/Main.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +fc9a8788d075a5df6ba33e2aaff4335f57496fcbbea48b273642a6c07957e27a diff --git a/Main/obj/Debug/net9.0/Main.GeneratedMSBuildEditorConfig.editorconfig b/Main/obj/Debug/net9.0/Main.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 0000000..6b090ba --- /dev/null +++ b/Main/obj/Debug/net9.0/Main.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,15 @@ +is_global = true +build_property.TargetFramework = net9.0 +build_property.TargetPlatformMinVersion = +build_property.UsingMicrosoftNETSdkWeb = +build_property.ProjectTypeGuids = +build_property.InvariantGlobalization = +build_property.PlatformNeutralAssembly = +build_property.EnforceExtendedAnalyzerRules = +build_property._SupportedPlatformList = Linux,macOS,Windows +build_property.RootNamespace = Main +build_property.ProjectDir = D:\work\Fishing2Server\Main\ +build_property.EnableComHosting = +build_property.EnableGeneratedComInterfaceComImportInterop = +build_property.EffectiveAnalysisLevelStyle = 9.0 +build_property.EnableCodeStyleSeverity = diff --git a/Main/obj/Debug/net9.0/Main.GlobalUsings.g.cs b/Main/obj/Debug/net9.0/Main.GlobalUsings.g.cs new file mode 100644 index 0000000..8578f3d --- /dev/null +++ b/Main/obj/Debug/net9.0/Main.GlobalUsings.g.cs @@ -0,0 +1,8 @@ +// +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Net.Http; +global using global::System.Threading; +global using global::System.Threading.Tasks; diff --git a/Main/obj/Debug/net9.0/Main.assets.cache b/Main/obj/Debug/net9.0/Main.assets.cache new file mode 100644 index 0000000..e0d1a81 Binary files /dev/null and b/Main/obj/Debug/net9.0/Main.assets.cache differ diff --git a/Main/obj/Debug/net9.0/Main.csproj.AssemblyReference.cache b/Main/obj/Debug/net9.0/Main.csproj.AssemblyReference.cache new file mode 100644 index 0000000..6bce45e Binary files /dev/null and b/Main/obj/Debug/net9.0/Main.csproj.AssemblyReference.cache differ diff --git a/Main/obj/Debug/net9.0/Main.csproj.CoreCompileInputs.cache b/Main/obj/Debug/net9.0/Main.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..adeb184 --- /dev/null +++ b/Main/obj/Debug/net9.0/Main.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +292ce48b0f62b84117b005a76ae2bf2724504c20e2a698038c8eb55ca1642b53 diff --git a/Main/obj/Debug/net9.0/Main.csproj.FileListAbsolute.txt b/Main/obj/Debug/net9.0/Main.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..c184870 --- /dev/null +++ b/Main/obj/Debug/net9.0/Main.csproj.FileListAbsolute.txt @@ -0,0 +1,43 @@ +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Fantasy.config +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Fantasy.xsd +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Main.exe +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\NLog.config +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Main.deps.json +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Main.runtimeconfig.json +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Main.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Main.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\CommandLine.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\DnsClient.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Fantasy-Net.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\MongoDB.Bson.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\MongoDB.Driver.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Newtonsoft.Json.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\NLog.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\protobuf-net.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\protobuf-net.Core.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\SharpCompress.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Snappier.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\ZstdSharp.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Entity.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Hotfix.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Entity.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Hotfix.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\Main.csproj.AssemblyReference.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\Main.GeneratedMSBuildEditorConfig.editorconfig +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\Main.AssemblyInfoInputs.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\Main.AssemblyInfo.cs +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\Main.csproj.CoreCompileInputs.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\Main.csproj.Up2Date +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\Main.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\refint\Main.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\Main.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\Main.genruntimeconfig.cache +D:\work\Fishing2ServerNew\Fishing2\Server\Main\obj\Debug\net9.0\ref\Main.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\configs.json +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Microsoft.IdentityModel.Abstractions.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Microsoft.IdentityModel.Logging.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Microsoft.IdentityModel.Tokens.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\ThirdParty.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\ThirdParty.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\Microsoft.IdentityModel.JsonWebTokens.dll +D:\work\Fishing2ServerNew\Fishing2\Server\Main\bin\Debug\net9.0\System.IdentityModel.Tokens.Jwt.dll diff --git a/Main/obj/Debug/net9.0/Main.csproj.Up2Date b/Main/obj/Debug/net9.0/Main.csproj.Up2Date new file mode 100644 index 0000000..e69de29 diff --git a/Main/obj/Debug/net9.0/Main.dll b/Main/obj/Debug/net9.0/Main.dll new file mode 100644 index 0000000..7d94324 Binary files /dev/null and b/Main/obj/Debug/net9.0/Main.dll differ diff --git a/Main/obj/Debug/net9.0/Main.genruntimeconfig.cache b/Main/obj/Debug/net9.0/Main.genruntimeconfig.cache new file mode 100644 index 0000000..9b8a746 --- /dev/null +++ b/Main/obj/Debug/net9.0/Main.genruntimeconfig.cache @@ -0,0 +1 @@ +f7b3b59ea4a346ccb1b1bd90e08296a5128123bee96b07e25dbe0d73dbe5fe11 diff --git a/Main/obj/Debug/net9.0/Main.pdb b/Main/obj/Debug/net9.0/Main.pdb new file mode 100644 index 0000000..331c676 Binary files /dev/null and b/Main/obj/Debug/net9.0/Main.pdb differ diff --git a/Main/obj/Debug/net9.0/apphost.exe b/Main/obj/Debug/net9.0/apphost.exe new file mode 100644 index 0000000..f3fe461 Binary files /dev/null and b/Main/obj/Debug/net9.0/apphost.exe differ diff --git a/Main/obj/Debug/net9.0/ref/Main.dll b/Main/obj/Debug/net9.0/ref/Main.dll new file mode 100644 index 0000000..407ef54 Binary files /dev/null and b/Main/obj/Debug/net9.0/ref/Main.dll differ diff --git a/Main/obj/Debug/net9.0/refint/Main.dll b/Main/obj/Debug/net9.0/refint/Main.dll new file mode 100644 index 0000000..407ef54 Binary files /dev/null and b/Main/obj/Debug/net9.0/refint/Main.dll differ diff --git a/Main/obj/Main.csproj.nuget.dgspec.json b/Main/obj/Main.csproj.nuget.dgspec.json new file mode 100644 index 0000000..b8b99c6 --- /dev/null +++ b/Main/obj/Main.csproj.nuget.dgspec.json @@ -0,0 +1,303 @@ +{ + "format": 1, + "restore": { + "D:\\work\\Fishing2Server\\Main\\Main.csproj": {} + }, + "projects": { + "D:\\work\\Fishing2Server\\Entity\\Entity.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj", + "projectName": "Entity", + "projectPath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\Entity\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net9.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "projectReferences": { + "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "dependencies": { + "Fantasy-Net": { + "target": "Package", + "version": "[2025.2.0, )" + }, + "Microsoft.IdentityModel.Tokens": { + "target": "Package", + "version": "[8.14.0, )" + }, + "System.IdentityModel.Tokens.Jwt": { + "target": "Package", + "version": "[8.14.0, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + }, + "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj", + "projectName": "Hotfix", + "projectPath": "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\Hotfix\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net9.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "projectReferences": { + "D:\\work\\Fishing2Server\\Entity\\Entity.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + }, + "D:\\work\\Fishing2Server\\Main\\Main.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\Main\\Main.csproj", + "projectName": "Main", + "projectPath": "D:\\work\\Fishing2Server\\Main\\Main.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\Main\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net9.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "projectReferences": { + "D:\\work\\Fishing2Server\\Entity\\Entity.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj" + }, + "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "dependencies": { + "NLog": { + "target": "Package", + "version": "[*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + }, + "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "projectName": "ThirdParty", + "projectPath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\ThirdParty\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net8.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/Main/obj/Main.csproj.nuget.g.props b/Main/obj/Main.csproj.nuget.g.props new file mode 100644 index 0000000..fbb082f --- /dev/null +++ b/Main/obj/Main.csproj.nuget.g.props @@ -0,0 +1,16 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + $(UserProfile)\.nuget\packages\ + C:\Users\FIREBAT\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages + PackageReference + 6.14.0 + + + + + + \ No newline at end of file diff --git a/Main/obj/Main.csproj.nuget.g.targets b/Main/obj/Main.csproj.nuget.g.targets new file mode 100644 index 0000000..eb7028d --- /dev/null +++ b/Main/obj/Main.csproj.nuget.g.targets @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Main/obj/project.assets.json b/Main/obj/project.assets.json new file mode 100644 index 0000000..82bbb3e --- /dev/null +++ b/Main/obj/project.assets.json @@ -0,0 +1,1282 @@ +{ + "version": 3, + "targets": { + "net9.0": { + "CommandLineParser/2.9.1": { + "type": "package", + "compile": { + "lib/netstandard2.0/CommandLine.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/CommandLine.dll": { + "related": ".xml" + } + } + }, + "DnsClient/1.6.1": { + "type": "package", + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0" + }, + "compile": { + "lib/net5.0/DnsClient.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net5.0/DnsClient.dll": { + "related": ".xml" + } + } + }, + "Fantasy-Net/2025.2.0": { + "type": "package", + "dependencies": { + "CommandLineParser": "2.9.1", + "MongoDB.Bson": "3.5.0", + "MongoDB.Driver": "3.5.0", + "Newtonsoft.Json": "13.0.4", + "protobuf-net": "3.2.56" + }, + "compile": { + "lib/net9.0/Fantasy-Net.dll": {} + }, + "runtime": { + "lib/net9.0/Fantasy-Net.dll": {} + }, + "frameworkReferences": [ + "Microsoft.AspNetCore.App" + ], + "build": { + "buildTransitive/Fantasy-Net.targets": {} + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { + "type": "package", + "compile": { + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "related": ".xml" + } + }, + "build": { + "buildTransitive/net6.0/_._": {} + } + }, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "type": "package", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" + }, + "compile": { + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "related": ".xml" + } + }, + "build": { + "buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets": {} + } + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "type": "package", + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "related": ".xml" + } + } + }, + "Microsoft.NETCore.Platforms/5.0.0": { + "type": "package", + "compile": { + "lib/netstandard1.0/_._": {} + }, + "runtime": { + "lib/netstandard1.0/_._": {} + } + }, + "Microsoft.Win32.Registry/5.0.0": { + "type": "package", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/Microsoft.Win32.Registry.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/Microsoft.Win32.Registry.dll": { + "related": ".xml" + } + }, + "runtimeTargets": { + "runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "MongoDB.Bson/3.5.0": { + "type": "package", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "5.0.0" + }, + "compile": { + "lib/net6.0/MongoDB.Bson.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/MongoDB.Bson.dll": { + "related": ".xml" + } + } + }, + "MongoDB.Driver/3.5.0": { + "type": "package", + "dependencies": { + "DnsClient": "1.6.1", + "Microsoft.Extensions.Logging.Abstractions": "2.0.0", + "MongoDB.Bson": "3.5.0", + "SharpCompress": "0.30.1", + "Snappier": "1.0.0", + "System.Buffers": "4.5.1", + "ZstdSharp.Port": "0.7.3" + }, + "compile": { + "lib/net6.0/MongoDB.Driver.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/MongoDB.Driver.dll": { + "related": ".xml" + } + } + }, + "Newtonsoft.Json/13.0.4": { + "type": "package", + "compile": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + }, + "NLog/6.0.6": { + "type": "package", + "compile": { + "lib/netstandard2.1/NLog.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.1/NLog.dll": { + "related": ".xml" + } + } + }, + "protobuf-net/3.2.56": { + "type": "package", + "dependencies": { + "protobuf-net.Core": "3.2.56" + }, + "compile": { + "lib/net8.0/protobuf-net.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/protobuf-net.dll": { + "related": ".xml" + } + } + }, + "protobuf-net.Core/3.2.56": { + "type": "package", + "compile": { + "lib/net8.0/protobuf-net.Core.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/protobuf-net.Core.dll": { + "related": ".xml" + } + } + }, + "SharpCompress/0.30.1": { + "type": "package", + "compile": { + "lib/net5.0/SharpCompress.dll": {} + }, + "runtime": { + "lib/net5.0/SharpCompress.dll": {} + } + }, + "Snappier/1.0.0": { + "type": "package", + "compile": { + "lib/net5.0/Snappier.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net5.0/Snappier.dll": { + "related": ".xml" + } + } + }, + "System.Buffers/4.5.1": { + "type": "package", + "compile": { + "ref/netcoreapp2.0/_._": {} + }, + "runtime": { + "lib/netcoreapp2.0/_._": {} + } + }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.14.0", + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "compile": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "related": ".xml" + } + } + }, + "System.Memory/4.5.5": { + "type": "package", + "compile": { + "ref/netcoreapp2.1/_._": {} + }, + "runtime": { + "lib/netcoreapp2.1/_._": {} + } + }, + "System.Runtime.CompilerServices.Unsafe/5.0.0": { + "type": "package", + "compile": { + "ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "related": ".xml" + } + } + }, + "System.Security.AccessControl/5.0.0": { + "type": "package", + "dependencies": { + "Microsoft.NETCore.Platforms": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/System.Security.AccessControl.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/System.Security.AccessControl.dll": { + "related": ".xml" + } + }, + "runtimeTargets": { + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "System.Security.Principal.Windows/5.0.0": { + "type": "package", + "compile": { + "ref/netcoreapp3.0/System.Security.Principal.Windows.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/System.Security.Principal.Windows.dll": { + "related": ".xml" + } + }, + "runtimeTargets": { + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": { + "assetType": "runtime", + "rid": "unix" + }, + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "ZstdSharp.Port/0.7.3": { + "type": "package", + "compile": { + "lib/net7.0/ZstdSharp.dll": {} + }, + "runtime": { + "lib/net7.0/ZstdSharp.dll": {} + } + }, + "Entity/1.0.0": { + "type": "project", + "framework": ".NETCoreApp,Version=v9.0", + "dependencies": { + "Fantasy-Net": "2025.2.0", + "Microsoft.IdentityModel.Tokens": "8.14.0", + "System.IdentityModel.Tokens.Jwt": "8.14.0", + "ThirdParty": "1.0.0" + }, + "compile": { + "bin/placeholder/Entity.dll": {} + }, + "runtime": { + "bin/placeholder/Entity.dll": {} + } + }, + "Hotfix/1.0.0": { + "type": "project", + "framework": ".NETCoreApp,Version=v9.0", + "dependencies": { + "Entity": "1.0.0" + }, + "compile": { + "bin/placeholder/Hotfix.dll": {} + }, + "runtime": { + "bin/placeholder/Hotfix.dll": {} + } + }, + "ThirdParty/1.0.0": { + "type": "project", + "framework": ".NETCoreApp,Version=v8.0", + "compile": { + "bin/placeholder/ThirdParty.dll": {} + }, + "runtime": { + "bin/placeholder/ThirdParty.dll": {} + } + } + } + }, + "libraries": { + "CommandLineParser/2.9.1": { + "sha512": "OE0sl1/sQ37bjVsPKKtwQlWDgqaxWgtme3xZz7JssWUzg5JpMIyHgCTY9MVMxOg48fJ1AgGT3tgdH5m/kQ5xhA==", + "type": "package", + "path": "commandlineparser/2.9.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "CommandLine20.png", + "License.md", + "README.md", + "commandlineparser.2.9.1.nupkg.sha512", + "commandlineparser.nuspec", + "lib/net40/CommandLine.dll", + "lib/net40/CommandLine.xml", + "lib/net45/CommandLine.dll", + "lib/net45/CommandLine.xml", + "lib/net461/CommandLine.dll", + "lib/net461/CommandLine.xml", + "lib/netstandard2.0/CommandLine.dll", + "lib/netstandard2.0/CommandLine.xml" + ] + }, + "DnsClient/1.6.1": { + "sha512": "4H/f2uYJOZ+YObZjpY9ABrKZI+JNw3uizp6oMzTXwDw6F+2qIPhpRl/1t68O/6e98+vqNiYGu+lswmwdYUy3gg==", + "type": "package", + "path": "dnsclient/1.6.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "dnsclient.1.6.1.nupkg.sha512", + "dnsclient.nuspec", + "icon.png", + "lib/net45/DnsClient.dll", + "lib/net45/DnsClient.xml", + "lib/net471/DnsClient.dll", + "lib/net471/DnsClient.xml", + "lib/net5.0/DnsClient.dll", + "lib/net5.0/DnsClient.xml", + "lib/netstandard1.3/DnsClient.dll", + "lib/netstandard1.3/DnsClient.xml", + "lib/netstandard2.0/DnsClient.dll", + "lib/netstandard2.0/DnsClient.xml", + "lib/netstandard2.1/DnsClient.dll", + "lib/netstandard2.1/DnsClient.xml" + ] + }, + "Fantasy-Net/2025.2.0": { + "sha512": "vCkduwxkMlH8GozyS+ZlWGLC4nGjFGaL13Ah4w5HL55XAJaAhe+RX+gbSRNBeJf1Uu0cjG2MgVyS4NX7bXdN4g==", + "type": "package", + "path": "fantasy-net/2025.2.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE", + "README.md", + "analyzers/dotnet/cs/Fantasy.SourceGenerator.dll", + "build/Fantasy-Net.props", + "build/Fantasy-Net.targets", + "build/Fantasy.config", + "build/Fantasy.xsd", + "buildTransitive/Fantasy-Net.targets", + "buildTransitive/Fantasy.config", + "buildTransitive/Fantasy.xsd", + "fantasy-net.2025.2.0.nupkg.sha512", + "fantasy-net.nuspec", + "icon.png", + "lib/net8.0/Fantasy-Net.dll", + "lib/net9.0/Fantasy-Net.dll" + ] + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { + "sha512": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "type": "package", + "path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "PACKAGE.md", + "THIRD-PARTY-NOTICES.TXT", + "buildTransitive/net461/Microsoft.Extensions.DependencyInjection.Abstractions.targets", + "buildTransitive/net462/_._", + "buildTransitive/net6.0/_._", + "buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.Abstractions.targets", + "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.xml", + "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512", + "microsoft.extensions.dependencyinjection.abstractions.nuspec", + "useSharedDesignerContext.txt" + ] + }, + "Microsoft.Extensions.Logging.Abstractions/8.0.0": { + "sha512": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "type": "package", + "path": "microsoft.extensions.logging.abstractions/8.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "PACKAGE.md", + "THIRD-PARTY-NOTICES.TXT", + "analyzers/dotnet/roslyn3.11/cs/Microsoft.Extensions.Logging.Generators.dll", + "analyzers/dotnet/roslyn3.11/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn3.11/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/Microsoft.Extensions.Logging.Generators.dll", + "analyzers/dotnet/roslyn4.0/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.0/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/Microsoft.Extensions.Logging.Generators.dll", + "analyzers/dotnet/roslyn4.4/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", + "analyzers/dotnet/roslyn4.4/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", + "buildTransitive/net461/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/net462/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/netcoreapp2.0/Microsoft.Extensions.Logging.Abstractions.targets", + "buildTransitive/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.targets", + "lib/net462/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net462/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/net6.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net6.0/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net7.0/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.xml", + "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll", + "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.xml", + "microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512", + "microsoft.extensions.logging.abstractions.nuspec", + "useSharedDesignerContext.txt" + ] + }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "sha512": "iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==", + "type": "package", + "path": "microsoft.identitymodel.abstractions/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Abstractions.dll", + "lib/net462/Microsoft.IdentityModel.Abstractions.xml", + "lib/net472/Microsoft.IdentityModel.Abstractions.dll", + "lib/net472/Microsoft.IdentityModel.Abstractions.xml", + "lib/net6.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net6.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/net8.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net8.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net9.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.xml", + "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512", + "microsoft.identitymodel.abstractions.nuspec" + ] + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "sha512": "4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==", + "type": "package", + "path": "microsoft.identitymodel.jsonwebtokens/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net462/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net472/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net472/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512", + "microsoft.identitymodel.jsonwebtokens.nuspec" + ] + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "sha512": "eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==", + "type": "package", + "path": "microsoft.identitymodel.logging/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Logging.dll", + "lib/net462/Microsoft.IdentityModel.Logging.xml", + "lib/net472/Microsoft.IdentityModel.Logging.dll", + "lib/net472/Microsoft.IdentityModel.Logging.xml", + "lib/net6.0/Microsoft.IdentityModel.Logging.dll", + "lib/net6.0/Microsoft.IdentityModel.Logging.xml", + "lib/net8.0/Microsoft.IdentityModel.Logging.dll", + "lib/net8.0/Microsoft.IdentityModel.Logging.xml", + "lib/net9.0/Microsoft.IdentityModel.Logging.dll", + "lib/net9.0/Microsoft.IdentityModel.Logging.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Logging.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Logging.xml", + "microsoft.identitymodel.logging.8.14.0.nupkg.sha512", + "microsoft.identitymodel.logging.nuspec" + ] + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "sha512": "lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==", + "type": "package", + "path": "microsoft.identitymodel.tokens/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Tokens.dll", + "lib/net462/Microsoft.IdentityModel.Tokens.xml", + "lib/net472/Microsoft.IdentityModel.Tokens.dll", + "lib/net472/Microsoft.IdentityModel.Tokens.xml", + "lib/net6.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net6.0/Microsoft.IdentityModel.Tokens.xml", + "lib/net8.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net8.0/Microsoft.IdentityModel.Tokens.xml", + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net9.0/Microsoft.IdentityModel.Tokens.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.xml", + "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512", + "microsoft.identitymodel.tokens.nuspec" + ] + }, + "Microsoft.NETCore.Platforms/5.0.0": { + "sha512": "VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==", + "type": "package", + "path": "microsoft.netcore.platforms/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/netstandard1.0/_._", + "microsoft.netcore.platforms.5.0.0.nupkg.sha512", + "microsoft.netcore.platforms.nuspec", + "runtime.json", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "Microsoft.Win32.Registry/5.0.0": { + "sha512": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "type": "package", + "path": "microsoft.win32.registry/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/Microsoft.Win32.Registry.dll", + "lib/net461/Microsoft.Win32.Registry.dll", + "lib/net461/Microsoft.Win32.Registry.xml", + "lib/netstandard1.3/Microsoft.Win32.Registry.dll", + "lib/netstandard2.0/Microsoft.Win32.Registry.dll", + "lib/netstandard2.0/Microsoft.Win32.Registry.xml", + "microsoft.win32.registry.5.0.0.nupkg.sha512", + "microsoft.win32.registry.nuspec", + "ref/net46/Microsoft.Win32.Registry.dll", + "ref/net461/Microsoft.Win32.Registry.dll", + "ref/net461/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/Microsoft.Win32.Registry.dll", + "ref/netstandard1.3/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/de/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/es/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/fr/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/it/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/ja/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/ko/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/ru/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/zh-hans/Microsoft.Win32.Registry.xml", + "ref/netstandard1.3/zh-hant/Microsoft.Win32.Registry.xml", + "ref/netstandard2.0/Microsoft.Win32.Registry.dll", + "ref/netstandard2.0/Microsoft.Win32.Registry.xml", + "runtimes/win/lib/net46/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/net461/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/net461/Microsoft.Win32.Registry.xml", + "runtimes/win/lib/netstandard1.3/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.dll", + "runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.xml", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "MongoDB.Bson/3.5.0": { + "sha512": "JGNK6BanLDEifgkvPLqVFCPus5EDCy416pxf1dxUBRSVd3D9+NB3AvMVX190eXlk5/UXuCxpsQv7jWfNKvppBQ==", + "type": "package", + "path": "mongodb.bson/3.5.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net472/MongoDB.Bson.dll", + "lib/net472/MongoDB.Bson.xml", + "lib/net6.0/MongoDB.Bson.dll", + "lib/net6.0/MongoDB.Bson.xml", + "lib/netstandard2.1/MongoDB.Bson.dll", + "lib/netstandard2.1/MongoDB.Bson.xml", + "mongodb.bson.3.5.0.nupkg.sha512", + "mongodb.bson.nuspec", + "packageIcon.png" + ] + }, + "MongoDB.Driver/3.5.0": { + "sha512": "ST90u7psyMkNNOWFgSkexsrB3kPn7Ynl2DlMFj2rJyYuc6SIxjmzu4ufy51yzM+cPVE1SvVcdb5UFobrRw6cMg==", + "type": "package", + "path": "mongodb.driver/3.5.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net472/MongoDB.Driver.dll", + "lib/net472/MongoDB.Driver.xml", + "lib/net6.0/MongoDB.Driver.dll", + "lib/net6.0/MongoDB.Driver.xml", + "lib/netstandard2.1/MongoDB.Driver.dll", + "lib/netstandard2.1/MongoDB.Driver.xml", + "mongodb.driver.3.5.0.nupkg.sha512", + "mongodb.driver.nuspec", + "packageIcon.png" + ] + }, + "Newtonsoft.Json/13.0.4": { + "sha512": "pdgNNMai3zv51W5aq268sujXUyx7SNdE2bj1wZcWjAQrKMFZV260lbqYop1d2GM67JI1huLRwxo9ZqnfF/lC6A==", + "type": "package", + "path": "newtonsoft.json/13.0.4", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "README.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/net6.0/Newtonsoft.Json.dll", + "lib/net6.0/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.4.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "NLog/6.0.6": { + "sha512": "eUd/LDIwPtufj5OxtzFYiwuoKpzaS87iqO9P9D05avLCk4jIoOlqMwRH0o/43LmzM+CmgVAdDrCOq/rOK0sDKw==", + "type": "package", + "path": "nlog/6.0.6", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "N.png", + "lib/net35/NLog.dll", + "lib/net35/NLog.xml", + "lib/net45/NLog.dll", + "lib/net45/NLog.xml", + "lib/net46/NLog.dll", + "lib/net46/NLog.xml", + "lib/netstandard2.0/NLog.dll", + "lib/netstandard2.0/NLog.xml", + "lib/netstandard2.1/NLog.dll", + "lib/netstandard2.1/NLog.xml", + "nlog.6.0.6.nupkg.sha512", + "nlog.nuspec" + ] + }, + "protobuf-net/3.2.56": { + "sha512": "4IPJeTYAMNewlN8MDaFkcmR/9hLhJeo9eARnTh104zh7mf+vXT2gu5MUfUnkSQU+CH578Q6vcdU7LQDQPG6eaw==", + "type": "package", + "path": "protobuf-net/3.2.56", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net462/protobuf-net.dll", + "lib/net462/protobuf-net.xml", + "lib/net8.0/protobuf-net.dll", + "lib/net8.0/protobuf-net.xml", + "lib/netstandard2.0/protobuf-net.dll", + "lib/netstandard2.0/protobuf-net.xml", + "lib/netstandard2.1/protobuf-net.dll", + "lib/netstandard2.1/protobuf-net.xml", + "protobuf-net.3.2.56.nupkg.sha512", + "protobuf-net.nuspec", + "protobuf-net.png", + "readme.md" + ] + }, + "protobuf-net.Core/3.2.56": { + "sha512": "d6QOukTpDzs7zZv9tPnBZMtvHDNeHJQXUhMx54g4urUQsXK3oo9U70H9HvklYq7hlQ4A7AHJl7EVEqyCXXIl8Q==", + "type": "package", + "path": "protobuf-net.core/3.2.56", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net462/protobuf-net.Core.dll", + "lib/net462/protobuf-net.Core.xml", + "lib/net8.0/protobuf-net.Core.dll", + "lib/net8.0/protobuf-net.Core.xml", + "lib/netstandard2.0/protobuf-net.Core.dll", + "lib/netstandard2.0/protobuf-net.Core.xml", + "lib/netstandard2.1/protobuf-net.Core.dll", + "lib/netstandard2.1/protobuf-net.Core.xml", + "protobuf-net.core.3.2.56.nupkg.sha512", + "protobuf-net.core.nuspec", + "protobuf-net.png", + "readme.md" + ] + }, + "SharpCompress/0.30.1": { + "sha512": "XqD4TpfyYGa7QTPzaGlMVbcecKnXy4YmYLDWrU+JIj7IuRNl7DH2END+Ll7ekWIY8o3dAMWLFDE1xdhfIWD1nw==", + "type": "package", + "path": "sharpcompress/0.30.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net461/SharpCompress.dll", + "lib/net5.0/SharpCompress.dll", + "lib/netcoreapp3.1/SharpCompress.dll", + "lib/netstandard2.0/SharpCompress.dll", + "lib/netstandard2.1/SharpCompress.dll", + "sharpcompress.0.30.1.nupkg.sha512", + "sharpcompress.nuspec" + ] + }, + "Snappier/1.0.0": { + "sha512": "rFtK2KEI9hIe8gtx3a0YDXdHOpedIf9wYCEYtBEmtlyiWVX3XlCNV03JrmmAi/Cdfn7dxK+k0sjjcLv4fpHnqA==", + "type": "package", + "path": "snappier/1.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "COPYING.txt", + "lib/net5.0/Snappier.dll", + "lib/net5.0/Snappier.xml", + "lib/netcoreapp3.0/Snappier.dll", + "lib/netcoreapp3.0/Snappier.xml", + "lib/netstandard2.0/Snappier.dll", + "lib/netstandard2.0/Snappier.xml", + "lib/netstandard2.1/Snappier.dll", + "lib/netstandard2.1/Snappier.xml", + "snappier.1.0.0.nupkg.sha512", + "snappier.nuspec" + ] + }, + "System.Buffers/4.5.1": { + "sha512": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==", + "type": "package", + "path": "system.buffers/4.5.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Buffers.dll", + "lib/net461/System.Buffers.xml", + "lib/netcoreapp2.0/_._", + "lib/netstandard1.1/System.Buffers.dll", + "lib/netstandard1.1/System.Buffers.xml", + "lib/netstandard2.0/System.Buffers.dll", + "lib/netstandard2.0/System.Buffers.xml", + "lib/uap10.0.16299/_._", + "ref/net45/System.Buffers.dll", + "ref/net45/System.Buffers.xml", + "ref/netcoreapp2.0/_._", + "ref/netstandard1.1/System.Buffers.dll", + "ref/netstandard1.1/System.Buffers.xml", + "ref/netstandard2.0/System.Buffers.dll", + "ref/netstandard2.0/System.Buffers.xml", + "ref/uap10.0.16299/_._", + "system.buffers.4.5.1.nupkg.sha512", + "system.buffers.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "sha512": "EYGgN/S+HK7S6F3GaaPLFAfK0UzMrkXFyWCvXpQWFYmZln3dqtbyIO7VuTM/iIIPMzkelg8ZLlBPvMhxj6nOAA==", + "type": "package", + "path": "system.identitymodel.tokens.jwt/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/System.IdentityModel.Tokens.Jwt.dll", + "lib/net462/System.IdentityModel.Tokens.Jwt.xml", + "lib/net472/System.IdentityModel.Tokens.Jwt.dll", + "lib/net472/System.IdentityModel.Tokens.Jwt.xml", + "lib/net6.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net6.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/net8.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net8.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net9.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.xml", + "system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512", + "system.identitymodel.tokens.jwt.nuspec" + ] + }, + "System.Memory/4.5.5": { + "sha512": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "type": "package", + "path": "system.memory/4.5.5", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Memory.dll", + "lib/net461/System.Memory.xml", + "lib/netcoreapp2.1/_._", + "lib/netstandard1.1/System.Memory.dll", + "lib/netstandard1.1/System.Memory.xml", + "lib/netstandard2.0/System.Memory.dll", + "lib/netstandard2.0/System.Memory.xml", + "ref/netcoreapp2.1/_._", + "system.memory.4.5.5.nupkg.sha512", + "system.memory.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Runtime.CompilerServices.Unsafe/5.0.0": { + "sha512": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==", + "type": "package", + "path": "system.runtime.compilerservices.unsafe/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net45/System.Runtime.CompilerServices.Unsafe.dll", + "lib/net45/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netstandard1.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netstandard1.0/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/net461/System.Runtime.CompilerServices.Unsafe.dll", + "ref/net461/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard1.0/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard1.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard2.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.xml", + "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512", + "system.runtime.compilerservices.unsafe.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.AccessControl/5.0.0": { + "sha512": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "type": "package", + "path": "system.security.accesscontrol/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/System.Security.AccessControl.dll", + "lib/net461/System.Security.AccessControl.dll", + "lib/net461/System.Security.AccessControl.xml", + "lib/netstandard1.3/System.Security.AccessControl.dll", + "lib/netstandard2.0/System.Security.AccessControl.dll", + "lib/netstandard2.0/System.Security.AccessControl.xml", + "lib/uap10.0.16299/_._", + "ref/net46/System.Security.AccessControl.dll", + "ref/net461/System.Security.AccessControl.dll", + "ref/net461/System.Security.AccessControl.xml", + "ref/netstandard1.3/System.Security.AccessControl.dll", + "ref/netstandard1.3/System.Security.AccessControl.xml", + "ref/netstandard1.3/de/System.Security.AccessControl.xml", + "ref/netstandard1.3/es/System.Security.AccessControl.xml", + "ref/netstandard1.3/fr/System.Security.AccessControl.xml", + "ref/netstandard1.3/it/System.Security.AccessControl.xml", + "ref/netstandard1.3/ja/System.Security.AccessControl.xml", + "ref/netstandard1.3/ko/System.Security.AccessControl.xml", + "ref/netstandard1.3/ru/System.Security.AccessControl.xml", + "ref/netstandard1.3/zh-hans/System.Security.AccessControl.xml", + "ref/netstandard1.3/zh-hant/System.Security.AccessControl.xml", + "ref/netstandard2.0/System.Security.AccessControl.dll", + "ref/netstandard2.0/System.Security.AccessControl.xml", + "ref/uap10.0.16299/_._", + "runtimes/win/lib/net46/System.Security.AccessControl.dll", + "runtimes/win/lib/net461/System.Security.AccessControl.dll", + "runtimes/win/lib/net461/System.Security.AccessControl.xml", + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll", + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.xml", + "runtimes/win/lib/netstandard1.3/System.Security.AccessControl.dll", + "runtimes/win/lib/uap10.0.16299/_._", + "system.security.accesscontrol.5.0.0.nupkg.sha512", + "system.security.accesscontrol.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.Principal.Windows/5.0.0": { + "sha512": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==", + "type": "package", + "path": "system.security.principal.windows/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/System.Security.Principal.Windows.dll", + "lib/net461/System.Security.Principal.Windows.dll", + "lib/net461/System.Security.Principal.Windows.xml", + "lib/netstandard1.3/System.Security.Principal.Windows.dll", + "lib/netstandard2.0/System.Security.Principal.Windows.dll", + "lib/netstandard2.0/System.Security.Principal.Windows.xml", + "lib/uap10.0.16299/_._", + "ref/net46/System.Security.Principal.Windows.dll", + "ref/net461/System.Security.Principal.Windows.dll", + "ref/net461/System.Security.Principal.Windows.xml", + "ref/netcoreapp3.0/System.Security.Principal.Windows.dll", + "ref/netcoreapp3.0/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/System.Security.Principal.Windows.dll", + "ref/netstandard1.3/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/de/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/es/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/fr/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/it/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ja/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ko/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ru/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/zh-hans/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/zh-hant/System.Security.Principal.Windows.xml", + "ref/netstandard2.0/System.Security.Principal.Windows.dll", + "ref/netstandard2.0/System.Security.Principal.Windows.xml", + "ref/uap10.0.16299/_._", + "runtimes/unix/lib/netcoreapp2.0/System.Security.Principal.Windows.dll", + "runtimes/unix/lib/netcoreapp2.0/System.Security.Principal.Windows.xml", + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll", + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.xml", + "runtimes/win/lib/net46/System.Security.Principal.Windows.dll", + "runtimes/win/lib/net461/System.Security.Principal.Windows.dll", + "runtimes/win/lib/net461/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netcoreapp2.0/System.Security.Principal.Windows.dll", + "runtimes/win/lib/netcoreapp2.0/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll", + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netstandard1.3/System.Security.Principal.Windows.dll", + "runtimes/win/lib/uap10.0.16299/_._", + "system.security.principal.windows.5.0.0.nupkg.sha512", + "system.security.principal.windows.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "ZstdSharp.Port/0.7.3": { + "sha512": "U9Ix4l4cl58Kzz1rJzj5hoVTjmbx1qGMwzAcbv1j/d3NzrFaESIurQyg+ow4mivCgkE3S413y+U9k4WdnEIkRA==", + "type": "package", + "path": "zstdsharp.port/0.7.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net461/ZstdSharp.dll", + "lib/net5.0/ZstdSharp.dll", + "lib/net6.0/ZstdSharp.dll", + "lib/net7.0/ZstdSharp.dll", + "lib/netcoreapp3.1/ZstdSharp.dll", + "lib/netstandard2.0/ZstdSharp.dll", + "lib/netstandard2.1/ZstdSharp.dll", + "zstdsharp.port.0.7.3.nupkg.sha512", + "zstdsharp.port.nuspec" + ] + }, + "Entity/1.0.0": { + "type": "project", + "path": "../Entity/Entity.csproj", + "msbuildProject": "../Entity/Entity.csproj" + }, + "Hotfix/1.0.0": { + "type": "project", + "path": "../Hotfix/Hotfix.csproj", + "msbuildProject": "../Hotfix/Hotfix.csproj" + }, + "ThirdParty/1.0.0": { + "type": "project", + "path": "../ThirdParty/ThirdParty.csproj", + "msbuildProject": "../ThirdParty/ThirdParty.csproj" + } + }, + "projectFileDependencyGroups": { + "net9.0": [ + "Entity >= 1.0.0", + "Hotfix >= 1.0.0", + "NLog >= *" + ] + }, + "packageFolders": { + "C:\\Users\\FIREBAT\\.nuget\\packages\\": {}, + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\Main\\Main.csproj", + "projectName": "Main", + "projectPath": "D:\\work\\Fishing2Server\\Main\\Main.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\Main\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net9.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "projectReferences": { + "D:\\work\\Fishing2Server\\Entity\\Entity.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\Entity\\Entity.csproj" + }, + "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj": { + "projectPath": "D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net9.0": { + "targetAlias": "net9.0", + "dependencies": { + "NLog": { + "target": "Package", + "version": "[*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/Main/obj/project.nuget.cache b/Main/obj/project.nuget.cache new file mode 100644 index 0000000..cca274d --- /dev/null +++ b/Main/obj/project.nuget.cache @@ -0,0 +1,35 @@ +{ + "version": 2, + "dgSpecHash": "tXEWsEHCjQI=", + "success": true, + "projectFilePath": "D:\\work\\Fishing2Server\\Main\\Main.csproj", + "expectedPackageFiles": [ + "C:\\Users\\FIREBAT\\.nuget\\packages\\commandlineparser\\2.9.1\\commandlineparser.2.9.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\dnsclient\\1.6.1\\dnsclient.1.6.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\fantasy-net\\2025.2.0\\fantasy-net.2025.2.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\8.0.0\\microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\8.0.0\\microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.abstractions\\8.14.0\\microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.jsonwebtokens\\8.14.0\\microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.logging\\8.14.0\\microsoft.identitymodel.logging.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.identitymodel.tokens\\8.14.0\\microsoft.identitymodel.tokens.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.netcore.platforms\\5.0.0\\microsoft.netcore.platforms.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\microsoft.win32.registry\\5.0.0\\microsoft.win32.registry.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\mongodb.bson\\3.5.0\\mongodb.bson.3.5.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\mongodb.driver\\3.5.0\\mongodb.driver.3.5.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\newtonsoft.json\\13.0.4\\newtonsoft.json.13.0.4.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\nlog\\6.0.6\\nlog.6.0.6.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\protobuf-net\\3.2.56\\protobuf-net.3.2.56.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\protobuf-net.core\\3.2.56\\protobuf-net.core.3.2.56.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\sharpcompress\\0.30.1\\sharpcompress.0.30.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\snappier\\1.0.0\\snappier.1.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.buffers\\4.5.1\\system.buffers.4.5.1.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.identitymodel.tokens.jwt\\8.14.0\\system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.memory\\4.5.5\\system.memory.4.5.5.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\5.0.0\\system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.security.accesscontrol\\5.0.0\\system.security.accesscontrol.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\system.security.principal.windows\\5.0.0\\system.security.principal.windows.5.0.0.nupkg.sha512", + "C:\\Users\\FIREBAT\\.nuget\\packages\\zstdsharp.port\\0.7.3\\zstdsharp.port.0.7.3.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/Main/obj/project.packagespec.json b/Main/obj/project.packagespec.json new file mode 100644 index 0000000..2b7f131 --- /dev/null +++ b/Main/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"D:\\work\\Fishing2Server\\Main\\Main.csproj","projectName":"Main","projectPath":"D:\\work\\Fishing2Server\\Main\\Main.csproj","outputPath":"D:\\work\\Fishing2Server\\Main\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"],"originalTargetFrameworks":["net9.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net9.0":{"targetAlias":"net9.0","projectReferences":{"D:\\work\\Fishing2Server\\Entity\\Entity.csproj":{"projectPath":"D:\\work\\Fishing2Server\\Entity\\Entity.csproj"},"D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj":{"projectPath":"D:\\work\\Fishing2Server\\Hotfix\\Hotfix.csproj"}}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"},"SdkAnalysisLevel":"9.0.300"}"frameworks":{"net9.0":{"targetAlias":"net9.0","dependencies":{"NLog":{"target":"Package","version":"[*, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/Main/obj/rider.project.model.nuget.info b/Main/obj/rider.project.model.nuget.info new file mode 100644 index 0000000..6d2746b --- /dev/null +++ b/Main/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17628533865638419 \ No newline at end of file diff --git a/Main/obj/rider.project.restore.info b/Main/obj/rider.project.restore.info new file mode 100644 index 0000000..fb450a1 --- /dev/null +++ b/Main/obj/rider.project.restore.info @@ -0,0 +1 @@ +17628541519681195 \ No newline at end of file diff --git a/Server.sln b/Server.sln index 29972cd..863f7de 100644 --- a/Server.sln +++ b/Server.sln @@ -1,18 +1,14 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fantasy.Net", "Fantasy\Fantasy.Net\Fantasy.Net\Fantasy.Net.csproj", "{7BDEBABB-8630-4B61-8AF4-75DD969F29E6}" +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Main", "Main/Main.csproj", "{E5006019-2E61-44C0-9465-5F4E58AC7A17}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Main", "Main\Main.csproj", "{FE0784FD-8ACB-42FB-82EC-81A1335C85CF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entity", "Entity/Entity.csproj", "{0F4F49DF-35F5-4D25-BEC9-8669B580E63B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entity", "Entity\Entity.csproj", "{85943714-1018-4E7D-9476-25CD66ACB0F0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hotfix", "Hotfix/Hotfix.csproj", "{FA3C7D20-D91A-4444-B5EB-CA39F7463A89}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hotfix", "Hotfix\Hotfix.csproj", "{B2740AB3-250F-44E2-B61D-8F3C4D9B4BEB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fantasy.ConfigTable", "Fantasy\Fantasy.Packages\Fantasy.ConfigTable\Net\Fantasy.ConfigTable.csproj", "{0A539FA2-C595-4AA3-A2C3-86BF86EA7FFB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Fantasy", "Fantasy", "{B1F4CF72-A767-4509-B050-8DB30D0DC40A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThirdParty", "ThirdParty\ThirdParty.csproj", "{9C25A89F-0C87-4F91-AEEA-2ECCD2763DC3}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThirdParty", "ThirdParty\ThirdParty.csproj", "{EEF04830-6481-4977-B0AA-3442E93FF9E7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -20,33 +16,21 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7BDEBABB-8630-4B61-8AF4-75DD969F29E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7BDEBABB-8630-4B61-8AF4-75DD969F29E6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7BDEBABB-8630-4B61-8AF4-75DD969F29E6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7BDEBABB-8630-4B61-8AF4-75DD969F29E6}.Release|Any CPU.Build.0 = Release|Any CPU - {FE0784FD-8ACB-42FB-82EC-81A1335C85CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FE0784FD-8ACB-42FB-82EC-81A1335C85CF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FE0784FD-8ACB-42FB-82EC-81A1335C85CF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FE0784FD-8ACB-42FB-82EC-81A1335C85CF}.Release|Any CPU.Build.0 = Release|Any CPU - {85943714-1018-4E7D-9476-25CD66ACB0F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {85943714-1018-4E7D-9476-25CD66ACB0F0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {85943714-1018-4E7D-9476-25CD66ACB0F0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {85943714-1018-4E7D-9476-25CD66ACB0F0}.Release|Any CPU.Build.0 = Release|Any CPU - {B2740AB3-250F-44E2-B61D-8F3C4D9B4BEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B2740AB3-250F-44E2-B61D-8F3C4D9B4BEB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B2740AB3-250F-44E2-B61D-8F3C4D9B4BEB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B2740AB3-250F-44E2-B61D-8F3C4D9B4BEB}.Release|Any CPU.Build.0 = Release|Any CPU - {0A539FA2-C595-4AA3-A2C3-86BF86EA7FFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0A539FA2-C595-4AA3-A2C3-86BF86EA7FFB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0A539FA2-C595-4AA3-A2C3-86BF86EA7FFB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0A539FA2-C595-4AA3-A2C3-86BF86EA7FFB}.Release|Any CPU.Build.0 = Release|Any CPU - {9C25A89F-0C87-4F91-AEEA-2ECCD2763DC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9C25A89F-0C87-4F91-AEEA-2ECCD2763DC3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9C25A89F-0C87-4F91-AEEA-2ECCD2763DC3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9C25A89F-0C87-4F91-AEEA-2ECCD2763DC3}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {0A539FA2-C595-4AA3-A2C3-86BF86EA7FFB} = {B1F4CF72-A767-4509-B050-8DB30D0DC40A} - {7BDEBABB-8630-4B61-8AF4-75DD969F29E6} = {B1F4CF72-A767-4509-B050-8DB30D0DC40A} + {E5006019-2E61-44C0-9465-5F4E58AC7A17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5006019-2E61-44C0-9465-5F4E58AC7A17}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5006019-2E61-44C0-9465-5F4E58AC7A17}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5006019-2E61-44C0-9465-5F4E58AC7A17}.Release|Any CPU.Build.0 = Release|Any CPU + {0F4F49DF-35F5-4D25-BEC9-8669B580E63B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F4F49DF-35F5-4D25-BEC9-8669B580E63B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F4F49DF-35F5-4D25-BEC9-8669B580E63B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F4F49DF-35F5-4D25-BEC9-8669B580E63B}.Release|Any CPU.Build.0 = Release|Any CPU + {FA3C7D20-D91A-4444-B5EB-CA39F7463A89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA3C7D20-D91A-4444-B5EB-CA39F7463A89}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA3C7D20-D91A-4444-B5EB-CA39F7463A89}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA3C7D20-D91A-4444-B5EB-CA39F7463A89}.Release|Any CPU.Build.0 = Release|Any CPU + {EEF04830-6481-4977-B0AA-3442E93FF9E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEF04830-6481-4977-B0AA-3442E93FF9E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEF04830-6481-4977-B0AA-3442E93FF9E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEF04830-6481-4977-B0AA-3442E93FF9E7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Server.sln.DotSettings.user b/Server.sln.DotSettings.user index c0de287..74d6cfe 100644 --- a/Server.sln.DotSettings.user +++ b/Server.sln.DotSettings.user @@ -1,93 +1,6 @@  - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - - \ No newline at end of file + ForceIncluded + ForceIncluded + ForceIncluded + ForceIncluded + ForceIncluded \ No newline at end of file diff --git a/ThirdParty/bin/Debug/net8.0/ThirdParty.deps.json b/ThirdParty/bin/Debug/net8.0/ThirdParty.deps.json new file mode 100644 index 0000000..84789c4 --- /dev/null +++ b/ThirdParty/bin/Debug/net8.0/ThirdParty.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v8.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v8.0": { + "ThirdParty/1.0.0": { + "runtime": { + "ThirdParty.dll": {} + } + } + } + }, + "libraries": { + "ThirdParty/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/ThirdParty/bin/Debug/net8.0/ThirdParty.dll b/ThirdParty/bin/Debug/net8.0/ThirdParty.dll new file mode 100644 index 0000000..c68db15 Binary files /dev/null and b/ThirdParty/bin/Debug/net8.0/ThirdParty.dll differ diff --git a/ThirdParty/bin/Debug/net8.0/ThirdParty.pdb b/ThirdParty/bin/Debug/net8.0/ThirdParty.pdb new file mode 100644 index 0000000..6d74378 Binary files /dev/null and b/ThirdParty/bin/Debug/net8.0/ThirdParty.pdb differ diff --git a/ThirdParty/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs b/ThirdParty/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs new file mode 100644 index 0000000..2217181 --- /dev/null +++ b/ThirdParty/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] diff --git a/ThirdParty/obj/Debug/net8.0/ThirdParty.AssemblyInfo.cs b/ThirdParty/obj/Debug/net8.0/ThirdParty.AssemblyInfo.cs new file mode 100644 index 0000000..ea1b1f0 --- /dev/null +++ b/ThirdParty/obj/Debug/net8.0/ThirdParty.AssemblyInfo.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("ThirdParty")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+7b10d4cb317c9f310649a9cb4afe3882d4b12624")] +[assembly: System.Reflection.AssemblyProductAttribute("ThirdParty")] +[assembly: System.Reflection.AssemblyTitleAttribute("ThirdParty")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// 由 MSBuild WriteCodeFragment 类生成。 + diff --git a/ThirdParty/obj/Debug/net8.0/ThirdParty.AssemblyInfoInputs.cache b/ThirdParty/obj/Debug/net8.0/ThirdParty.AssemblyInfoInputs.cache new file mode 100644 index 0000000..4db7bb4 --- /dev/null +++ b/ThirdParty/obj/Debug/net8.0/ThirdParty.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +343aff4060e1171ae9efe8ea48e50784b28c7410d94cfab84812dab9813996af diff --git a/ThirdParty/obj/Debug/net8.0/ThirdParty.GeneratedMSBuildEditorConfig.editorconfig b/ThirdParty/obj/Debug/net8.0/ThirdParty.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 0000000..5536950 --- /dev/null +++ b/ThirdParty/obj/Debug/net8.0/ThirdParty.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,15 @@ +is_global = true +build_property.TargetFramework = net8.0 +build_property.TargetPlatformMinVersion = +build_property.UsingMicrosoftNETSdkWeb = +build_property.ProjectTypeGuids = +build_property.InvariantGlobalization = +build_property.PlatformNeutralAssembly = +build_property.EnforceExtendedAnalyzerRules = +build_property._SupportedPlatformList = Linux,macOS,Windows +build_property.RootNamespace = ThirdParty +build_property.ProjectDir = D:\work\Fishing2Server\ThirdParty\ +build_property.EnableComHosting = +build_property.EnableGeneratedComInterfaceComImportInterop = +build_property.EffectiveAnalysisLevelStyle = 8.0 +build_property.EnableCodeStyleSeverity = diff --git a/ThirdParty/obj/Debug/net8.0/ThirdParty.GlobalUsings.g.cs b/ThirdParty/obj/Debug/net8.0/ThirdParty.GlobalUsings.g.cs new file mode 100644 index 0000000..8578f3d --- /dev/null +++ b/ThirdParty/obj/Debug/net8.0/ThirdParty.GlobalUsings.g.cs @@ -0,0 +1,8 @@ +// +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Net.Http; +global using global::System.Threading; +global using global::System.Threading.Tasks; diff --git a/ThirdParty/obj/Debug/net8.0/ThirdParty.assets.cache b/ThirdParty/obj/Debug/net8.0/ThirdParty.assets.cache new file mode 100644 index 0000000..c4ddefd Binary files /dev/null and b/ThirdParty/obj/Debug/net8.0/ThirdParty.assets.cache differ diff --git a/ThirdParty/obj/Debug/net8.0/ThirdParty.csproj.CoreCompileInputs.cache b/ThirdParty/obj/Debug/net8.0/ThirdParty.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..acb400e --- /dev/null +++ b/ThirdParty/obj/Debug/net8.0/ThirdParty.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +67676f43cfe61f8f0c588d3eb57c01718e4bdc9b7f4587b07207c9cd9eefc6bf diff --git a/ThirdParty/obj/Debug/net8.0/ThirdParty.csproj.FileListAbsolute.txt b/ThirdParty/obj/Debug/net8.0/ThirdParty.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..ca7481a --- /dev/null +++ b/ThirdParty/obj/Debug/net8.0/ThirdParty.csproj.FileListAbsolute.txt @@ -0,0 +1,22 @@ +D:\work\Fishing2Server\ThirdParty\bin\Debug\net8.0\ThirdParty.deps.json +D:\work\Fishing2Server\ThirdParty\bin\Debug\net8.0\ThirdParty.dll +D:\work\Fishing2Server\ThirdParty\bin\Debug\net8.0\ThirdParty.pdb +D:\work\Fishing2Server\ThirdParty\obj\Debug\net8.0\ThirdParty.GeneratedMSBuildEditorConfig.editorconfig +D:\work\Fishing2Server\ThirdParty\obj\Debug\net8.0\ThirdParty.AssemblyInfoInputs.cache +D:\work\Fishing2Server\ThirdParty\obj\Debug\net8.0\ThirdParty.AssemblyInfo.cs +D:\work\Fishing2Server\ThirdParty\obj\Debug\net8.0\ThirdParty.csproj.CoreCompileInputs.cache +D:\work\Fishing2Server\ThirdParty\obj\Debug\net8.0\ThirdParty.dll +D:\work\Fishing2Server\ThirdParty\obj\Debug\net8.0\refint\ThirdParty.dll +D:\work\Fishing2Server\ThirdParty\obj\Debug\net8.0\ThirdParty.pdb +D:\work\Fishing2Server\ThirdParty\obj\Debug\net8.0\ref\ThirdParty.dll +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\bin\Debug\net8.0\ThirdParty.deps.json +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\bin\Debug\net8.0\ThirdParty.dll +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\bin\Debug\net8.0\ThirdParty.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\obj\Debug\net8.0\ThirdParty.GeneratedMSBuildEditorConfig.editorconfig +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\obj\Debug\net8.0\ThirdParty.AssemblyInfoInputs.cache +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\obj\Debug\net8.0\ThirdParty.AssemblyInfo.cs +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\obj\Debug\net8.0\ThirdParty.csproj.CoreCompileInputs.cache +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\obj\Debug\net8.0\ThirdParty.dll +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\obj\Debug\net8.0\refint\ThirdParty.dll +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\obj\Debug\net8.0\ThirdParty.pdb +D:\work\Fishing2ServerNew\Fishing2\Server\ThirdParty\obj\Debug\net8.0\ref\ThirdParty.dll diff --git a/ThirdParty/obj/Debug/net8.0/ThirdParty.dll b/ThirdParty/obj/Debug/net8.0/ThirdParty.dll new file mode 100644 index 0000000..c68db15 Binary files /dev/null and b/ThirdParty/obj/Debug/net8.0/ThirdParty.dll differ diff --git a/ThirdParty/obj/Debug/net8.0/ThirdParty.pdb b/ThirdParty/obj/Debug/net8.0/ThirdParty.pdb new file mode 100644 index 0000000..6d74378 Binary files /dev/null and b/ThirdParty/obj/Debug/net8.0/ThirdParty.pdb differ diff --git a/ThirdParty/obj/Debug/net8.0/ref/ThirdParty.dll b/ThirdParty/obj/Debug/net8.0/ref/ThirdParty.dll new file mode 100644 index 0000000..9547fd1 Binary files /dev/null and b/ThirdParty/obj/Debug/net8.0/ref/ThirdParty.dll differ diff --git a/ThirdParty/obj/Debug/net8.0/refint/ThirdParty.dll b/ThirdParty/obj/Debug/net8.0/refint/ThirdParty.dll new file mode 100644 index 0000000..9547fd1 Binary files /dev/null and b/ThirdParty/obj/Debug/net8.0/refint/ThirdParty.dll differ diff --git a/ThirdParty/obj/ThirdParty.csproj.nuget.dgspec.json b/ThirdParty/obj/ThirdParty.csproj.nuget.dgspec.json new file mode 100644 index 0000000..34fe0b9 --- /dev/null +++ b/ThirdParty/obj/ThirdParty.csproj.nuget.dgspec.json @@ -0,0 +1,73 @@ +{ + "format": 1, + "restore": { + "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj": {} + }, + "projects": { + "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "projectName": "ThirdParty", + "projectPath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\ThirdParty\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net8.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/ThirdParty/obj/ThirdParty.csproj.nuget.g.props b/ThirdParty/obj/ThirdParty.csproj.nuget.g.props new file mode 100644 index 0000000..fbb082f --- /dev/null +++ b/ThirdParty/obj/ThirdParty.csproj.nuget.g.props @@ -0,0 +1,16 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + $(UserProfile)\.nuget\packages\ + C:\Users\FIREBAT\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages + PackageReference + 6.14.0 + + + + + + \ No newline at end of file diff --git a/ThirdParty/obj/ThirdParty.csproj.nuget.g.targets b/ThirdParty/obj/ThirdParty.csproj.nuget.g.targets new file mode 100644 index 0000000..3dc06ef --- /dev/null +++ b/ThirdParty/obj/ThirdParty.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/ThirdParty/obj/project.assets.json b/ThirdParty/obj/project.assets.json new file mode 100644 index 0000000..604a98f --- /dev/null +++ b/ThirdParty/obj/project.assets.json @@ -0,0 +1,79 @@ +{ + "version": 3, + "targets": { + "net8.0": {} + }, + "libraries": {}, + "projectFileDependencyGroups": { + "net8.0": [] + }, + "packageFolders": { + "C:\\Users\\FIREBAT\\.nuget\\packages\\": {}, + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "projectName": "ThirdParty", + "projectPath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "packagesPath": "C:\\Users\\FIREBAT\\.nuget\\packages\\", + "outputPath": "D:\\work\\Fishing2Server\\ThirdParty\\obj\\", + "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\FIREBAT\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net8.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + }, + "restoreAuditProperties": { + "enableAudit": "true", + "auditLevel": "low", + "auditMode": "direct" + }, + "SdkAnalysisLevel": "9.0.300" + }, + "frameworks": { + "net8.0": { + "targetAlias": "net8.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/ThirdParty/obj/project.nuget.cache b/ThirdParty/obj/project.nuget.cache new file mode 100644 index 0000000..5a9b4e8 --- /dev/null +++ b/ThirdParty/obj/project.nuget.cache @@ -0,0 +1,8 @@ +{ + "version": 2, + "dgSpecHash": "lXq0CpWaEKA=", + "success": true, + "projectFilePath": "D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj", + "expectedPackageFiles": [], + "logs": [] +} \ No newline at end of file diff --git a/ThirdParty/obj/project.packagespec.json b/ThirdParty/obj/project.packagespec.json new file mode 100644 index 0000000..bd75f68 --- /dev/null +++ b/ThirdParty/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj","projectName":"ThirdParty","projectPath":"D:\\work\\Fishing2Server\\ThirdParty\\ThirdParty.csproj","outputPath":"D:\\work\\Fishing2Server\\ThirdParty\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"],"originalTargetFrameworks":["net8.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net8.0":{"targetAlias":"net8.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"},"SdkAnalysisLevel":"9.0.300"}"frameworks":{"net8.0":{"targetAlias":"net8.0","imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/ThirdParty/obj/rider.project.model.nuget.info b/ThirdParty/obj/rider.project.model.nuget.info new file mode 100644 index 0000000..b93a03c --- /dev/null +++ b/ThirdParty/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17628533858668918 \ No newline at end of file diff --git a/ThirdParty/obj/rider.project.restore.info b/ThirdParty/obj/rider.project.restore.info new file mode 100644 index 0000000..ef1587a --- /dev/null +++ b/ThirdParty/obj/rider.project.restore.info @@ -0,0 +1 @@ +17628541514056906 \ No newline at end of file diff --git a/Tools/ConfigBuilder/ConfigBuilder.sln b/Tools/ConfigBuilder/ConfigBuilder.sln deleted file mode 100644 index ff5bae9..0000000 --- a/Tools/ConfigBuilder/ConfigBuilder.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.14.36408.4 d17.14 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBConfigBuilder", "NBConfigBuilder\NBConfigBuilder.csproj", "{A6264F0E-870D-401D-B1BF-698695AC674C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A6264F0E-870D-401D-B1BF-698695AC674C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A6264F0E-870D-401D-B1BF-698695AC674C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A6264F0E-870D-401D-B1BF-698695AC674C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A6264F0E-870D-401D-B1BF-698695AC674C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {F223241C-FF74-4903-8F47-8A5A5A0FAC99} - EndGlobalSection -EndGlobal diff --git a/Tools/ConfigBuilder/ConfigBuilder.sln.DotSettings.user b/Tools/ConfigBuilder/ConfigBuilder.sln.DotSettings.user deleted file mode 100644 index d5915f5..0000000 --- a/Tools/ConfigBuilder/ConfigBuilder.sln.DotSettings.user +++ /dev/null @@ -1,6 +0,0 @@ - - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/App.cs b/Tools/ConfigBuilder/NBConfigBuilder/App.cs deleted file mode 100644 index e824884..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/App.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace NBConfigBuilder; - -// 添加配置类 -public class AppConfig -{ - public string ExcelPath { get; set; } - public string ClientPath { get; set; } - public string ClientJsonPath { get; set; } - public string ServerPath { get; set; } - public string ServerJsonPath { get; set; } - public bool GenClient { get; set; } - public bool GenServer { get; set; } - - - public string ExcelVersionPath => Path.Combine(ExcelPath, "Version.txt"); -} - -public static class App -{ - public static AppConfig Config; -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Core/IPool.cs b/Tools/ConfigBuilder/NBConfigBuilder/Core/IPool.cs deleted file mode 100644 index 808a332..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Core/IPool.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace NBConfigBuilder; - -/// -/// 实现了这个接口代表支持对象池 -/// -public interface IPool -{ - /// - /// 是否从池里创建的 - /// - bool IsPool(); - /// - /// 设置是否从池里创建的 - /// - /// - void SetIsPool(bool isPool); -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Core/IntDictionaryConfig.cs b/Tools/ConfigBuilder/NBConfigBuilder/Core/IntDictionaryConfig.cs deleted file mode 100644 index 7d8a06a..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Core/IntDictionaryConfig.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace NBConfigBuilder; - -public partial class IntDictionaryConfig -{ - public Dictionary Dic; - public int this[int key] => GetValue(key); - - public bool TryGetValue(int key, out int value) - { - value = default; - - if (!Dic.ContainsKey(key)) - { - return false; - } - - value = Dic[key]; - return true; - } - - private int GetValue(int key) - { - return Dic.TryGetValue(key, out var value) ? value : 0; - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Core/MemoryStreamBuffer.cs b/Tools/ConfigBuilder/NBConfigBuilder/Core/MemoryStreamBuffer.cs deleted file mode 100644 index ddc6998..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Core/MemoryStreamBuffer.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Buffers; - -namespace NBConfigBuilder; - -public enum MemoryStreamBufferSource -{ - None = 0, - Pack = 1, - UnPack = 2, -} - -public sealed class MemoryStreamBuffer : MemoryStream, IBufferWriter -{ - public MemoryStreamBufferSource MemoryStreamBufferSource; - - public MemoryStreamBuffer() - { - } - - public MemoryStreamBuffer(MemoryStreamBufferSource memoryStreamBufferSource, int capacity) : base(capacity) - { - MemoryStreamBufferSource = memoryStreamBufferSource; - } - - public MemoryStreamBuffer(byte[] buffer) : base(buffer) - { - } - - public void Advance(int count) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), count, "The value of 'count' cannot be negative."); - } - - var newLength = Position + count; - - if (newLength != Length) - { - SetLength(newLength); - } - - Position = newLength; - } - - public Memory GetMemory(int sizeHint = 0) - { - if (sizeHint < 0) - { - throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint, - "The value of 'count' cannot be negative."); - } - - if (Length - Position <= sizeHint) - { - SetLength(Position + sizeHint); - } - - return new Memory(GetBuffer(), (int)Position, (int)(Length - Position)); - } - - public Span GetSpan(int sizeHint = 0) - { - if (sizeHint < 0) - { - throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint, - "The value of 'count' cannot be negative."); - } - - if (Length - Position <= sizeHint) - { - SetLength(Position + sizeHint); - } - - return new Span(GetBuffer(), (int)Position, (int)(Length - Position)); - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Core/OneToManyList.cs b/Tools/ConfigBuilder/NBConfigBuilder/Core/OneToManyList.cs deleted file mode 100644 index f6a1203..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Core/OneToManyList.cs +++ /dev/null @@ -1,217 +0,0 @@ -namespace NBConfigBuilder; - -/// -/// 可回收的、一对多关系的列表池。 -/// -/// 键的类型。 -/// 值的类型。 -public class OneToManyListPool : OneToManyList, IDisposable, IPool where TKey : notnull -{ - private bool _isPool; - private bool _isDispose; - - /// - /// 创建一个 一对多关系的列表池的实例。 - /// - /// 创建的实例。 - public static OneToManyListPool Create() - { - var list = Pool>.Rent(); - list._isDispose = false; - list._isPool = true; - return list; - } - - /// - /// 释放当前对象所占用的资源,并将对象回收到对象池中。 - /// - public void Dispose() - { - if (_isDispose) - { - return; - } - - _isDispose = true; - Clear(); - Pool>.Return(this); - } - - /// - /// 获取一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public bool IsPool() - { - return _isPool; - } - - /// - /// 设置一个值,该值指示当前实例是否为对象池中的实例。 - /// - /// - public void SetIsPool(bool isPool) - { - _isPool = isPool; - } -} - -/// -/// 一对多关系的列表字典。 -/// -/// 键的类型。 -/// 值的类型。 -public class OneToManyList : Dictionary> where TKey : notnull -{ - private readonly int _recyclingLimit = 120; - private static readonly List Empty = new List(); - private readonly Queue> _queue = new Queue>(); - - /// - /// 初始化一个新的 实例。 - /// - public OneToManyList() - { - } - - /// - /// 设置最大缓存数量 - /// - /// - /// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC. - /// 2:设置成0不控制数量,全部缓存 - /// - public OneToManyList(int recyclingLimit) - { - _recyclingLimit = recyclingLimit; - } - - /// - /// 判断给定的键和值是否存在于列表中。 - /// - /// 要搜索的键。 - /// 要搜索的值。 - /// 如果存在则为 ,否则为 - public bool Contains(TKey key, TValue value) - { - TryGetValue(key, out var list); - - return list != null && list.Contains(value); - } - - /// - /// 向列表中添加指定键和值。 - /// - /// 要添加值的键。 - /// 要添加的值。 - public void Add(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - list = Fetch(); - list.Add(value); - Add(key, list); - - return; - } - - list.Add(value); - } - - /// - /// 获取指定键对应的列表中的第一个值。 - /// - /// 要获取值的键。 - /// 键对应的列表中的第一个值。 - public TValue First(TKey key) - { - return !TryGetValue(key, out var list) ? default : list.FirstOrDefault(); - } - - /// - /// 从列表中移除指定键和值。 - /// - /// 要移除值的键。 - /// 要移除的值。 - /// 如果成功移除则为 ,否则为 - public bool RemoveValue(TKey key, TValue value) - { - if (!TryGetValue(key, out var list)) - { - return true; - } - - var isRemove = list.Remove(value); - - if (list.Count == 0) - { - isRemove = RemoveByKey(key); - } - - return isRemove; - } - - /// - /// 从列表中移除指定键及其关联的所有值。 - /// - /// 要移除的键。 - /// 如果成功移除则为 ,否则为 - public bool RemoveByKey(TKey key) - { - if (!TryGetValue(key, out var list)) - { - return false; - } - - Remove(key); - Recycle(list); - return true; - } - - /// - /// 获取指定键关联的所有值的列表。 - /// - /// 要获取值的键。 - /// 键关联的所有值的列表。 - public List GetValues(TKey key) - { - if (TryGetValue(key, out List list)) - { - return list; - } - - return Empty; - } - - /// - /// 清除字典中的所有键值对,并回收相关的值集合。 - /// - public new void Clear() - { - foreach (var keyValuePair in this) Recycle(keyValuePair.Value); - - base.Clear(); - } - - /// - /// 从空闲值集合队列中获取一个值集合,如果队列为空则创建一个新的值集合。 - /// - /// 从队列中获取的值集合。 - private List Fetch() - { - return _queue.Count <= 0 ? new List() : _queue.Dequeue(); - } - - /// - /// 回收一个不再使用的值集合到空闲值集合队列中。 - /// - /// 要回收的值集合。 - private void Recycle(List list) - { - list.Clear(); - - if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return; - - _queue.Enqueue(list); - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Core/Pool.cs b/Tools/ConfigBuilder/NBConfigBuilder/Core/Pool.cs deleted file mode 100644 index 989ac54..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Core/Pool.cs +++ /dev/null @@ -1,72 +0,0 @@ -namespace NBConfigBuilder; - -/// -/// 静态的对象池系统,不支持多线程。 -/// -/// -public static class Pool where T : IPool, new() -{ - private static readonly Queue PoolQueue = new Queue(); - - /// - /// 池子里可用的数量 - /// - public static int Count => PoolQueue.Count; - - /// - /// 租借 - /// - /// - public static T Rent() - { - return PoolQueue.Count == 0 ? new T() : PoolQueue.Dequeue(); - } - - /// - /// 租借 - /// - /// 如果池子里没有,会先执行这个委托。 - /// - public static T Rent(Func generator) - { - return PoolQueue.Count == 0 ? generator() : PoolQueue.Dequeue(); - } - - /// - /// 返还 - /// - /// - public static void Return(T t) - { - if (t == null) - { - return; - } - - PoolQueue.Enqueue(t); - } - - /// - /// 返还 - /// - /// 返还的东西 - /// 返还后执行的委托 - public static void Return(T t, Action reset) - { - if (t == null) - { - return; - } - - reset(t); - PoolQueue.Enqueue(t); - } - - /// - /// 清空池子 - /// - public static void Clear() - { - PoolQueue.Clear(); - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Core/Serialize/ASerialize.cs b/Tools/ConfigBuilder/NBConfigBuilder/Core/Serialize/ASerialize.cs deleted file mode 100644 index 67e7671..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Core/Serialize/ASerialize.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.ComponentModel; - -namespace Fantasy.Serialize; - -public abstract class ASerialize : ISupportInitialize, IDisposable -{ - public virtual void Dispose() - { - } - - public virtual void BeginInit() - { - } - - public virtual void EndInit() - { - } - - public virtual void AfterDeserialization() => EndInit(); -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Core/StringDictionaryConfig.cs b/Tools/ConfigBuilder/NBConfigBuilder/Core/StringDictionaryConfig.cs deleted file mode 100644 index bf8ae75..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Core/StringDictionaryConfig.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace NBConfigBuilder; - -public sealed partial class StringDictionaryConfig -{ - public Dictionary Dic; - public string this[int key] => GetValue(key); - - public bool TryGetValue(int key, out string value) - { - value = default; - - if (!Dic.ContainsKey(key)) - { - return false; - } - - value = Dic[key]; - return true; - } - - private string GetValue(int key) - { - return Dic.TryGetValue(key, out var value) ? value : null; - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelExporter.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelExporter.cs deleted file mode 100644 index 20031cb..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelExporter.cs +++ /dev/null @@ -1,750 +0,0 @@ -using System.Collections.Concurrent; -using System.Reflection; -using System.Runtime.Loader; -using System.Security.Cryptography; -using System.Text; -using System.Text.RegularExpressions; -using Microsoft.VisualBasic.ApplicationServices; -using Newtonsoft.Json; -using OfficeOpenXml; -using static System.String; - -namespace NBConfigBuilder; - -using TableDictionary = SortedDictionary>; - -/// -/// Excel 数据导出器,用于从 Excel 文件导出数据到二进制格式和生成 C# 类文件。 -/// -public sealed class ExcelExporter -{ - public ExportType ExportType; - private readonly string _excelProgramPath; - private readonly string _versionFilePath; - - // public VersionInfo VersionInfo; // 存储 Excel 文件的版本信息。 - private readonly Regex _regexName = new Regex("^[a-zA-Z][a-zA-Z0-9_]*$"); // 用于验证 Excel 表名的正则表达式。 - private readonly HashSet _loadFiles = [".xlsx", ".xlsm", ".csv"]; // 加载的支持文件扩展名。 - - private readonly ConcurrentDictionary _excelTables = - new ConcurrentDictionary(); // 存储解析后的 Excel 表。 - - /// - /// 导表支持的数据类型集合。 - /// - public static readonly HashSet ColTypeSet = - [ - "", "0", "bool", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "string", - "IntDictionaryConfig", "StringDictionaryConfig", - "short[]", "int[]", "long[]", "float[]", "string[]", "uint[]" - ]; - - // 进度报告回调 - private Action _progressCallback; - - static ExcelExporter() - { - ExcelPackage.License.SetNonCommercialOrganization("Fantasy"); - } - - /// - /// 根据指定的 exportType 初始化 ExcelExporter 类的新实例。 - /// - /// 要执行的导出类型(AllExcel 或 AllExcelIncrement)。 - public ExcelExporter(ExportType exportType) - { - ExportType = exportType; - - if (App.Config.ExcelVersionPath == null || App.Config.ExcelVersionPath.Trim() == "") - { - Log.Info($"ExcelVersionFile Can not be empty!"); - return; - } - - if (App.Config.ExcelPath == null || App.Config.ExcelPath.Trim() == "") - { - Log.Info($"ExcelProgramPath Can not be empty!"); - return; - } - - _excelProgramPath = FileHelper.GetFullPath(App.Config.ExcelPath); - _versionFilePath = FileHelper.GetFullPath(App.Config.ExcelVersionPath); - - if (App.Config.GenClient) - { - if (App.Config.ClientJsonPath == null || - App.Config.ClientJsonPath.Trim() == "") - { - Log.Info($"ExcelClientJsonDirectory Can not be empty!"); - return; - } - - if (App.Config.ClientPath == null || - App.Config.ClientPath.Trim() == "") - { - Log.Info($"ExcelServerFileDirectory Can not be empty!"); - return; - } - } - - if (App.Config.GenServer) - { - if (App.Config.ServerPath == null || - App.Config.ServerPath.Trim() == "") - { - Log.Info($"ExcelServerFileDirectory Can not be empty!"); - return; - } - - if (App.Config.ServerJsonPath == null || - App.Config.ServerJsonPath.Trim() == "") - { - Log.Info($"ExcelServerJsonDirectory Can not be empty!"); - return; - } - } - - switch (ExportType) - { - case ExportType.AllExcelIncrement: - { - break; - } - case ExportType.AllExcel: - { - if (File.Exists(_versionFilePath)) - { - File.Delete(_versionFilePath); - } - - break; - } - } - } - - /// - /// 设置进度报告回调 - /// - /// 进度报告回调函数 - public void SetProgressCallback(Action callback) - { - _progressCallback = callback; - } - - public void Run() - { - ReportProgress("正在查找配置文件..."); - Find(); - ReportProgress("正在解析配置表..."); - Parsing(); - ReportProgress("正在导出JSON数据..."); - ExportToJson(); - ReportProgress("导出完成"); - } - - private void ReportProgress(string message) - { - _progressCallback?.Invoke(message); - } - - /// - /// 查找配置文件 - /// - private void Find() - { - var dir = new DirectoryInfo(_excelProgramPath); - var excelFiles = dir.GetFiles("*", SearchOption.AllDirectories); - - if (excelFiles.Length <= 0) - { - return; - } - - - var tables = new List(); - - // var tables = new OneToManyList(); - foreach (var excelFile in excelFiles) - { - // 过滤掉非指定后缀的文件 - - if (!_loadFiles.Contains(excelFile.Extension)) - { - continue; - } - - var lastIndexOf = excelFile.Name.LastIndexOf(".", StringComparison.Ordinal); - - if (lastIndexOf < 0) - { - continue; - } - - var fullName = excelFile.FullName; - var excelName = excelFile.Name.Substring(0, lastIndexOf); - var path = fullName.Substring(0, fullName.Length - excelFile.Name.Length); - - // 过滤~开头文件 - - if (excelName.StartsWith("~", StringComparison.Ordinal)) - { - continue; - } - - // 如果文件名以#开头,那么这个文件夹下的所有文件都不导出 - if (excelName.StartsWith("#", StringComparison.Ordinal)) - { - continue; - } - - // 如果文件夹名包含#,那么这个文件夹下的所有文件都不导出 - if (path.Contains("#", StringComparison.Ordinal)) - { - continue; - } - - if (!_regexName.IsMatch(excelName)) - { - Log.Info($"{excelName} 配置文件名非法"); - continue; - } - - tables.Add(excelFile); - } - - - var generateTasks = new List(); - - foreach (var table in tables) - { - var task = Task.Run(() => - { - var worksheets = LoadExcel(table.FullName); - foreach (var worksheet in worksheets) - { - var tableName = worksheet.Name; - if (tableName.Contains("#", StringComparison.Ordinal)) - { - continue; - } - - ReportProgress($"正在解析配置表: {table.Name} Sheet:{tableName}"); - var excelTable = new ExcelTable(worksheet); - try - { - var serverColInfoList = new List(); - var clientColInfoList = new List(); - - for (var col = 3; col <= worksheet.Columns.EndColumn; col++) - { - // 列名字第一个字符是#不参与导出 - - var colName = worksheet.GetCellValue(5, col); - if (colName.StartsWith("#", StringComparison.Ordinal)) - { - continue; - } - - // 数值列不参与导出 - - var numericalCol = worksheet.GetCellValue(3, col); - if (numericalCol != "" && numericalCol != "0") - { - continue; - } - - var serverType = worksheet.GetCellValue(1, col); - var clientType = worksheet.GetCellValue(2, col); - var isExportServer = !IsNullOrEmpty(serverType) && serverType != "0"; - var isExportClient = !IsNullOrEmpty(clientType) && clientType != "0"; - - if (!isExportServer && !isExportClient) - { - continue; - } - - if (isExportServer && isExportClient & serverType != clientType) - { - Log.Info( - $"配置表 {tableName} {col} 列 [{colName}] 客户端类型 {clientType} 和 服务端类型 {serverType} 不一致"); - continue; - } - - if (!ColTypeSet.Contains(serverType) || !ColTypeSet.Contains(clientType)) - { - Log.Info( - $"配置表 {tableName} {col} 列 [{colName}] 客户端类型 {clientType}, 服务端类型 {serverType} 不合法"); - continue; - } - - if (!_regexName.IsMatch(colName)) - { - Log.Info($"配置表 {tableName} {col} 列 [{colName}] 列名非法"); - continue; - } - - serverColInfoList.Add(col); - - if (isExportClient) - { - clientColInfoList.Add(col); - } - } - - if (clientColInfoList.Count > 0) - { - excelTable.ClientColInfos.Add(tableName, clientColInfoList); - } - - if (serverColInfoList.Count > 0) - { - excelTable.ServerColInfos.Add(tableName, serverColInfoList); - } - } - catch (Exception e) - { - Log.Error($"Config : {tableName}, Name : {tableName}, Error : {e}"); - } - - _excelTables.TryAdd(tableName, excelTable); - } - }); - - generateTasks.Add(task); - } - - Task.WaitAll(generateTasks.ToArray()); - } - - /// - /// 生成配置文件 - /// - private void Parsing() - { - var generateTasks = new List(); - - foreach ((var tableName, ExcelTable excelTable) in _excelTables) - { - var task = Task.Run(() => - { - // 生成cs文件 - var writeToClassTask = new List(); - - var table = excelTable; - if (App.Config.GenServer) - { - writeToClassTask.Add(Task.Run(() => - { - ReportProgress($"正在生成服务端CS文件: {tableName}"); - WriteToClass(table, true); - })); - } - - if (App.Config.GenClient) - { - writeToClassTask.Add(Task.Run(() => - { - ReportProgress($"正在生成客户端CS文件: {tableName}"); - WriteToClass(table, false); - })); - } - - Task.WaitAll(writeToClassTask.ToArray()); - }); - - generateTasks.Add(task); - } - - Task.WaitAll(generateTasks.ToArray()); - Console.WriteLine("build cs success==="); - } - - #region json - - private Dictionary>> _clientTableJsonDictionary = - new Dictionary>>(); - - private Dictionary>> _serverTableJsonDictionary = - new Dictionary>>(); - - /// - /// 把数据生成json - /// - private void ExportToJson() - { - _clientTableJsonDictionary.Clear(); - _serverTableJsonDictionary.Clear(); - foreach (var (tableName, excelTable) in _excelTables) - { - // 示例:客户端JSON导出 - if (App.Config.GenClient && excelTable.ClientColInfos.Count > 0) - { - ReportProgress($"正在生成客户端JSON文件: {tableName}"); - ExportTableToJson(excelTable, excelTable.ClientColInfos, _clientTableJsonDictionary); - } - - // 示例:服务端JSON导出 - if (App.Config.GenServer && excelTable.ServerColInfos.Count > 0) - { - ReportProgress($"正在生成服务端JSON文件: {tableName}"); - ExportTableToJson(excelTable, excelTable.ServerColInfos, _serverTableJsonDictionary); - } - } - - if (_clientTableJsonDictionary.Count > 0) - { - ReportProgress("正在写入客户端JSON文件: configs.json"); - var json = JsonConvert.SerializeObject(_clientTableJsonDictionary, Formatting.Indented); - File.WriteAllText(Path.Combine(App.Config.ClientJsonPath, $"configs.json"), json); - } - - if (_serverTableJsonDictionary.Count > 0) - { - ReportProgress("正在写入服务端JSON文件: configs.json"); - var json = JsonConvert.SerializeObject(_serverTableJsonDictionary, Formatting.Indented); - File.WriteAllText(Path.Combine(App.Config.ServerJsonPath, $"configs.json"), json); - } - } - - private void ExportTableToJson(ExcelTable table, TableDictionary colInfos, - Dictionary>> dictionary) - { - var result = new List>(); - - var worksheet = table.Sheet; - foreach (var (fileName, columns) in colInfos) - { - // 从第7行开始读取数据(前6行为表头) - for (int row = 7; row <= worksheet.Rows.EndRow; row++) - { - // 检查是否为空行 - bool isEmptyRow = true; - foreach (var col in columns) - { - var cellValue = worksheet.GetCellValue(row, col); - if (!IsNullOrEmpty(cellValue)) - { - isEmptyRow = false; - break; - } - } - - // 如果整行都为空,则停止处理 - if (isEmptyRow) - { - break; - } - - var rowData = new Dictionary(); - - foreach (var col in columns) - { - var columnName = worksheet.GetCellValue(5, col); - var cellValue = worksheet.GetCellValue(row, col); - // 可在此处做类型转换 - var columnType = GetColumnType(worksheet, col); // 需要实现获取列类型的方法 - rowData[columnName] = ConvertCellValue(cellValue, columnType); - } - - result.Add(rowData); - } - } - - dictionary[table.Name] = result; - } - - private string GetColumnType(ExcelWorksheet worksheet, int column) - { - var serverType = worksheet.GetCellValue(1, column); - var clientType = worksheet.GetCellValue(2, column); - - // 根据实际情况确定使用哪个类型,这里简化处理 - return !string.IsNullOrEmpty(serverType) && serverType != "0" ? serverType : clientType; - } - - private object ConvertCellValue(string cellValue, string targetType) - { - if (string.IsNullOrEmpty(cellValue)) - { - // 返回默认值 - if (targetType.EndsWith("[]")) - { - var elementType = targetType.Substring(0, targetType.Length - 2); - return Array.CreateInstance(Type.GetType(elementType) ?? typeof(object), 0); - } - - return GetDefaultValue(targetType); - } - - // 处理数组类型 - if (targetType.EndsWith("[]")) - { - var elementType = targetType.Substring(0, targetType.Length - 2); - var values = cellValue.Split(','); - - switch (elementType) - { - case "short": - return values.Select(v => - { - short result; - return short.TryParse(v, out result) ? result : (short)0; - }).ToArray(); - - case "ushort": - return values.Select(v => - { - ushort result; - return ushort.TryParse(v, out result) ? result : (ushort)0; - }).ToArray(); - - case "int": - return values.Select(v => - { - int result; - return int.TryParse(v, out result) ? result : 0; - }).ToArray(); - - case "uint": - return values.Select(v => - { - uint result; - return uint.TryParse(v, out result) ? result : 0u; - }).ToArray(); - - case "long": - return values.Select(v => - { - long result; - return long.TryParse(v, out result) ? result : 0L; - }).ToArray(); - - case "ulong": - return values.Select(v => - { - ulong result; - return ulong.TryParse(v, out result) ? result : 0UL; - }).ToArray(); - - case "bool": - return values.Select(v => - { - bool result; - return bool.TryParse(v, out result) ? result : false; - }).ToArray(); - - case "string": - return values.Select(v => v.Trim()).ToArray(); - - default: - return values; - } - } - - // 处理单个值 - switch (targetType) - { - case "short": - short shortResult; - return short.TryParse(cellValue, out shortResult) ? shortResult : (short)0; - - case "ushort": - ushort ushortResult; - return ushort.TryParse(cellValue, out ushortResult) ? ushortResult : (ushort)0; - - case "int": - int intResult; - return int.TryParse(cellValue, out intResult) ? intResult : 0; - - case "uint": - uint uintResult; - return uint.TryParse(cellValue, out uintResult) ? uintResult : 0u; - - case "long": - long longResult; - return long.TryParse(cellValue, out longResult) ? longResult : 0L; - - case "ulong": - ulong ulongResult; - return ulong.TryParse(cellValue, out ulongResult) ? ulongResult : 0UL; - - case "bool": - bool boolResult; - if (bool.TryParse(cellValue, out boolResult)) - { - return boolResult; - } - else - { - int numericBool; - return int.TryParse(cellValue, out numericBool) ? numericBool != 0 : false; - } - - case "string": - return cellValue; - - default: - return cellValue; - } - } - - private object GetDefaultValue(string type) - { - switch (type) - { - case "short": return (short)0; - case "ushort": return (ushort)0; - case "int": return 0; - case "uint": return 0u; - case "long": return 0L; - case "ulong": return 0UL; - case "bool": return false; - case "string": return ""; - case "short[]": return new short[0]; - case "ushort[]": return new ushort[0]; - case "int[]": return new int[0]; - case "uint[]": return new uint[0]; - case "long[]": return new long[0]; - case "ulong[]": return new ulong[0]; - case "bool[]": return new bool[0]; - case "string[]": return new string[0]; - default: return null; - } - } - - #endregion - - /// - /// 从 Excel 文件加载工作表并返回 ExcelWorksheet 对象。 - /// - /// 工作表的名称或文件路径。 - /// 表示 Excel 工作表的 ExcelWorksheet 对象。 - public List LoadExcel(string name) - { - var workbookWorksheets = ExcelHelper.LoadExcel(name).Workbook.Worksheets; - return workbookWorksheets.ToList(); - } - - /// - /// 写入到cs - /// - /// - /// - private void WriteToClass(ExcelTable table, bool isServer) - { - var colInfos = isServer ? table.ServerColInfos : table.ClientColInfos; - var exportPath = isServer ? App.Config.ServerPath : App.Config.ClientPath; - - if (colInfos.Count <= 0) - { - return; - } - - var excelWorksheet = table.Sheet; - - var index = 0; - var fileBuilder = new StringBuilder(); - var colNameSet = new HashSet(); - - if (colInfos.Count == 0) - { - return; - } - - var csName = Path.GetFileNameWithoutExtension(colInfos.First().Key)?.Split('_')[0]; - - foreach (var (tableName, cols) in colInfos) - { - if (cols == null || cols.Count == 0) - { - continue; - } - - - foreach (var colIndex in cols) - { - var colName = excelWorksheet.GetCellValue(5, colIndex); - - if (!colNameSet.Add(colName)) - { - continue; - } - - string colType; - - if (isServer) - { - colType = excelWorksheet.GetCellValue(1, colIndex); - - if (IsNullOrEmpty(colType) || colType == "0") - { - colType = excelWorksheet.GetCellValue(2, colIndex); - } - } - else - { - colType = excelWorksheet.GetCellValue(2, colIndex); - } - - var remarks = excelWorksheet.GetCellValue(4, colIndex); - - // 解决不同平台换行符不一致的问题 - - switch (Environment.OSVersion.Platform) - { - case PlatformID.Win32NT: - case PlatformID.Win32S: - case PlatformID.Win32Windows: - case PlatformID.WinCE: - { - fileBuilder.Append($"\r\n\t\t[ProtoMember({++index})]\r\n"); - break; - } - default: - { - fileBuilder.Append($"\n\t\t[ProtoMember({++index})]\n"); - break; - } - } - - fileBuilder.Append( - IsArray(colType, out var t) - ? $"\t\tpublic {colType} {colName} {{ get; set; }} = Array.Empty<{t}>(); // {remarks}" - : $"\t\tpublic {colType} {colName} {{ get; set; }} // {remarks}"); - } - } - - var template = GetTemplate(isServer); - - if (fileBuilder.Length > 0) - { - if (!Directory.Exists(exportPath)) - { - FileHelper.CreateDirectory(exportPath); - } - - var content = template.Replace("(ConfigName)", csName) - .Replace("(Fields)", fileBuilder.ToString()); - File.WriteAllText(Path.Combine(exportPath, $"{csName}.cs"), content); - } - } - - private bool IsArray(string type, out string t) - { - t = null; - var index = type.IndexOf("[]", StringComparison.Ordinal); - - if (index >= 0) - { - t = type.Remove(index, 2); - } - - return index >= 0; - } - - private string GetTemplate(bool isServer) - { - var fileName = isServer ? "TemplateServer.txt" : "TemplateClient.txt"; - return File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName)); - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelHelper.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelHelper.cs deleted file mode 100644 index 3ef64d4..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelHelper.cs +++ /dev/null @@ -1,47 +0,0 @@ -using OfficeOpenXml; - -namespace NBConfigBuilder; - -/// -/// 提供操作 Excel 文件的辅助方法。 -/// -public static class ExcelHelper -{ - /// - /// 加载 Excel 文件并返回 ExcelPackage 实例。 - /// - /// Excel 文件的路径。 - /// ExcelPackage 实例。 - public static ExcelPackage LoadExcel(string name) - { - return new ExcelPackage(name); - } - - /// - /// 获取指定工作表中指定行列位置的单元格值。 - /// - /// Excel 工作表。 - /// 行索引。 - /// 列索引。 - /// 单元格值。 - public static string GetCellValue(this ExcelWorksheet sheet, int row, int column) - { - ExcelRange cell = sheet.Cells[row, column]; - - try - { - if (cell.Value == null) - { - return ""; - } - - string s = cell.GetValue(); - - return s.Trim(); - } - catch (Exception e) - { - throw new Exception($"Rows {row} Columns {column} Content {cell.Text} {e}"); - } - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTable.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTable.cs deleted file mode 100644 index dd5a525..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTable.cs +++ /dev/null @@ -1,39 +0,0 @@ -using OfficeOpenXml; - -namespace NBConfigBuilder; - -/// -/// Excel表格类,用于存储表格的名称和列信息。 -/// -public sealed class ExcelTable -{ - /// - /// 表格的名称。 - /// - public readonly string Name; - - /// - /// 客户端列信息,使用排序字典存储列名和列索引列表。 - /// - public readonly SortedDictionary> ClientColInfos = new(); - - /// - /// 服务器端列信息,使用排序字典存储列名和列索引列表。 - /// - public readonly SortedDictionary> ServerColInfos = new(); - - /// - /// 表数据 - /// - public readonly ExcelWorksheet Sheet; - - /// - /// 构造函数,初始化Excel表格对象并设置表格名称。 - /// - /// 表格。 - public ExcelTable(ExcelWorksheet sheet) - { - Name = sheet.Name; - Sheet = sheet; - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelWorksheets.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelWorksheets.cs deleted file mode 100644 index 1c23c40..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelWorksheets.cs +++ /dev/null @@ -1,22 +0,0 @@ -// using OfficeOpenXml; -// -// namespace NBConfigBuilder; -// -// public sealed class ExcelWorksheets(ExcelExporter excelExporter) -// { -// public bool TryGetValue(string worksheetName, out ExcelWorksheet excelWorksheet) -// { -// if (excelExporter.Worksheets.TryGetValue(worksheetName, out excelWorksheet)) -// { -// return true; -// } -// -// var computeHash64 = HashCodeHelper.ComputeHash64(worksheetName); -// if (!excelExporter.VersionInfo.WorksheetNames.Contains(computeHash64)) -// { -// Log.Info($"{worksheetName} is not exist!"); -// } -// -// return false; -// } -// } \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportType.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportType.cs deleted file mode 100644 index 348a9e6..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportType.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace NBConfigBuilder; - -/// -/// 导出类型枚举,用于标识不同类型的导出操作。 -/// -public enum ExportType -{ - /// - /// 无导出类型。 - /// - None = 0, - /// - /// 所有数据的增量导出Excel类型。 - /// - AllExcelIncrement = 1, - /// - /// 所有数据的全量导出Excel类型。 - /// - AllExcel = 2, - /// - /// 导出类型枚举的最大值,一定要放在最后。 - /// - Max, -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/VersionInfo.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/VersionInfo.cs deleted file mode 100644 index c04cd9f..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/VersionInfo.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace NBConfigBuilder; - -public class VersionInfo -{ - public SortedSet WorksheetNames = []; - public SortedDictionary Tables = new(); -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Form1.Designer.cs b/Tools/ConfigBuilder/NBConfigBuilder/Form1.Designer.cs deleted file mode 100644 index 7fe6094..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Form1.Designer.cs +++ /dev/null @@ -1,266 +0,0 @@ -namespace NBConfigBuilder -{ - partial class Form1 - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - textBoxExcelPath = new TextBox(); - buttonSelectExcelPath = new Button(); - label1 = new Label(); - textBoxClientGenPath = new TextBox(); - buttonSelectClientPath = new Button(); - checkBoxGenClient = new CheckBox(); - label2 = new Label(); - textBoxServerGenPath = new TextBox(); - label3 = new Label(); - checkBoxGenServer = new CheckBox(); - buttonSelectServerPath = new Button(); - buttonRun = new Button(); - textBoxClientGenJsonPath = new TextBox(); - label4 = new Label(); - buttonSelectClientJsonPath = new Button(); - textBoxServerGenJsonPath = new TextBox(); - label5 = new Label(); - buttonSelectServerJsonPath = new Button(); - SuspendLayout(); - // - // textBoxExcelPath - // - textBoxExcelPath.Location = new Point(81, 13); - textBoxExcelPath.Name = "textBoxExcelPath"; - textBoxExcelPath.Size = new Size(325, 23); - textBoxExcelPath.TabIndex = 0; - // - // buttonSelectExcelPath - // - buttonSelectExcelPath.Location = new Point(412, 13); - buttonSelectExcelPath.Name = "buttonSelectExcelPath"; - buttonSelectExcelPath.Size = new Size(84, 23); - buttonSelectExcelPath.TabIndex = 1; - buttonSelectExcelPath.Text = "选择"; - buttonSelectExcelPath.UseVisualStyleBackColor = true; - buttonSelectExcelPath.Click += buttonSelectExcelPath_Click; - // - // label1 - // - label1.AutoSize = true; - label1.Location = new Point(7, 17); - label1.Name = "label1"; - label1.Size = new Size(68, 17); - label1.TabIndex = 2; - label1.Text = "配置表路径"; - // - // textBoxClientGenPath - // - textBoxClientGenPath.Location = new Point(81, 42); - textBoxClientGenPath.Name = "textBoxClientGenPath"; - textBoxClientGenPath.Size = new Size(325, 23); - textBoxClientGenPath.TabIndex = 3; - // - // buttonSelectClientPath - // - buttonSelectClientPath.Location = new Point(412, 42); - buttonSelectClientPath.Name = "buttonSelectClientPath"; - buttonSelectClientPath.Size = new Size(84, 23); - buttonSelectClientPath.TabIndex = 4; - buttonSelectClientPath.Text = "选择"; - buttonSelectClientPath.UseVisualStyleBackColor = true; - buttonSelectClientPath.Click += buttonSelectClientPath_Click; - // - // checkBoxGenClient - // - checkBoxGenClient.AutoSize = true; - checkBoxGenClient.Checked = true; - checkBoxGenClient.CheckState = CheckState.Checked; - checkBoxGenClient.Location = new Point(504, 13); - checkBoxGenClient.Name = "checkBoxGenClient"; - checkBoxGenClient.Size = new Size(87, 21); - checkBoxGenClient.TabIndex = 5; - checkBoxGenClient.Text = "生成客户端"; - checkBoxGenClient.UseVisualStyleBackColor = true; - // - // label2 - // - label2.AutoSize = true; - label2.Location = new Point(7, 47); - label2.Name = "label2"; - label2.Size = new Size(68, 17); - label2.TabIndex = 6; - label2.Text = "客户端代码"; - // - // textBoxServerGenPath - // - textBoxServerGenPath.Location = new Point(81, 100); - textBoxServerGenPath.Name = "textBoxServerGenPath"; - textBoxServerGenPath.Size = new Size(325, 23); - textBoxServerGenPath.TabIndex = 7; - // - // label3 - // - label3.AutoSize = true; - label3.Location = new Point(7, 103); - label3.Name = "label3"; - label3.Size = new Size(68, 17); - label3.TabIndex = 8; - label3.Text = "服务端代码"; - // - // checkBoxGenServer - // - checkBoxGenServer.AutoSize = true; - checkBoxGenServer.Checked = true; - checkBoxGenServer.CheckState = CheckState.Checked; - checkBoxGenServer.Location = new Point(504, 42); - checkBoxGenServer.Name = "checkBoxGenServer"; - checkBoxGenServer.Size = new Size(87, 21); - checkBoxGenServer.TabIndex = 9; - checkBoxGenServer.Text = "生成服务端"; - checkBoxGenServer.UseVisualStyleBackColor = true; - checkBoxGenServer.CheckedChanged += checkBoxGenServer_CheckedChanged; - // - // buttonSelectServerPath - // - buttonSelectServerPath.Location = new Point(412, 100); - buttonSelectServerPath.Name = "buttonSelectServerPath"; - buttonSelectServerPath.Size = new Size(84, 23); - buttonSelectServerPath.TabIndex = 10; - buttonSelectServerPath.Text = "选择"; - buttonSelectServerPath.UseVisualStyleBackColor = true; - buttonSelectServerPath.Click += buttonSelectServerPath_Click; - // - // buttonRun - // - buttonRun.Location = new Point(504, 77); - buttonRun.Name = "buttonRun"; - buttonRun.Size = new Size(87, 77); - buttonRun.TabIndex = 12; - buttonRun.Text = "执行"; - buttonRun.UseVisualStyleBackColor = true; - buttonRun.Click += buttonRun_Click; - // - // textBoxClientGenJsonPath - // - textBoxClientGenJsonPath.Location = new Point(81, 71); - textBoxClientGenJsonPath.Name = "textBoxClientGenJsonPath"; - textBoxClientGenJsonPath.Size = new Size(325, 23); - textBoxClientGenJsonPath.TabIndex = 13; - // - // label4 - // - label4.AutoSize = true; - label4.Location = new Point(7, 77); - label4.Name = "label4"; - label4.Size = new Size(68, 17); - label4.TabIndex = 14; - label4.Text = "客户端配置"; - // - // buttonSelectClientJsonPath - // - buttonSelectClientJsonPath.Location = new Point(412, 71); - buttonSelectClientJsonPath.Name = "buttonSelectClientJsonPath"; - buttonSelectClientJsonPath.Size = new Size(84, 23); - buttonSelectClientJsonPath.TabIndex = 15; - buttonSelectClientJsonPath.Text = "选择"; - buttonSelectClientJsonPath.UseVisualStyleBackColor = true; - buttonSelectClientJsonPath.Click += buttonSelectClientJsonPath_Click; - // - // textBoxServerGenJsonPath - // - textBoxServerGenJsonPath.Location = new Point(81, 131); - textBoxServerGenJsonPath.Name = "textBoxServerGenJsonPath"; - textBoxServerGenJsonPath.Size = new Size(325, 23); - textBoxServerGenJsonPath.TabIndex = 16; - // - // label5 - // - label5.AutoSize = true; - label5.Location = new Point(7, 132); - label5.Name = "label5"; - label5.Size = new Size(68, 17); - label5.TabIndex = 17; - label5.Text = "服务端配置"; - // - // buttonSelectServerJsonPath - // - buttonSelectServerJsonPath.Location = new Point(412, 129); - buttonSelectServerJsonPath.Name = "buttonSelectServerJsonPath"; - buttonSelectServerJsonPath.Size = new Size(84, 23); - buttonSelectServerJsonPath.TabIndex = 18; - buttonSelectServerJsonPath.Text = "选择"; - buttonSelectServerJsonPath.UseVisualStyleBackColor = true; - buttonSelectServerJsonPath.Click += buttonSelectServerJsonPath_Click; - // - // Form1 - // - AutoScaleDimensions = new SizeF(7F, 17F); - AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(599, 165); - Controls.Add(buttonSelectServerJsonPath); - Controls.Add(label5); - Controls.Add(textBoxServerGenJsonPath); - Controls.Add(buttonSelectClientJsonPath); - Controls.Add(label4); - Controls.Add(textBoxClientGenJsonPath); - Controls.Add(buttonRun); - Controls.Add(buttonSelectServerPath); - Controls.Add(checkBoxGenServer); - Controls.Add(label3); - Controls.Add(textBoxServerGenPath); - Controls.Add(label2); - Controls.Add(checkBoxGenClient); - Controls.Add(buttonSelectClientPath); - Controls.Add(textBoxClientGenPath); - Controls.Add(label1); - Controls.Add(buttonSelectExcelPath); - Controls.Add(textBoxExcelPath); - Name = "Form1"; - Text = "配置生成导出"; - ResumeLayout(false); - PerformLayout(); - } - - #endregion - - private TextBox textBoxExcelPath; - private Button buttonSelectExcelPath; - private Label label1; - private TextBox textBoxClientGenPath; - private Button buttonSelectClientPath; - private CheckBox checkBoxGenClient; - private Label label2; - private TextBox textBoxServerGenPath; - private Label label3; - private CheckBox checkBoxGenServer; - private Button buttonSelectServerPath; - private Button buttonRun; - private TextBox textBoxClientGenJsonPath; - private Label label4; - private Button buttonSelectClientJsonPath; - private TextBox textBoxServerGenJsonPath; - private Label label5; - private Button buttonSelectServerJsonPath; - } -} diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Form1.cs b/Tools/ConfigBuilder/NBConfigBuilder/Form1.cs deleted file mode 100644 index 4fd5750..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Form1.cs +++ /dev/null @@ -1,198 +0,0 @@ -using System.Text.Json; -using System.Threading.Tasks; - -namespace NBConfigBuilder -{ - public partial class Form1 : Form - { - // 配置文件路径 - private readonly string configPath = - Path.Combine(Path.GetDirectoryName(Application.ExecutablePath) ?? string.Empty, "config.json"); - - // 保存原始标题 - private string _originalTitle; - - public Form1() - { - InitializeComponent(); - // 设置窗口大小不可变 - this.FormBorderStyle = FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - - // 保存原始标题 - _originalTitle = this.Text; - - // 加载保存的配置 - LoadConfig(); - } - - private async void buttonRun_Click(object sender, EventArgs e) - { - // 禁用按钮防止重复点击 - buttonRun.Enabled = false; - buttonRun.Text = "执行中..."; - - try - { - // 保存当前配置 - SaveConfig(); - - // 创建导出器并设置进度回调 - var exporter = new ExcelExporter(ExportType.AllExcel); - exporter.SetProgressCallback(UpdateProgress); - - // 运行导出器 - await Task.Run(() => exporter.Run()); - - // 显示成功消息 - MessageBox.Show("配置导出完成!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - catch (Exception ex) - { - // 显示错误消息 - MessageBox.Show($"导出过程中发生错误:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - finally - { - // 恢复按钮状态和标题 - buttonRun.Enabled = true; - buttonRun.Text = "执行"; - this.Text = _originalTitle; - } - } - - /// - /// 更新进度显示 - /// - /// 进度消息 - private void UpdateProgress(string message) - { - // 确保在UI线程上更新界面 - if (InvokeRequired) - { - Invoke(new Action(UpdateProgress), message); - return; - } - - // 更新标题栏显示进度 - this.Text = $"{_originalTitle} - {message}"; - } - - private void buttonSelectExcelPath_Click(object sender, EventArgs e) - { - using (FolderBrowserDialog folderDlg = new FolderBrowserDialog()) - { - folderDlg.Description = "请选择配置表路径"; - if (folderDlg.ShowDialog() == DialogResult.OK) - { - textBoxExcelPath.Text = folderDlg.SelectedPath; - } - } - } - - private void buttonSelectClientJsonPath_Click(object sender, EventArgs e) - { - using (FolderBrowserDialog folderDlg = new FolderBrowserDialog()) - { - folderDlg.Description = @"选择客户端json保存目录"; - if (folderDlg.ShowDialog() == DialogResult.OK) - { - textBoxClientGenJsonPath.Text = folderDlg.SelectedPath; - } - } - } - - private void buttonSelectServerJsonPath_Click(object sender, EventArgs e) - { - using (FolderBrowserDialog folderDlg = new FolderBrowserDialog()) - { - folderDlg.Description = @"选择服务端json保存目录"; - if (folderDlg.ShowDialog() == DialogResult.OK) - { - textBoxServerGenJsonPath.Text = folderDlg.SelectedPath; - } - } - } - - private void buttonSelectClientPath_Click(object sender, EventArgs e) - { - using (FolderBrowserDialog folderDlg = new FolderBrowserDialog()) - { - folderDlg.Description = @"选择客户端代码保存目录"; - if (folderDlg.ShowDialog() == DialogResult.OK) - { - textBoxClientGenPath.Text = folderDlg.SelectedPath; - } - } - } - - private void buttonSelectServerPath_Click(object sender, EventArgs e) - { - using (FolderBrowserDialog folderDlg = new FolderBrowserDialog()) - { - folderDlg.Description = @"选择服务端代码保存目录"; - if (folderDlg.ShowDialog() == DialogResult.OK) - { - textBoxServerGenPath.Text = folderDlg.SelectedPath; - } - } - } - - // 添加保存和加载配置的方法 - private void SaveConfig() - { - var config = new AppConfig - { - ExcelPath = textBoxExcelPath.Text, - ClientPath = textBoxClientGenPath.Text, - ClientJsonPath = textBoxClientGenJsonPath.Text, - ServerPath = textBoxServerGenPath.Text, - ServerJsonPath = textBoxServerGenJsonPath.Text, - GenClient = checkBoxGenClient.Checked, - GenServer = checkBoxGenServer.Checked - }; - App.Config = config; - try - { - string json = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true }); - File.WriteAllText(configPath, json); - } - catch (Exception ex) - { - MessageBox.Show($"保存配置失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void LoadConfig() - { - if (!File.Exists(configPath)) return; - - try - { - string json = File.ReadAllText(configPath); - var config = JsonSerializer.Deserialize(json); - - if (config != null) - { - App.Config = config; - textBoxExcelPath.Text = config.ExcelPath ?? ""; - textBoxClientGenPath.Text = config.ClientPath ?? ""; - textBoxServerGenPath.Text = config.ServerPath ?? ""; - checkBoxGenClient.Checked = config.GenClient; - checkBoxGenServer.Checked = config.GenServer; - textBoxClientGenJsonPath.Text = config.ClientJsonPath ?? ""; - textBoxServerGenJsonPath.Text = config.ServerJsonPath ?? ""; - } - } - catch (Exception ex) - { - MessageBox.Show($"加载配置失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void checkBoxGenServer_CheckedChanged(object sender, EventArgs e) - { - - } - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Form1.resx b/Tools/ConfigBuilder/NBConfigBuilder/Form1.resx deleted file mode 100644 index 8b2ff64..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Form1.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Log.cs b/Tools/ConfigBuilder/NBConfigBuilder/Log.cs deleted file mode 100644 index 6da4ad0..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Log.cs +++ /dev/null @@ -1,97 +0,0 @@ -using NLog; -using System; -using System.Diagnostics; - -namespace NBConfigBuilder -{ - public static class Log - { - private static readonly Logger logger = LogManager.GetCurrentClassLogger(); - - static Log() - { - } - - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - public static void Info(string msg) - { - logger.Info(msg); - } - - /// - /// 记录错误级别的日志消息,并附带调用栈信息。 - /// - /// 日志消息。 - public static void Error(string msg) - { - var st = new StackTrace(1, true); - logger.Error($"{msg}\n{st}"); - } - - /// - /// 记录异常的错误级别的日志消息,并附带调用栈信息。 - /// - /// 异常对象。 - public static void Error(Exception e) - { - if (e.Data.Contains("StackTrace")) - { - logger.Error($"{e.Data["StackTrace"]}\n{e}"); - return; - } - - var str = e.ToString(); - logger.Error(str); - } - - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Info(string message, params object[] args) - { - logger.Info(message, args); - } - - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - public static void Debug(string msg) - { - logger.Debug(msg); - } - - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - public static void Warn(string msg) - { - logger.Warn(msg); - } - - /// - /// 记录严重错误级别的日志消息。 - /// - /// 日志消息。 - public static void Fatal(string msg) - { - logger.Fatal(msg); - } - - /// - /// 记录异常的错误级别的日志消息。 - /// - /// 异常对象。 - /// 附加消息。 - public static void Error(Exception e, string message) - { - logger.Error(e, message); - } - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/NBConfigBuilder.csproj b/Tools/ConfigBuilder/NBConfigBuilder/NBConfigBuilder.csproj deleted file mode 100644 index f6b8602..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/NBConfigBuilder.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - WinExe - net8.0-windows - disable - true - enable - true - - - - - - - - - - - - - Always - - - Always - - - Always - - - Always - - - \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/NBConfigBuilder.csproj.user b/Tools/ConfigBuilder/NBConfigBuilder/NBConfigBuilder.csproj.user deleted file mode 100644 index 7814ea2..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/NBConfigBuilder.csproj.user +++ /dev/null @@ -1,8 +0,0 @@ - - - - - Form - - - diff --git a/Tools/ConfigBuilder/NBConfigBuilder/NLog.config b/Tools/ConfigBuilder/NBConfigBuilder/NLog.config deleted file mode 100644 index 4bd1557..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/NLog.config +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Program.cs b/Tools/ConfigBuilder/NBConfigBuilder/Program.cs deleted file mode 100644 index a3718e5..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using NLog; - -namespace NBConfigBuilder -{ - internal static class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - // 配置NLog - var logger = LogManager.GetCurrentClassLogger(); - logger.Info("Application started"); - - // To customize application configuration such as set high DPI settings or default font, - // see https://aka.ms/applicationconfiguration. - ApplicationConfiguration.Initialize(); - Application.Run(new Form1()); - - logger.Info("Application closing"); - } - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/TemplateBack.txt b/Tools/ConfigBuilder/NBConfigBuilder/TemplateBack.txt deleted file mode 100644 index ebbd5d3..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/TemplateBack.txt +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using ProtoBuf; -using Fantasy; -using System.Linq; -using System.Reflection; -using System.Collections.Generic; -using System.Collections.Concurrent; -#if FANTASY_NET -using Fantasy.ConfigTable; -using Fantasy.Serialize; -#else -using NBC; -using NBC.Serialize; -#endif -// ReSharper disable CollectionNeverUpdated.Global -// ReSharper disable UnusedAutoPropertyAccessor.Global -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS0169 -#pragma warning disable CS8618 -#pragma warning disable CS8625 -#pragma warning disable CS8603 - -namespace (namespace) -{ - [ProtoContract] - public sealed partial class (ConfigName)Data : ASerialize, IConfigTable, IProto - { - [ProtoMember(1)] - public List<(ConfigName)> List { get; set; } = new List<(ConfigName)>(); -#if FANTASY_NET - [ProtoIgnore] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); -#else - [ProtoIgnore] - private readonly Dictionary _configs = new Dictionary(); -#endif - private static (ConfigName)Data _instance = null; - - public static (ConfigName)Data Instance - { - get { return _instance ??= ConfigTableHelper.Load<(ConfigName)Data>(); } - private set => _instance = value; - } - - public (ConfigName) Get(uint id, bool check = true) - { - if (_configs.ContainsKey(id)) - { - return _configs[id]; - } - - if (check) - { - throw new Exception($"(ConfigName) not find {id} Id"); - } - - return null; - } - public bool TryGet(uint id, out (ConfigName) config) - { - config = null; - - if (!_configs.ContainsKey(id)) - { - return false; - } - - config = _configs[id]; - return true; - } - public override void AfterDeserialization() - { - foreach (var config in List) - { -#if FANTASY_NET - _configs.TryAdd(config.Id, config); -#else - _configs.Add(config.Id, config); -#endif - config.AfterDeserialization(); - } - - EndInit(); - } - - public override void Dispose() - { - Instance = null; - } - } - - [ProtoContract] - public sealed partial class (ConfigName) : ASerialize, IProto - {(Fields) - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/TemplateClient.txt b/Tools/ConfigBuilder/NBConfigBuilder/TemplateClient.txt deleted file mode 100644 index 47a04cb..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/TemplateClient.txt +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using ProtoBuf; -using Fantasy; -using System.Linq; -using System.Reflection; -using System.Collections.Generic; -using System.Collections.Concurrent; -using NBC; -using NBC.Serialize; - -namespace NBF -{ - [ProtoContract] - public sealed partial class (ConfigName) : ASerialize, IProto, IConfigTable - { - (Fields) - [ProtoIgnore] - public uint Key => Id; - - #region Static - - private static ConfigContext<(ConfigName)> Context => ConfigTableHelper.Table<(ConfigName)>(); - - public static (ConfigName) Get(uint key) - { - return Context.Get(key); - } - - public static (ConfigName) Get(Predicate<(ConfigName)> match) - { - return Context.Get(match); - } - - public static (ConfigName) Fist() - { - return Context.Fist(); - } - - public static (ConfigName) Last() - { - return Context.Last(); - } - - public static (ConfigName) Fist(Predicate<(ConfigName)> match) - { - return Context.Fist(match); - } - - public static (ConfigName) Last(Predicate<(ConfigName)> match) - { - return Context.Last(match); - } - - public static int Count() - { - return Context.Count(); - } - - public static int Count(Func<(ConfigName), bool> predicate) - { - return Context.Count(predicate); - } - - public static List<(ConfigName)> GetList() - { - return Context.GetList(); - } - - public static List<(ConfigName)> GetList(Predicate<(ConfigName)> match) - { - return Context.GetList(match); - } - public static void ParseJson(Newtonsoft.Json.Linq.JArray arr) - { - ConfigTableHelper.ParseLine<(ConfigName)>(arr); - } - #endregion - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/TemplateServer.txt b/Tools/ConfigBuilder/NBConfigBuilder/TemplateServer.txt deleted file mode 100644 index 3a2823b..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/TemplateServer.txt +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using ProtoBuf; -using Fantasy; -using System.Linq; -using System.Reflection; -using System.Collections.Generic; -using System.Collections.Concurrent; -using Fantasy.Serialize; -using Fantasy.ConfigTable; - -namespace NBF -{ - [ProtoContract] - public sealed partial class (ConfigName) : ASerialize, IProto, IConfigTable - { - (Fields) - [ProtoIgnore] - public uint Key => Id; - - #region Static - - private static ConfigContext<(ConfigName)> Context => ConfigTableHelper.Table<(ConfigName)>(); - - public static (ConfigName) Get(uint key) - { - return Context.Get(key); - } - - public static (ConfigName) Get(Predicate<(ConfigName)> match) - { - return Context.Get(match); - } - - public static (ConfigName) Fist() - { - return Context.Fist(); - } - - public static (ConfigName) Last() - { - return Context.Last(); - } - - public static (ConfigName) Fist(Predicate<(ConfigName)> match) - { - return Context.Fist(match); - } - - public static (ConfigName) Last(Predicate<(ConfigName)> match) - { - return Context.Last(match); - } - - public static int Count() - { - return Context.Count(); - } - - public static int Count(Func<(ConfigName), bool> predicate) - { - return Context.Count(predicate); - } - - public static List<(ConfigName)> GetList() - { - return Context.GetList(); - } - - public static List<(ConfigName)> GetList(Predicate<(ConfigName)> match) - { - return Context.GetList(match); - } - public static void ParseJson(Newtonsoft.Json.Linq.JArray arr) - { - ConfigTableHelper.ParseLine<(ConfigName)>(arr); - } - #endregion - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Utils/FileHelper.cs b/Tools/ConfigBuilder/NBConfigBuilder/Utils/FileHelper.cs deleted file mode 100644 index db846ad..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Utils/FileHelper.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System.Text; - -namespace NBConfigBuilder; - -/// -/// 文件操作助手类,提供了各种文件操作方法。 -/// -public static partial class FileHelper -{ - /// - /// 获取相对路径的完整路径。 - /// - /// 相对路径。 - /// 完整路径。 - public static string GetFullPath(string relativePath) - { - return Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), relativePath)); - } - - /// - /// 获取相对路径的完整路径。 - /// - /// 相对于指定的目录的相对路径。 - /// 指定的目录 - /// 完整路径。 - public static string GetFullPath(string relativePath, string srcDir) - { - return Path.GetFullPath(Path.Combine(srcDir, relativePath)); - } - - /// - /// 获取相对路径的的文本信息。 - /// - /// - /// - public static async Task GetTextByRelativePath(string relativePath) - { - var fullPath = GetFullPath(relativePath); - return await File.ReadAllTextAsync(fullPath, Encoding.UTF8); - } - - /// - /// 获取绝对路径的的文本信息。 - /// - /// - /// - public static async Task GetText(string fullPath) - { - return await File.ReadAllTextAsync(fullPath, Encoding.UTF8); - } - - /// - /// 根据文件夹路径创建文件夹,如果文件夹不存在会自动创建文件夹。 - /// - /// - public static void CreateDirectory(string directoryPath) - { - if (directoryPath.LastIndexOf('/') != directoryPath.Length - 1) - { - directoryPath += "/"; - } - - var directoriesByFilePath = GetDirectoriesByFilePath(directoryPath); - - foreach (var dir in directoriesByFilePath) - { - if (Directory.Exists(dir)) - { - continue; - } - - Directory.CreateDirectory(dir); - } - } - - /// - /// 将文件复制到目标路径,如果目标目录不存在会自动创建目录。 - /// - /// 源文件路径。 - /// 目标文件路径。 - /// 是否覆盖已存在的目标文件。 - public static void Copy(string sourceFile, string destinationFile, bool overwrite) - { - CreateDirectory(destinationFile); - File.Copy(sourceFile, destinationFile, overwrite); - } - - /// - /// 获取文件路径内的所有文件夹路径。 - /// - /// 文件路径。 - /// 文件夹路径列表。 - public static IEnumerable GetDirectoriesByFilePath(string filePath) - { - var dir = ""; - var fileDirectories = filePath.Split('/'); - - for (var i = 0; i < fileDirectories.Length - 1; i++) - { - dir = $"{dir}{fileDirectories[i]}/"; - yield return dir; - } - - if (fileDirectories.Length == 1) - { - yield return filePath; - } - } - - /// - /// 将文件夹内的所有内容复制到目标位置。 - /// - /// 源文件夹路径。 - /// 目标文件夹路径。 - /// 是否覆盖已存在的文件。 - public static void CopyDirectory(string sourceDirectory, string destinationDirectory, bool overwrite) - { - // 创建目标文件夹 - - if (!Directory.Exists(destinationDirectory)) - { - Directory.CreateDirectory(destinationDirectory); - } - - // 获取当前文件夹中的所有文件 - - var files = Directory.GetFiles(sourceDirectory); - - // 拷贝文件到目标文件夹 - - foreach (var file in files) - { - var fileName = Path.GetFileName(file); - var destinationPath = Path.Combine(destinationDirectory, fileName); - File.Copy(file, destinationPath, overwrite); - } - - // 获取源文件夹中的所有子文件夹 - - var directories = Directory.GetDirectories(sourceDirectory); - - // 递归方式拷贝文件夹 - - foreach (var directory in directories) - { - var directoryName = Path.GetFileName(directory); - var destinationPath = Path.Combine(destinationDirectory, directoryName); - CopyDirectory(directory, destinationPath, overwrite); - } - } - - /// - /// 获取目录下的所有文件 - /// - /// 文件夹路径。 - /// 需要查找的文件通配符 - /// 查找的类型 - /// - public static string[] GetDirectoryFile(string folderPath, string searchPattern, SearchOption searchOption) - { - return Directory.GetFiles(folderPath, searchPattern, searchOption); - } - - /// - /// 清空文件夹内的所有文件。 - /// - /// 文件夹路径。 - public static void ClearDirectoryFile(string folderPath) - { - if (!Directory.Exists(folderPath)) - { - return; - } - - var files = Directory.GetFiles(folderPath); - - foreach (var file in files) - { - File.Delete(file); - } - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Utils/HashCodeHelper.cs b/Tools/ConfigBuilder/NBConfigBuilder/Utils/HashCodeHelper.cs deleted file mode 100644 index 92094c7..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Utils/HashCodeHelper.cs +++ /dev/null @@ -1,228 +0,0 @@ -using System.Security.Cryptography; -using System.Text; - -namespace NBConfigBuilder; - -/// -/// HashCode算法帮助类 -/// -public static partial class HashCodeHelper -{ - private static readonly SHA256 Sha256Hash = SHA256.Create(); - - /// - /// 计算两个字符串的HashCode - /// - /// - /// - /// - public static int GetHashCode(string a, string b) - { - var hash = 17; - hash = hash * 31 + a.GetHashCode(); - hash = hash * 31 + b.GetHashCode(); - return hash; - } -#if FANTASY_NET || !FANTASY_WEBGL - /// - /// 使用bkdr算法生成一个long的值 - /// - /// - /// - public static unsafe long GetBKDRHashCode(string str) - { - ulong hash = 0; - // 如果要修改这个种子、建议选择一个质数来做种子 - const uint seed = 13131; // 31 131 1313 13131 131313 etc.. - fixed (char* p = str) - { - for (var i = 0; i < str.Length; i++) - { - var c = p[i]; - var high = (byte)(c >> 8); - var low = (byte)(c & byte.MaxValue); - hash = hash * seed + high; - hash = hash * seed + low; - } - } - - return (long)hash; - } - - /// - /// 使用MurmurHash3算法生成一个uint的值 - /// - /// - /// - public static unsafe uint MurmurHash3(string str) - { - const uint seed = 0xc58f1a7b; - uint hash = seed; - uint c1 = 0xcc9e2d51; - uint c2 = 0x1b873593; - - fixed (char* p = str) - { - var current = p; - - for (var i = 0; i < str.Length; i++) - { - var k1 = (uint)(*current); - k1 *= c1; - k1 = (k1 << 15) | (k1 >> (32 - 15)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 13) | (hash >> (32 - 13)); - hash = hash * 5 + 0xe6546b64; - - current++; - } - } - - hash ^= (uint)str.Length; - hash ^= hash >> 16; - hash *= 0x85ebca6b; - hash ^= hash >> 13; - hash *= 0xc2b2ae35; - hash ^= hash >> 16; - return hash; - } - - /// - /// 使用MurmurHash3算法生成一个long的值 - /// - /// - /// - public static unsafe long ComputeHash64(string str) - { - const ulong seed = 0xc58f1a7bc58f1a7bUL; // 64-bit seed - var hash = seed; - var c1 = 0x87c37b91114253d5UL; - var c2 = 0x4cf5ad432745937fUL; - - fixed (char* p = str) - { - var current = p; - - for (var i = 0; i < str.Length; i++) - { - var k1 = (ulong)(*current); - k1 *= c1; - k1 = (k1 << 31) | (k1 >> (64 - 31)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 27) | (hash >> (64 - 27)); - hash = hash * 5 + 0x52dce729; - - current++; - } - } - - hash ^= (ulong)str.Length; - hash ^= hash >> 33; - hash *= 0xff51afd7ed558ccdUL; - hash ^= hash >> 33; - hash *= 0xc4ceb9fe1a85ec53UL; - hash ^= hash >> 33; - return (long)hash; - } -#endif -#if FANTASY_WEBGL - /// - /// 使用bkdr算法生成一个long的值 - /// - /// - /// - public static long GetBKDRHashCode(string str) - { - long hash = 0; - // 如果要修改这个种子、建议选择一个质数来做种子 - const uint seed = 13131; // 31 131 1313 13131 131313 etc.. - foreach (var c in str) - { - var high = (byte)(c >> 8); - var low = (byte)(c & byte.MaxValue); - hash = hash * seed + high; - hash = hash * seed + low; - } - return hash; - } - /// - /// 使用MurmurHash3算法生成一个uint的值 - /// - /// - /// - public static uint MurmurHash3(string str) - { - const uint seed = 0xc58f1a7b; - uint hash = seed; - uint c1 = 0xcc9e2d51; - uint c2 = 0x1b873593; - - foreach (var t in str) - { - var k1 = (uint)(t); - k1 *= c1; - k1 = (k1 << 15) | (k1 >> (32 - 15)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 13) | (hash >> (32 - 13)); - hash = hash * 5 + 0xe6546b64; - } - - hash ^= (uint)str.Length; - hash ^= hash >> 16; - hash *= 0x85ebca6b; - hash ^= hash >> 13; - hash *= 0xc2b2ae35; - hash ^= hash >> 16; - return hash; - } - - /// - /// 使用MurmurHash3算法生成一个long的值 - /// - /// - /// - public static long ComputeHash64(string str) - { - const ulong seed = 0xc58f1a7bc58f1a7bUL; // 64-bit seed - var hash = seed; - var c1 = 0x87c37b91114253d5UL; - var c2 = 0x4cf5ad432745937fUL; - - foreach (var t in str) - { - var k1 = (ulong)(t); - k1 *= c1; - k1 = (k1 << 31) | (k1 >> (64 - 31)); - k1 *= c2; - - hash ^= k1; - hash = (hash << 27) | (hash >> (64 - 27)); - hash = hash * 5 + 0x52dce729; - } - - hash ^= (ulong)str.Length; - hash ^= hash >> 33; - hash *= 0xff51afd7ed558ccdUL; - hash ^= hash >> 33; - hash *= 0xc4ceb9fe1a85ec53UL; - hash ^= hash >> 33; - return (long)hash; - } -#endif - /// - /// 根据字符串计算一个Hash值 - /// - /// - /// - public static int ComputeSha256HashAsInt(string rawData) - { - var bytes = Sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData)); - return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]; - } -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Utils/TimeHelper.cs b/Tools/ConfigBuilder/NBConfigBuilder/Utils/TimeHelper.cs deleted file mode 100644 index 8630260..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Utils/TimeHelper.cs +++ /dev/null @@ -1,65 +0,0 @@ -namespace NBConfigBuilder; - -/// -/// 提供与时间相关的帮助方法。 -/// -public static partial class TimeHelper -{ - /// - /// 一小时的毫秒值。 - /// - public const long Hour = 3600000; - - /// - /// 一分钟的毫秒值。 - /// - public const long Minute = 60000; - - /// - /// 一天的毫秒值。 - /// - public const long OneDay = 86400000; - - // 1970年1月1日的Ticks - private const long Epoch = 621355968000000000L; - /// - /// 获取当前时间的毫秒数,从1970年1月1日开始计算。 - /// - public static long Now => (DateTime.UtcNow.Ticks - Epoch) / 10000; - - /// - /// 根据时间获取时间戳 - /// - public static long Transition(DateTime dateTime) - { - return (dateTime.ToUniversalTime().Ticks - Epoch) / 10000; - } - - /// - /// 根据时间获取 时间戳 - /// - public static long TransitionToSeconds(DateTime dateTime) - { - return (dateTime.ToUniversalTime().Ticks - Epoch) / 10000000; - } - - /// - /// 将毫秒数转换为日期时间。 - /// - /// 要转换的毫秒数。 - /// 转换后的日期时间。 - public static DateTime Transition(this long timeStamp) - { - return new DateTime(Epoch + timeStamp * 10000, DateTimeKind.Utc).ToUniversalTime(); - } - - /// - /// 将毫秒数转换为本地时间的日期时间。 - /// - /// 要转换的毫秒数。 - /// 转换后的本地时间的日期时间。 - public static DateTime TransitionLocal(this long timeStamp) - { - return new DateTime(Epoch + timeStamp * 10000, DateTimeKind.Utc).ToLocalTime(); - } -} \ No newline at end of file diff --git a/Tools/NBConfigBuilder/EPPlus.Interfaces.dll b/Tools/NBConfigBuilder/EPPlus.Interfaces.dll deleted file mode 100644 index 8a69f81..0000000 Binary files a/Tools/NBConfigBuilder/EPPlus.Interfaces.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/EPPlus.dll b/Tools/NBConfigBuilder/EPPlus.dll deleted file mode 100644 index 6628025..0000000 Binary files a/Tools/NBConfigBuilder/EPPlus.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.CodeAnalysis.CSharp.dll b/Tools/NBConfigBuilder/Microsoft.CodeAnalysis.CSharp.dll deleted file mode 100644 index e2821ad..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.CodeAnalysis.CSharp.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.CodeAnalysis.dll b/Tools/NBConfigBuilder/Microsoft.CodeAnalysis.dll deleted file mode 100644 index d3f985e..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.CodeAnalysis.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.Abstractions.dll b/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.Abstractions.dll deleted file mode 100644 index a5ab313..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.Abstractions.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.FileExtensions.dll b/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.FileExtensions.dll deleted file mode 100644 index 19d8f5c..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.FileExtensions.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.Json.dll b/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.Json.dll deleted file mode 100644 index 9e50db0..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.Json.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.dll b/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.dll deleted file mode 100644 index d3e5c22..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.Extensions.Configuration.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.Extensions.FileProviders.Abstractions.dll b/Tools/NBConfigBuilder/Microsoft.Extensions.FileProviders.Abstractions.dll deleted file mode 100644 index f907206..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.Extensions.FileProviders.Abstractions.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.Extensions.FileProviders.Physical.dll b/Tools/NBConfigBuilder/Microsoft.Extensions.FileProviders.Physical.dll deleted file mode 100644 index 6fb7f47..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.Extensions.FileProviders.Physical.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.Extensions.FileSystemGlobbing.dll b/Tools/NBConfigBuilder/Microsoft.Extensions.FileSystemGlobbing.dll deleted file mode 100644 index e590735..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.Extensions.FileSystemGlobbing.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.Extensions.Primitives.dll b/Tools/NBConfigBuilder/Microsoft.Extensions.Primitives.dll deleted file mode 100644 index c24f2a0..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.Extensions.Primitives.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/Microsoft.IO.RecyclableMemoryStream.dll b/Tools/NBConfigBuilder/Microsoft.IO.RecyclableMemoryStream.dll deleted file mode 100644 index 6e0ea40..0000000 Binary files a/Tools/NBConfigBuilder/Microsoft.IO.RecyclableMemoryStream.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/NBConfigBuilder.deps.json b/Tools/NBConfigBuilder/NBConfigBuilder.deps.json deleted file mode 100644 index 804b791..0000000 --- a/Tools/NBConfigBuilder/NBConfigBuilder.deps.json +++ /dev/null @@ -1,516 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETCoreApp,Version=v8.0", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETCoreApp,Version=v8.0": { - "NBConfigBuilder/1.0.0": { - "dependencies": { - "EPPlus": "8.2.0", - "Microsoft.CodeAnalysis.CSharp": "4.14.0", - "NLog": "6.0.4", - "Newtonsoft.Json": "13.0.4", - "protobuf-net": "3.2.56" - }, - "runtime": { - "NBConfigBuilder.dll": {} - } - }, - "EPPlus/8.2.0": { - "dependencies": { - "EPPlus.Interfaces": "8.1.0", - "Microsoft.Extensions.Configuration.Json": "8.0.1", - "Microsoft.IO.RecyclableMemoryStream": "3.0.1", - "System.ComponentModel.Annotations": "5.0.0", - "System.Security.Cryptography.Pkcs": "8.0.1", - "System.Security.Cryptography.Xml": "8.0.2", - "System.Text.Encoding.CodePages": "8.0.0" - }, - "runtime": { - "lib/net8.0/EPPlus.dll": { - "assemblyVersion": "8.2.0.0", - "fileVersion": "8.2.0.0" - } - } - }, - "EPPlus.Interfaces/8.1.0": { - "runtime": { - "lib/net8.0/EPPlus.Interfaces.dll": { - "assemblyVersion": "8.1.0.0", - "fileVersion": "8.1.0.0" - } - } - }, - "Microsoft.CodeAnalysis.Analyzers/3.11.0": {}, - "Microsoft.CodeAnalysis.Common/4.14.0": { - "dependencies": { - "Microsoft.CodeAnalysis.Analyzers": "3.11.0", - "System.Collections.Immutable": "9.0.0", - "System.Reflection.Metadata": "9.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.CodeAnalysis.dll": { - "assemblyVersion": "4.14.0.0", - "fileVersion": "4.1400.25.26210" - } - }, - "resources": { - "lib/net8.0/cs/Microsoft.CodeAnalysis.resources.dll": { - "locale": "cs" - }, - "lib/net8.0/de/Microsoft.CodeAnalysis.resources.dll": { - "locale": "de" - }, - "lib/net8.0/es/Microsoft.CodeAnalysis.resources.dll": { - "locale": "es" - }, - "lib/net8.0/fr/Microsoft.CodeAnalysis.resources.dll": { - "locale": "fr" - }, - "lib/net8.0/it/Microsoft.CodeAnalysis.resources.dll": { - "locale": "it" - }, - "lib/net8.0/ja/Microsoft.CodeAnalysis.resources.dll": { - "locale": "ja" - }, - "lib/net8.0/ko/Microsoft.CodeAnalysis.resources.dll": { - "locale": "ko" - }, - "lib/net8.0/pl/Microsoft.CodeAnalysis.resources.dll": { - "locale": "pl" - }, - "lib/net8.0/pt-BR/Microsoft.CodeAnalysis.resources.dll": { - "locale": "pt-BR" - }, - "lib/net8.0/ru/Microsoft.CodeAnalysis.resources.dll": { - "locale": "ru" - }, - "lib/net8.0/tr/Microsoft.CodeAnalysis.resources.dll": { - "locale": "tr" - }, - "lib/net8.0/zh-Hans/Microsoft.CodeAnalysis.resources.dll": { - "locale": "zh-Hans" - }, - "lib/net8.0/zh-Hant/Microsoft.CodeAnalysis.resources.dll": { - "locale": "zh-Hant" - } - } - }, - "Microsoft.CodeAnalysis.CSharp/4.14.0": { - "dependencies": { - "Microsoft.CodeAnalysis.Analyzers": "3.11.0", - "Microsoft.CodeAnalysis.Common": "4.14.0", - "System.Collections.Immutable": "9.0.0", - "System.Reflection.Metadata": "9.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.CodeAnalysis.CSharp.dll": { - "assemblyVersion": "4.14.0.0", - "fileVersion": "4.1400.25.26210" - } - }, - "resources": { - "lib/net8.0/cs/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "cs" - }, - "lib/net8.0/de/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "de" - }, - "lib/net8.0/es/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "es" - }, - "lib/net8.0/fr/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "fr" - }, - "lib/net8.0/it/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "it" - }, - "lib/net8.0/ja/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "ja" - }, - "lib/net8.0/ko/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "ko" - }, - "lib/net8.0/pl/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "pl" - }, - "lib/net8.0/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "pt-BR" - }, - "lib/net8.0/ru/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "ru" - }, - "lib/net8.0/tr/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "tr" - }, - "lib/net8.0/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "zh-Hans" - }, - "lib/net8.0/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "zh-Hant" - } - } - }, - "Microsoft.Extensions.Configuration/8.0.0": { - "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "8.0.0", - "Microsoft.Extensions.Primitives": "8.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.Extensions.Configuration.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.23.53103" - } - } - }, - "Microsoft.Extensions.Configuration.Abstractions/8.0.0": { - "dependencies": { - "Microsoft.Extensions.Primitives": "8.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.Extensions.Configuration.Abstractions.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.23.53103" - } - } - }, - "Microsoft.Extensions.Configuration.FileExtensions/8.0.1": { - "dependencies": { - "Microsoft.Extensions.Configuration": "8.0.0", - "Microsoft.Extensions.Configuration.Abstractions": "8.0.0", - "Microsoft.Extensions.FileProviders.Abstractions": "8.0.0", - "Microsoft.Extensions.FileProviders.Physical": "8.0.0", - "Microsoft.Extensions.Primitives": "8.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.Extensions.Configuration.FileExtensions.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.724.31311" - } - } - }, - "Microsoft.Extensions.Configuration.Json/8.0.1": { - "dependencies": { - "Microsoft.Extensions.Configuration": "8.0.0", - "Microsoft.Extensions.Configuration.Abstractions": "8.0.0", - "Microsoft.Extensions.Configuration.FileExtensions": "8.0.1", - "Microsoft.Extensions.FileProviders.Abstractions": "8.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.Extensions.Configuration.Json.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.1024.46610" - } - } - }, - "Microsoft.Extensions.FileProviders.Abstractions/8.0.0": { - "dependencies": { - "Microsoft.Extensions.Primitives": "8.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.Extensions.FileProviders.Abstractions.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.23.53103" - } - } - }, - "Microsoft.Extensions.FileProviders.Physical/8.0.0": { - "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "8.0.0", - "Microsoft.Extensions.FileSystemGlobbing": "8.0.0", - "Microsoft.Extensions.Primitives": "8.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.Extensions.FileProviders.Physical.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.23.53103" - } - } - }, - "Microsoft.Extensions.FileSystemGlobbing/8.0.0": { - "runtime": { - "lib/net8.0/Microsoft.Extensions.FileSystemGlobbing.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.23.53103" - } - } - }, - "Microsoft.Extensions.Primitives/8.0.0": { - "runtime": { - "lib/net8.0/Microsoft.Extensions.Primitives.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.23.53103" - } - } - }, - "Microsoft.IO.RecyclableMemoryStream/3.0.1": { - "runtime": { - "lib/net6.0/Microsoft.IO.RecyclableMemoryStream.dll": { - "assemblyVersion": "3.0.1.0", - "fileVersion": "3.0.1.0" - } - } - }, - "Newtonsoft.Json/13.0.4": { - "runtime": { - "lib/net6.0/Newtonsoft.Json.dll": { - "assemblyVersion": "13.0.0.0", - "fileVersion": "13.0.4.30916" - } - } - }, - "NLog/6.0.4": { - "runtime": { - "lib/netstandard2.1/NLog.dll": { - "assemblyVersion": "6.0.0.0", - "fileVersion": "6.0.4.4534" - } - } - }, - "protobuf-net/3.2.56": { - "dependencies": { - "protobuf-net.Core": "3.2.56" - }, - "runtime": { - "lib/net8.0/protobuf-net.dll": { - "assemblyVersion": "3.0.0.0", - "fileVersion": "3.2.56.57311" - } - } - }, - "protobuf-net.Core/3.2.56": { - "runtime": { - "lib/net8.0/protobuf-net.Core.dll": { - "assemblyVersion": "3.0.0.0", - "fileVersion": "3.2.56.57311" - } - } - }, - "System.Collections.Immutable/9.0.0": { - "runtime": { - "lib/net8.0/System.Collections.Immutable.dll": { - "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.24.52809" - } - } - }, - "System.ComponentModel.Annotations/5.0.0": {}, - "System.Reflection.Metadata/9.0.0": { - "dependencies": { - "System.Collections.Immutable": "9.0.0" - }, - "runtime": { - "lib/net8.0/System.Reflection.Metadata.dll": { - "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.24.52809" - } - } - }, - "System.Security.Cryptography.Pkcs/8.0.1": { - "runtime": { - "lib/net8.0/System.Security.Cryptography.Pkcs.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.1024.46610" - } - }, - "runtimeTargets": { - "runtimes/win/lib/net8.0/System.Security.Cryptography.Pkcs.dll": { - "rid": "win", - "assetType": "runtime", - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.1024.46610" - } - } - }, - "System.Security.Cryptography.Xml/8.0.2": { - "dependencies": { - "System.Security.Cryptography.Pkcs": "8.0.1" - }, - "runtime": { - "lib/net8.0/System.Security.Cryptography.Xml.dll": { - "assemblyVersion": "8.0.0.0", - "fileVersion": "8.0.1024.46610" - } - } - }, - "System.Text.Encoding.CodePages/8.0.0": {} - } - }, - "libraries": { - "NBConfigBuilder/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - }, - "EPPlus/8.2.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-UFAjVAP4UyR9rPL/adHw1uezX1gDbt2mM7Bkb7cMmqbw51y0HFKyLoHpsjvNzKRL/u05vW4pHJAmkuvrPBcgSw==", - "path": "epplus/8.2.0", - "hashPath": "epplus.8.2.0.nupkg.sha512" - }, - "EPPlus.Interfaces/8.1.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-Nfc7ehsn8Sb8Ed8KYYuOxqt8gWqmy2Vhts5nfLMw3zISi+aZFwyW+k9s3FOpVuW91VDSrhVAId9brYtz9NnmKA==", - "path": "epplus.interfaces/8.1.0", - "hashPath": "epplus.interfaces.8.1.0.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.Analyzers/3.11.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-v/EW3UE8/lbEYHoC2Qq7AR/DnmvpgdtAMndfQNmpuIMx/Mto8L5JnuCfdBYtgvalQOtfNCnxFejxuRrryvUTsg==", - "path": "microsoft.codeanalysis.analyzers/3.11.0", - "hashPath": "microsoft.codeanalysis.analyzers.3.11.0.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.Common/4.14.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-PC3tuwZYnC+idaPuoC/AZpEdwrtX7qFpmnrfQkgobGIWiYmGi5MCRtl5mx6QrfMGQpK78X2lfIEoZDLg/qnuHg==", - "path": "microsoft.codeanalysis.common/4.14.0", - "hashPath": "microsoft.codeanalysis.common.4.14.0.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.CSharp/4.14.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-568a6wcTivauIhbeWcCwfWwIn7UV7MeHEBvFB2uzGIpM2OhJ4eM/FZ8KS0yhPoNxnSpjGzz7x7CIjTxhslojQA==", - "path": "microsoft.codeanalysis.csharp/4.14.0", - "hashPath": "microsoft.codeanalysis.csharp.4.14.0.nupkg.sha512" - }, - "Microsoft.Extensions.Configuration/8.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-0J/9YNXTMWSZP2p2+nvl8p71zpSwokZXZuJW+VjdErkegAnFdO1XlqtA62SJtgVYHdKu3uPxJHcMR/r35HwFBA==", - "path": "microsoft.extensions.configuration/8.0.0", - "hashPath": "microsoft.extensions.configuration.8.0.0.nupkg.sha512" - }, - "Microsoft.Extensions.Configuration.Abstractions/8.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==", - "path": "microsoft.extensions.configuration.abstractions/8.0.0", - "hashPath": "microsoft.extensions.configuration.abstractions.8.0.0.nupkg.sha512" - }, - "Microsoft.Extensions.Configuration.FileExtensions/8.0.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-EJzSNO9oaAXnTdtdNO6npPRsIIeZCBSNmdQ091VDO7fBiOtJAAeEq6dtrVXIi3ZyjC5XRSAtVvF8SzcneRHqKQ==", - "path": "microsoft.extensions.configuration.fileextensions/8.0.1", - "hashPath": "microsoft.extensions.configuration.fileextensions.8.0.1.nupkg.sha512" - }, - "Microsoft.Extensions.Configuration.Json/8.0.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-L89DLNuimOghjV3tLx0ArFDwVEJD6+uGB3BMCMX01kaLzXkaXHb2021xOMl2QOxUxbdePKUZsUY7n2UUkycjRg==", - "path": "microsoft.extensions.configuration.json/8.0.1", - "hashPath": "microsoft.extensions.configuration.json.8.0.1.nupkg.sha512" - }, - "Microsoft.Extensions.FileProviders.Abstractions/8.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ZbaMlhJlpisjuWbvXr4LdAst/1XxH3vZ6A0BsgTphZ2L4PGuxRLz7Jr/S7mkAAnOn78Vu0fKhEgNF5JO3zfjqQ==", - "path": "microsoft.extensions.fileproviders.abstractions/8.0.0", - "hashPath": "microsoft.extensions.fileproviders.abstractions.8.0.0.nupkg.sha512" - }, - "Microsoft.Extensions.FileProviders.Physical/8.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-UboiXxpPUpwulHvIAVE36Knq0VSHaAmfrFkegLyBZeaADuKezJ/AIXYAW8F5GBlGk/VaibN2k/Zn1ca8YAfVdA==", - "path": "microsoft.extensions.fileproviders.physical/8.0.0", - "hashPath": "microsoft.extensions.fileproviders.physical.8.0.0.nupkg.sha512" - }, - "Microsoft.Extensions.FileSystemGlobbing/8.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-OK+670i7esqlQrPjdIKRbsyMCe9g5kSLpRRQGSr4Q58AOYEe/hCnfLZprh7viNisSUUQZmMrbbuDaIrP+V1ebQ==", - "path": "microsoft.extensions.filesystemglobbing/8.0.0", - "hashPath": "microsoft.extensions.filesystemglobbing.8.0.0.nupkg.sha512" - }, - "Microsoft.Extensions.Primitives/8.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g==", - "path": "microsoft.extensions.primitives/8.0.0", - "hashPath": "microsoft.extensions.primitives.8.0.0.nupkg.sha512" - }, - "Microsoft.IO.RecyclableMemoryStream/3.0.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-s/s20YTVY9r9TPfTrN5g8zPF1YhwxyqO6PxUkrYTGI2B+OGPe9AdajWZrLhFqXIvqIW23fnUE4+ztrUWNU1+9g==", - "path": "microsoft.io.recyclablememorystream/3.0.1", - "hashPath": "microsoft.io.recyclablememorystream.3.0.1.nupkg.sha512" - }, - "Newtonsoft.Json/13.0.4": { - "type": "package", - "serviceable": true, - "sha512": "sha512-pdgNNMai3zv51W5aq268sujXUyx7SNdE2bj1wZcWjAQrKMFZV260lbqYop1d2GM67JI1huLRwxo9ZqnfF/lC6A==", - "path": "newtonsoft.json/13.0.4", - "hashPath": "newtonsoft.json.13.0.4.nupkg.sha512" - }, - "NLog/6.0.4": { - "type": "package", - "serviceable": true, - "sha512": "sha512-Xr+lIk1ZlTTFXEqnxQVLxrDqZlt2tm5X+/AhJbaY2emb/dVtGDiU5QuEtj3gHtwV/SWlP/rJ922I/BPuOJXlRw==", - "path": "nlog/6.0.4", - "hashPath": "nlog.6.0.4.nupkg.sha512" - }, - "protobuf-net/3.2.56": { - "type": "package", - "serviceable": true, - "sha512": "sha512-4IPJeTYAMNewlN8MDaFkcmR/9hLhJeo9eARnTh104zh7mf+vXT2gu5MUfUnkSQU+CH578Q6vcdU7LQDQPG6eaw==", - "path": "protobuf-net/3.2.56", - "hashPath": "protobuf-net.3.2.56.nupkg.sha512" - }, - "protobuf-net.Core/3.2.56": { - "type": "package", - "serviceable": true, - "sha512": "sha512-d6QOukTpDzs7zZv9tPnBZMtvHDNeHJQXUhMx54g4urUQsXK3oo9U70H9HvklYq7hlQ4A7AHJl7EVEqyCXXIl8Q==", - "path": "protobuf-net.core/3.2.56", - "hashPath": "protobuf-net.core.3.2.56.nupkg.sha512" - }, - "System.Collections.Immutable/9.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w==", - "path": "system.collections.immutable/9.0.0", - "hashPath": "system.collections.immutable.9.0.0.nupkg.sha512" - }, - "System.ComponentModel.Annotations/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==", - "path": "system.componentmodel.annotations/5.0.0", - "hashPath": "system.componentmodel.annotations.5.0.0.nupkg.sha512" - }, - "System.Reflection.Metadata/9.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ANiqLu3DxW9kol/hMmTWbt3414t9ftdIuiIU7j80okq2YzAueo120M442xk1kDJWtmZTqWQn7wHDvMRipVOEOQ==", - "path": "system.reflection.metadata/9.0.0", - "hashPath": "system.reflection.metadata.9.0.0.nupkg.sha512" - }, - "System.Security.Cryptography.Pkcs/8.0.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-CoCRHFym33aUSf/NtWSVSZa99dkd0Hm7OCZUxORBjRB16LNhIEOf8THPqzIYlvKM0nNDAPTRBa1FxEECrgaxxA==", - "path": "system.security.cryptography.pkcs/8.0.1", - "hashPath": "system.security.cryptography.pkcs.8.0.1.nupkg.sha512" - }, - "System.Security.Cryptography.Xml/8.0.2": { - "type": "package", - "serviceable": true, - "sha512": "sha512-aDM/wm0ZGEZ6ZYJLzgqjp2FZdHbDHh6/OmpGfb7AdZ105zYmPn/83JRU2xLIbwgoNz9U1SLUTJN0v5th3qmvjA==", - "path": "system.security.cryptography.xml/8.0.2", - "hashPath": "system.security.cryptography.xml.8.0.2.nupkg.sha512" - }, - "System.Text.Encoding.CodePages/8.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==", - "path": "system.text.encoding.codepages/8.0.0", - "hashPath": "system.text.encoding.codepages.8.0.0.nupkg.sha512" - } - } -} \ No newline at end of file diff --git a/Tools/NBConfigBuilder/NBConfigBuilder.dll b/Tools/NBConfigBuilder/NBConfigBuilder.dll deleted file mode 100644 index 50e9687..0000000 Binary files a/Tools/NBConfigBuilder/NBConfigBuilder.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/NBConfigBuilder.exe b/Tools/NBConfigBuilder/NBConfigBuilder.exe deleted file mode 100644 index 5fe07fe..0000000 Binary files a/Tools/NBConfigBuilder/NBConfigBuilder.exe and /dev/null differ diff --git a/Tools/NBConfigBuilder/NBConfigBuilder.pdb b/Tools/NBConfigBuilder/NBConfigBuilder.pdb deleted file mode 100644 index 54cc7a1..0000000 Binary files a/Tools/NBConfigBuilder/NBConfigBuilder.pdb and /dev/null differ diff --git a/Tools/NBConfigBuilder/NBConfigBuilder.runtimeconfig.json b/Tools/NBConfigBuilder/NBConfigBuilder.runtimeconfig.json deleted file mode 100644 index b2dedf3..0000000 --- a/Tools/NBConfigBuilder/NBConfigBuilder.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net8.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "8.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "8.0.0" - } - ], - "configProperties": { - "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true, - "CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": false - } - } -} \ No newline at end of file diff --git a/Tools/NBConfigBuilder/NLog.config b/Tools/NBConfigBuilder/NLog.config deleted file mode 100644 index 4bd1557..0000000 --- a/Tools/NBConfigBuilder/NLog.config +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Tools/NBConfigBuilder/NLog.dll b/Tools/NBConfigBuilder/NLog.dll deleted file mode 100644 index 1d15c30..0000000 Binary files a/Tools/NBConfigBuilder/NLog.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/System.Collections.Immutable.dll b/Tools/NBConfigBuilder/System.Collections.Immutable.dll deleted file mode 100644 index 9db8140..0000000 Binary files a/Tools/NBConfigBuilder/System.Collections.Immutable.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/System.Reflection.Metadata.dll b/Tools/NBConfigBuilder/System.Reflection.Metadata.dll deleted file mode 100644 index 2366da2..0000000 Binary files a/Tools/NBConfigBuilder/System.Reflection.Metadata.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/System.Security.Cryptography.Pkcs.dll b/Tools/NBConfigBuilder/System.Security.Cryptography.Pkcs.dll deleted file mode 100644 index e521fd3..0000000 Binary files a/Tools/NBConfigBuilder/System.Security.Cryptography.Pkcs.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/System.Security.Cryptography.Xml.dll b/Tools/NBConfigBuilder/System.Security.Cryptography.Xml.dll deleted file mode 100644 index 1cb01ca..0000000 Binary files a/Tools/NBConfigBuilder/System.Security.Cryptography.Xml.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/TemplateBack.txt b/Tools/NBConfigBuilder/TemplateBack.txt deleted file mode 100644 index ebbd5d3..0000000 --- a/Tools/NBConfigBuilder/TemplateBack.txt +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using ProtoBuf; -using Fantasy; -using System.Linq; -using System.Reflection; -using System.Collections.Generic; -using System.Collections.Concurrent; -#if FANTASY_NET -using Fantasy.ConfigTable; -using Fantasy.Serialize; -#else -using NBC; -using NBC.Serialize; -#endif -// ReSharper disable CollectionNeverUpdated.Global -// ReSharper disable UnusedAutoPropertyAccessor.Global -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable CS0169 -#pragma warning disable CS8618 -#pragma warning disable CS8625 -#pragma warning disable CS8603 - -namespace (namespace) -{ - [ProtoContract] - public sealed partial class (ConfigName)Data : ASerialize, IConfigTable, IProto - { - [ProtoMember(1)] - public List<(ConfigName)> List { get; set; } = new List<(ConfigName)>(); -#if FANTASY_NET - [ProtoIgnore] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); -#else - [ProtoIgnore] - private readonly Dictionary _configs = new Dictionary(); -#endif - private static (ConfigName)Data _instance = null; - - public static (ConfigName)Data Instance - { - get { return _instance ??= ConfigTableHelper.Load<(ConfigName)Data>(); } - private set => _instance = value; - } - - public (ConfigName) Get(uint id, bool check = true) - { - if (_configs.ContainsKey(id)) - { - return _configs[id]; - } - - if (check) - { - throw new Exception($"(ConfigName) not find {id} Id"); - } - - return null; - } - public bool TryGet(uint id, out (ConfigName) config) - { - config = null; - - if (!_configs.ContainsKey(id)) - { - return false; - } - - config = _configs[id]; - return true; - } - public override void AfterDeserialization() - { - foreach (var config in List) - { -#if FANTASY_NET - _configs.TryAdd(config.Id, config); -#else - _configs.Add(config.Id, config); -#endif - config.AfterDeserialization(); - } - - EndInit(); - } - - public override void Dispose() - { - Instance = null; - } - } - - [ProtoContract] - public sealed partial class (ConfigName) : ASerialize, IProto - {(Fields) - } -} \ No newline at end of file diff --git a/Tools/NBConfigBuilder/TemplateClient.txt b/Tools/NBConfigBuilder/TemplateClient.txt deleted file mode 100644 index 47a04cb..0000000 --- a/Tools/NBConfigBuilder/TemplateClient.txt +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using ProtoBuf; -using Fantasy; -using System.Linq; -using System.Reflection; -using System.Collections.Generic; -using System.Collections.Concurrent; -using NBC; -using NBC.Serialize; - -namespace NBF -{ - [ProtoContract] - public sealed partial class (ConfigName) : ASerialize, IProto, IConfigTable - { - (Fields) - [ProtoIgnore] - public uint Key => Id; - - #region Static - - private static ConfigContext<(ConfigName)> Context => ConfigTableHelper.Table<(ConfigName)>(); - - public static (ConfigName) Get(uint key) - { - return Context.Get(key); - } - - public static (ConfigName) Get(Predicate<(ConfigName)> match) - { - return Context.Get(match); - } - - public static (ConfigName) Fist() - { - return Context.Fist(); - } - - public static (ConfigName) Last() - { - return Context.Last(); - } - - public static (ConfigName) Fist(Predicate<(ConfigName)> match) - { - return Context.Fist(match); - } - - public static (ConfigName) Last(Predicate<(ConfigName)> match) - { - return Context.Last(match); - } - - public static int Count() - { - return Context.Count(); - } - - public static int Count(Func<(ConfigName), bool> predicate) - { - return Context.Count(predicate); - } - - public static List<(ConfigName)> GetList() - { - return Context.GetList(); - } - - public static List<(ConfigName)> GetList(Predicate<(ConfigName)> match) - { - return Context.GetList(match); - } - public static void ParseJson(Newtonsoft.Json.Linq.JArray arr) - { - ConfigTableHelper.ParseLine<(ConfigName)>(arr); - } - #endregion - } -} \ No newline at end of file diff --git a/Tools/NBConfigBuilder/TemplateServer.txt b/Tools/NBConfigBuilder/TemplateServer.txt deleted file mode 100644 index 3a2823b..0000000 --- a/Tools/NBConfigBuilder/TemplateServer.txt +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using ProtoBuf; -using Fantasy; -using System.Linq; -using System.Reflection; -using System.Collections.Generic; -using System.Collections.Concurrent; -using Fantasy.Serialize; -using Fantasy.ConfigTable; - -namespace NBF -{ - [ProtoContract] - public sealed partial class (ConfigName) : ASerialize, IProto, IConfigTable - { - (Fields) - [ProtoIgnore] - public uint Key => Id; - - #region Static - - private static ConfigContext<(ConfigName)> Context => ConfigTableHelper.Table<(ConfigName)>(); - - public static (ConfigName) Get(uint key) - { - return Context.Get(key); - } - - public static (ConfigName) Get(Predicate<(ConfigName)> match) - { - return Context.Get(match); - } - - public static (ConfigName) Fist() - { - return Context.Fist(); - } - - public static (ConfigName) Last() - { - return Context.Last(); - } - - public static (ConfigName) Fist(Predicate<(ConfigName)> match) - { - return Context.Fist(match); - } - - public static (ConfigName) Last(Predicate<(ConfigName)> match) - { - return Context.Last(match); - } - - public static int Count() - { - return Context.Count(); - } - - public static int Count(Func<(ConfigName), bool> predicate) - { - return Context.Count(predicate); - } - - public static List<(ConfigName)> GetList() - { - return Context.GetList(); - } - - public static List<(ConfigName)> GetList(Predicate<(ConfigName)> match) - { - return Context.GetList(match); - } - public static void ParseJson(Newtonsoft.Json.Linq.JArray arr) - { - ConfigTableHelper.ParseLine<(ConfigName)>(arr); - } - #endregion - } -} \ No newline at end of file diff --git a/Tools/NBConfigBuilder/config - 副本.json b/Tools/NBConfigBuilder/config - 副本.json deleted file mode 100644 index 4891ac6..0000000 --- a/Tools/NBConfigBuilder/config - 副本.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "ExcelPath": "D:\\work\\Fishing2\\Config", - "ClientPath": "D:\\work\\Fishing2\\Assets\\Scripts\\Generate\\Config", - "ClientJsonPath": "D:\\work\\Fishing2\\Assets\\Resources\\config", - "ServerPath": "D:\\work\\Fishing2Server\\Entity\\Generate\\ConfigTable\\Entity", - "ServerJsonPath": "D:\\work\\Fishing2Server\\Config\\Json", - "GenClient": true, - "GenServer": true, - "ExcelVersionPath": "D:\\work\\Fishing2\\Config\\Version.txt" -} \ No newline at end of file diff --git a/Tools/NBConfigBuilder/config.json b/Tools/NBConfigBuilder/config.json deleted file mode 100644 index ab52864..0000000 --- a/Tools/NBConfigBuilder/config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "ExcelPath": "..\\..\\..\\Fishing2\\Config", - "ClientPath": "..\\..\\..\\Fishing2\\Assets\\Scripts\\Generate\\Config", - "ClientJsonPath": "..\\..\\..\\Fishing2\\Assets\\Resources\\config", - "ServerPath": "..\\..\\..\\Fishing2Server\\Entity\\Generate\\ConfigTable\\Entity", - "ServerJsonPath": "..\\..\\..\\Fishing2Server\\Config\\Json", - "GenClient": true, - "GenServer": true, - "ExcelVersionPath": "..\\..\\..\\Fishing2\\Config\\Version.txt" -} \ No newline at end of file diff --git a/Tools/NBConfigBuilder/cs/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/cs/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 67560d7..0000000 Binary files a/Tools/NBConfigBuilder/cs/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/cs/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/cs/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 155bcce..0000000 Binary files a/Tools/NBConfigBuilder/cs/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/de/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/de/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index daca134..0000000 Binary files a/Tools/NBConfigBuilder/de/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/de/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/de/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 0613dde..0000000 Binary files a/Tools/NBConfigBuilder/de/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/es/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/es/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 6528338..0000000 Binary files a/Tools/NBConfigBuilder/es/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/es/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/es/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 1d20ff2..0000000 Binary files a/Tools/NBConfigBuilder/es/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/fr/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/fr/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index d5d4b24..0000000 Binary files a/Tools/NBConfigBuilder/fr/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/fr/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/fr/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index e7aee2a..0000000 Binary files a/Tools/NBConfigBuilder/fr/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/it/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/it/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 57a91a7..0000000 Binary files a/Tools/NBConfigBuilder/it/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/it/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/it/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 78cb09d..0000000 Binary files a/Tools/NBConfigBuilder/it/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/ja/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/ja/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index a301df0..0000000 Binary files a/Tools/NBConfigBuilder/ja/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/ja/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/ja/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 77a390c..0000000 Binary files a/Tools/NBConfigBuilder/ja/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/ko/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/ko/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 5108385..0000000 Binary files a/Tools/NBConfigBuilder/ko/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/ko/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/ko/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 3c56215..0000000 Binary files a/Tools/NBConfigBuilder/ko/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/pl/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/pl/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 965c984..0000000 Binary files a/Tools/NBConfigBuilder/pl/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/pl/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/pl/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 2915250..0000000 Binary files a/Tools/NBConfigBuilder/pl/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 5afc260..0000000 Binary files a/Tools/NBConfigBuilder/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/pt-BR/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/pt-BR/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 700e2aa..0000000 Binary files a/Tools/NBConfigBuilder/pt-BR/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/ru/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/ru/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index b4138f4..0000000 Binary files a/Tools/NBConfigBuilder/ru/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/ru/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/ru/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 2cf63e5..0000000 Binary files a/Tools/NBConfigBuilder/ru/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/runtimes/win/lib/net8.0/System.Security.Cryptography.Pkcs.dll b/Tools/NBConfigBuilder/runtimes/win/lib/net8.0/System.Security.Cryptography.Pkcs.dll deleted file mode 100644 index b4d03d5..0000000 Binary files a/Tools/NBConfigBuilder/runtimes/win/lib/net8.0/System.Security.Cryptography.Pkcs.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/tr/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/tr/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 7ca2e8f..0000000 Binary files a/Tools/NBConfigBuilder/tr/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/tr/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/tr/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 0f76b86..0000000 Binary files a/Tools/NBConfigBuilder/tr/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 8c80a88..0000000 Binary files a/Tools/NBConfigBuilder/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/zh-Hans/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/zh-Hans/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 52f232d..0000000 Binary files a/Tools/NBConfigBuilder/zh-Hans/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/NBConfigBuilder/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 1936f8d..0000000 Binary files a/Tools/NBConfigBuilder/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/NBConfigBuilder/zh-Hant/Microsoft.CodeAnalysis.resources.dll b/Tools/NBConfigBuilder/zh-Hant/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index fe815c6..0000000 Binary files a/Tools/NBConfigBuilder/zh-Hant/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/NetworkProtocol/ExporterSettings.json b/Tools/NetworkProtocol/ExporterSettings.json deleted file mode 100644 index 0a26191..0000000 --- a/Tools/NetworkProtocol/ExporterSettings.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "Export": { - "NetworkProtocolDirectory": { - "Value": "../../Config/NetworkProtocol/", - "Comment": "ProtoBuf文件所在的文件夹位置" - }, - "NetworkProtocolServerDirectory": { - "Value": "../../Entity/Generate/NetworkProtocol/", - "Comment": "ProtoBuf生成到服务端的文件夹位置" - }, - "NetworkProtocolClientDirectory": { - "Value": "../../../Fishing2/Assets/Scripts/Generate/NetworkProtocol/", - "Comment": "ProtoBuf生成到客户端的文件夹位置" - }, - "Serializes": { - "Value": [ -// { -// "KeyIndex": 0, -// "NameSpace" : "MemoryPack", -// "SerializeName": "MemoryPack", -// "Attribute": "\t[MemoryPackable]", -// "Ignore": "\t\t[MemoryPackIgnore]", -// "Member": "MemoryPackOrder" -// } - ], - "Comment": "自定义序列化器" - } - } -} \ No newline at end of file diff --git a/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.dll b/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.dll deleted file mode 100644 index 5502bd8..0000000 Binary files a/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.dll and /dev/null differ diff --git a/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.exe b/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.exe deleted file mode 100644 index 7bdf927..0000000 Binary files a/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.exe and /dev/null differ diff --git a/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.pdb b/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.pdb deleted file mode 100644 index 5c60a04..0000000 Binary files a/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.pdb and /dev/null differ diff --git a/Config/NetworkProtocol/Inner/InnerMessage.proto b/Tools/NetworkProtocol/Inner/InnerMessage.proto similarity index 94% rename from Config/NetworkProtocol/Inner/InnerMessage.proto rename to Tools/NetworkProtocol/Inner/InnerMessage.proto index fad5279..feb5e4f 100644 --- a/Config/NetworkProtocol/Inner/InnerMessage.proto +++ b/Tools/NetworkProtocol/Inner/InnerMessage.proto @@ -59,7 +59,7 @@ message G2Map_EnterMapRequest // IRouteRequest,Map2G_EnterMapResponse { string RoomCode = 1; //房间代码 int64 AccountId = 2; //账号id - int32 MapId =3; //地图id + int32 MapId = 3; //地图id } /// 请求进入房间响应 @@ -67,7 +67,7 @@ message Map2G_EnterMapResponse // IRouteResponse { string RoomCode = 1; //房间代码 int32 MapId = 2; //地图id - repeated MapUnitInfo Units = 2; //房间玩家列表 + repeated MapUnitInfo Units = 3; //房间玩家列表 } diff --git a/Tools/NetworkProtocol/NetworkProtocol.zip b/Tools/NetworkProtocol/NetworkProtocol.zip new file mode 100644 index 0000000..706552d Binary files /dev/null and b/Tools/NetworkProtocol/NetworkProtocol.zip differ diff --git a/Config/NetworkProtocol/OpCode.Cache b/Tools/NetworkProtocol/OpCode.Cache similarity index 100% rename from Config/NetworkProtocol/OpCode.Cache rename to Tools/NetworkProtocol/OpCode.Cache diff --git a/Config/NetworkProtocol/Outer/GameMessage.proto b/Tools/NetworkProtocol/Outer/GameMessage.proto similarity index 100% rename from Config/NetworkProtocol/Outer/GameMessage.proto rename to Tools/NetworkProtocol/Outer/GameMessage.proto diff --git a/Config/NetworkProtocol/Outer/MapMessage.proto b/Tools/NetworkProtocol/Outer/MapMessage.proto similarity index 100% rename from Config/NetworkProtocol/Outer/MapMessage.proto rename to Tools/NetworkProtocol/Outer/MapMessage.proto diff --git a/Config/NetworkProtocol/Outer/OuterMessage.proto b/Tools/NetworkProtocol/Outer/OuterMessage.proto similarity index 100% rename from Config/NetworkProtocol/Outer/OuterMessage.proto rename to Tools/NetworkProtocol/Outer/OuterMessage.proto diff --git a/Config/NetworkProtocol/Outer/RoomMessage.proto b/Tools/NetworkProtocol/Outer/RoomMessage.proto similarity index 100% rename from Config/NetworkProtocol/Outer/RoomMessage.proto rename to Tools/NetworkProtocol/Outer/RoomMessage.proto diff --git a/Config/NetworkProtocol/Outer/SocialMessage.proto b/Tools/NetworkProtocol/Outer/SocialMessage.proto similarity index 100% rename from Config/NetworkProtocol/Outer/SocialMessage.proto rename to Tools/NetworkProtocol/Outer/SocialMessage.proto diff --git a/Config/NetworkProtocol/Outer/data/CommonProtoData.proto b/Tools/NetworkProtocol/Outer/data/CommonProtoData.proto similarity index 98% rename from Config/NetworkProtocol/Outer/data/CommonProtoData.proto rename to Tools/NetworkProtocol/Outer/data/CommonProtoData.proto index 5a4ce7f..83614ef 100644 --- a/Config/NetworkProtocol/Outer/data/CommonProtoData.proto +++ b/Tools/NetworkProtocol/Outer/data/CommonProtoData.proto @@ -86,7 +86,7 @@ message FishInfo { uint32 ConfigId = 1; //配置id int64 Id = 2; //物品id - int32 Weight =3; //重量 + int32 Weight = 3; //重量 int64 GetTime = 4; //获得时间 int64 ExpirationTime = 5; //失效时间 } diff --git a/Config/NetworkProtocol/Outer/data/MapProtoData.proto b/Tools/NetworkProtocol/Outer/data/MapProtoData.proto similarity index 100% rename from Config/NetworkProtocol/Outer/data/MapProtoData.proto rename to Tools/NetworkProtocol/Outer/data/MapProtoData.proto diff --git a/Config/NetworkProtocol/RoamingType.Config b/Tools/NetworkProtocol/RoamingType.Config similarity index 100% rename from Config/NetworkProtocol/RoamingType.Config rename to Tools/NetworkProtocol/RoamingType.Config diff --git a/Config/NetworkProtocol/RouteType.Config b/Tools/NetworkProtocol/RouteType.Config similarity index 100% rename from Config/NetworkProtocol/RouteType.Config rename to Tools/NetworkProtocol/RouteType.Config diff --git a/Tools/NetworkProtocol/Template.txt b/Tools/NetworkProtocol/Template.txt deleted file mode 100644 index 217dfaf..0000000 --- a/Tools/NetworkProtocol/Template.txt +++ /dev/null @@ -1,34 +0,0 @@ -#if SERVER -using ProtoBuf; -(UsingNamespace) -using System.Collections.Generic; -using MongoDB.Bson.Serialization.Attributes; -using Fantasy; -using Fantasy.Network.Interface; -using Fantasy.Serialize; -// ReSharper disable InconsistentNaming -// ReSharper disable RedundantUsingDirective -// ReSharper disable RedundantOverriddenMember -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedAutoPropertyAccessor.Global -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable CheckNamespace -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 - -namespace Fantasy -{ -#else -using ProtoBuf; -(UsingNamespace) -using System.Collections.Generic; -using Fantasy; -using NBC; -using NBC.Network.Interface; -using NBC.Serialize; -#pragma warning disable CS8618 - -namespace NBC -{ -#endif -(Content)} \ No newline at end of file diff --git a/Tools/NuGet/Fantasy.Tools.ExporterConfigTable/Fantasy-Net.Tools.ExporterConfigTable.targets b/Tools/NuGet/Fantasy.Tools.ExporterConfigTable/Fantasy-Net.Tools.ExporterConfigTable.targets deleted file mode 100644 index e8b9fad..0000000 --- a/Tools/NuGet/Fantasy.Tools.ExporterConfigTable/Fantasy-Net.Tools.ExporterConfigTable.targets +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/Tools/NuGet/Fantasy.Tools.ExporterConfigTable/Fantasy.Tools.ExporterConfigTable.csproj b/Tools/NuGet/Fantasy.Tools.ExporterConfigTable/Fantasy.Tools.ExporterConfigTable.csproj deleted file mode 100644 index af1ddef..0000000 --- a/Tools/NuGet/Fantasy.Tools.ExporterConfigTable/Fantasy.Tools.ExporterConfigTable.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - Fantasy-Net.Tools.ExporterConfigTable - 2024.2.26 - Fantasy-Net.Tools.ExporterConfigTable - qq362946 - qq362946 - ../../../nupkg - false - - Fantasy is a high-performance network development framework based on .NET, supporting mainstream protocols. It is designed for development teams or individuals needing a quick start, scalability, and a distributed, cross-platform solution at the commercial level. Fantasy aims to provide easy-to-use tools while ensuring high system performance and scalability. - Copyright 2026 qq362946 - https://www.code-fantasy.com/ - https://github.com/qq362946/Fantasy - git - Net, c#, Server, Game, GameServer, Fantasy , Network - icon.png - enable - enable - net8.0;net9.0 - default - - - - - - - - - - diff --git a/Tools/NuGet/Fantasy.Tools.ExporterConfigTable/icon.png b/Tools/NuGet/Fantasy.Tools.ExporterConfigTable/icon.png deleted file mode 100644 index 8ae7488..0000000 Binary files a/Tools/NuGet/Fantasy.Tools.ExporterConfigTable/icon.png and /dev/null differ diff --git a/Tools/NuGet/Fantasy.Tools.ExporterNetworkProtocol/Fantasy-Net.Tools.ExporterNetworkProtocol.targets b/Tools/NuGet/Fantasy.Tools.ExporterNetworkProtocol/Fantasy-Net.Tools.ExporterNetworkProtocol.targets deleted file mode 100644 index d719402..0000000 --- a/Tools/NuGet/Fantasy.Tools.ExporterNetworkProtocol/Fantasy-Net.Tools.ExporterNetworkProtocol.targets +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/Tools/NuGet/Fantasy.Tools.ExporterNetworkProtocol/Fantasy.Tools.ExporterNetworkProtocol.csproj b/Tools/NuGet/Fantasy.Tools.ExporterNetworkProtocol/Fantasy.Tools.ExporterNetworkProtocol.csproj deleted file mode 100644 index 18b4c30..0000000 --- a/Tools/NuGet/Fantasy.Tools.ExporterNetworkProtocol/Fantasy.Tools.ExporterNetworkProtocol.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - Fantasy-Net.Tools.ExporterNetworkProtocol - 2024.2.26 - Fantasy-Net.Tools.ExporterNetworkProtocol - qq362946 - qq362946 - ../../../nupkg - false - - Fantasy is a high-performance network development framework based on .NET, supporting mainstream protocols. It is designed for development teams or individuals needing a quick start, scalability, and a distributed, cross-platform solution at the commercial level. Fantasy aims to provide easy-to-use tools while ensuring high system performance and scalability. - Copyright 2026 qq362946 - https://www.code-fantasy.com/ - https://github.com/qq362946/Fantasy - git - Net, c#, Server, Game, GameServer, Fantasy , Network - icon.png - enable - enable - net8.0;net9.0 - default - - - - - - - - - - diff --git a/Tools/NuGet/Fantasy.Tools.ExporterNetworkProtocol/icon.png b/Tools/NuGet/Fantasy.Tools.ExporterNetworkProtocol/icon.png deleted file mode 100644 index 8ae7488..0000000 Binary files a/Tools/NuGet/Fantasy.Tools.ExporterNetworkProtocol/icon.png and /dev/null differ diff --git a/Tools/ProtocolExportTool/CommandLine.dll b/Tools/ProtocolExportTool/CommandLine.dll new file mode 100644 index 0000000..3eab2be Binary files /dev/null and b/Tools/ProtocolExportTool/CommandLine.dll differ diff --git a/Tools/ProtocolExportTool/ExporterSettings.json b/Tools/ProtocolExportTool/ExporterSettings.json new file mode 100644 index 0000000..f6cc5dc --- /dev/null +++ b/Tools/ProtocolExportTool/ExporterSettings.json @@ -0,0 +1,20 @@ +{ + "Export": { + "NetworkProtocolDirectory": { + "Value": "..//NetworkProtocol/", + "Comment": "网络协议文件所在的文件夹位置" + }, + "NetworkProtocolServerDirectory": { + "Value": "../../Server/Entity/Generate/NetworkProtocol/", + "Comment": "网络协议生成到服务端的文件夹位置" + }, + "NetworkProtocolClientDirectory": { + "Value": "../../Client/Unity/Assets/Scripts/Hotfix/Generate/NetworkProtocol/", + "Comment": "网络协议生成到客户端的文件夹位置" + }, + "Serializes": { + "Value": [], + "Comment": "自定义序列化器,暂不支持" + } + } +} \ No newline at end of file diff --git a/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol b/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol new file mode 100644 index 0000000..a7bf479 Binary files /dev/null and b/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol differ diff --git a/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.deps.json b/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.deps.json similarity index 55% rename from Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.deps.json rename to Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.deps.json index e19c8a4..646767f 100644 --- a/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.deps.json +++ b/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.deps.json @@ -9,7 +9,7 @@ "Fantasy.Tools.NetworkProtocol/1.0.0": { "dependencies": { "CommandLineParser": "2.9.1", - "Microsoft.Extensions.Configuration.Json": "9.0.6", + "Microsoft.Extensions.Configuration.Json": "9.0.10", "Newtonsoft.Json": "13.0.3" }, "runtime": { @@ -24,95 +24,95 @@ } } }, - "Microsoft.Extensions.Configuration/9.0.6": { + "Microsoft.Extensions.Configuration/9.0.10": { "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.6", - "Microsoft.Extensions.Primitives": "9.0.6" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.10", + "Microsoft.Extensions.Primitives": "9.0.10" }, "runtime": { "lib/net9.0/Microsoft.Extensions.Configuration.dll": { "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.625.26613" + "fileVersion": "9.0.1025.47515" } } }, - "Microsoft.Extensions.Configuration.Abstractions/9.0.6": { + "Microsoft.Extensions.Configuration.Abstractions/9.0.10": { "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.6" + "Microsoft.Extensions.Primitives": "9.0.10" }, "runtime": { "lib/net9.0/Microsoft.Extensions.Configuration.Abstractions.dll": { "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.625.26613" + "fileVersion": "9.0.1025.47515" } } }, - "Microsoft.Extensions.Configuration.FileExtensions/9.0.6": { + "Microsoft.Extensions.Configuration.FileExtensions/9.0.10": { "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.6", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.6", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.6", - "Microsoft.Extensions.FileProviders.Physical": "9.0.6", - "Microsoft.Extensions.Primitives": "9.0.6" + "Microsoft.Extensions.Configuration": "9.0.10", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.10", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.10", + "Microsoft.Extensions.FileProviders.Physical": "9.0.10", + "Microsoft.Extensions.Primitives": "9.0.10" }, "runtime": { "lib/net9.0/Microsoft.Extensions.Configuration.FileExtensions.dll": { "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.625.26613" + "fileVersion": "9.0.1025.47515" } } }, - "Microsoft.Extensions.Configuration.Json/9.0.6": { + "Microsoft.Extensions.Configuration.Json/9.0.10": { "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.6", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.6", - "Microsoft.Extensions.Configuration.FileExtensions": "9.0.6", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.6" + "Microsoft.Extensions.Configuration": "9.0.10", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.10", + "Microsoft.Extensions.Configuration.FileExtensions": "9.0.10", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.10" }, "runtime": { "lib/net9.0/Microsoft.Extensions.Configuration.Json.dll": { "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.625.26613" + "fileVersion": "9.0.1025.47515" } } }, - "Microsoft.Extensions.FileProviders.Abstractions/9.0.6": { + "Microsoft.Extensions.FileProviders.Abstractions/9.0.10": { "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.6" + "Microsoft.Extensions.Primitives": "9.0.10" }, "runtime": { "lib/net9.0/Microsoft.Extensions.FileProviders.Abstractions.dll": { "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.625.26613" + "fileVersion": "9.0.1025.47515" } } }, - "Microsoft.Extensions.FileProviders.Physical/9.0.6": { + "Microsoft.Extensions.FileProviders.Physical/9.0.10": { "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.6", - "Microsoft.Extensions.FileSystemGlobbing": "9.0.6", - "Microsoft.Extensions.Primitives": "9.0.6" + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.10", + "Microsoft.Extensions.FileSystemGlobbing": "9.0.10", + "Microsoft.Extensions.Primitives": "9.0.10" }, "runtime": { "lib/net9.0/Microsoft.Extensions.FileProviders.Physical.dll": { "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.625.26613" + "fileVersion": "9.0.1025.47515" } } }, - "Microsoft.Extensions.FileSystemGlobbing/9.0.6": { + "Microsoft.Extensions.FileSystemGlobbing/9.0.10": { "runtime": { "lib/net9.0/Microsoft.Extensions.FileSystemGlobbing.dll": { "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.625.26613" + "fileVersion": "9.0.1025.47515" } } }, - "Microsoft.Extensions.Primitives/9.0.6": { + "Microsoft.Extensions.Primitives/9.0.10": { "runtime": { "lib/net9.0/Microsoft.Extensions.Primitives.dll": { "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.625.26613" + "fileVersion": "9.0.1025.47515" } } }, @@ -139,61 +139,61 @@ "path": "commandlineparser/2.9.1", "hashPath": "commandlineparser.2.9.1.nupkg.sha512" }, - "Microsoft.Extensions.Configuration/9.0.6": { + "Microsoft.Extensions.Configuration/9.0.10": { "type": "package", "serviceable": true, - "sha512": "sha512-VWB5jdkxHsRiuoniTqwOL32R4OWyp5If/bAucLjRJczRVNcwb8iCXKLjn3Inv8fv+jHMVMnvQLg7xhSys+y5PA==", - "path": "microsoft.extensions.configuration/9.0.6", - "hashPath": "microsoft.extensions.configuration.9.0.6.nupkg.sha512" + "sha512": "sha512-UAm3SLGAMlJdowbN+/xnh2UGJkdJoXVm4MsdhZ60dAMS8jteoyCx5WfIab5DKv0TCYpdhVecLJVUjEO3abs9UQ==", + "path": "microsoft.extensions.configuration/9.0.10", + "hashPath": "microsoft.extensions.configuration.9.0.10.nupkg.sha512" }, - "Microsoft.Extensions.Configuration.Abstractions/9.0.6": { + "Microsoft.Extensions.Configuration.Abstractions/9.0.10": { "type": "package", "serviceable": true, - "sha512": "sha512-3GgMIi2jP8g1fBW93Z9b9Unamc0SIsgyhiCmC91gq4loTixK9vQMuxxUsfJ1kRGwn+/FqLKwOHqmn0oYWn3Fvw==", - "path": "microsoft.extensions.configuration.abstractions/9.0.6", - "hashPath": "microsoft.extensions.configuration.abstractions.9.0.6.nupkg.sha512" + "sha512": "sha512-ad3JxmFj0uxuFa1CT6oxTCC1lQ0xeRuOvzBRFT/I/ofIXVOnNsH/v2GZkAJWhlpZqKUvSexQZzp3EEAB2CdtJg==", + "path": "microsoft.extensions.configuration.abstractions/9.0.10", + "hashPath": "microsoft.extensions.configuration.abstractions.9.0.10.nupkg.sha512" }, - "Microsoft.Extensions.Configuration.FileExtensions/9.0.6": { + "Microsoft.Extensions.Configuration.FileExtensions/9.0.10": { "type": "package", "serviceable": true, - "sha512": "sha512-pCEueasI5JhJ24KYzMFxtG40zyLnWpcQYawpARh9FNq9XbWozuWgexmdkPa8p8YoVNlpi3ecKfcjfoRMkKAufw==", - "path": "microsoft.extensions.configuration.fileextensions/9.0.6", - "hashPath": "microsoft.extensions.configuration.fileextensions.9.0.6.nupkg.sha512" + "sha512": "sha512-kYWY9VRoCKQJCLKAA4Wqn74FVnytqosF7vFq1chJ8st9mGZS6SQrkoZg7GmcpqrRRUWmWDOZI4nFdoFnxsI/Ug==", + "path": "microsoft.extensions.configuration.fileextensions/9.0.10", + "hashPath": "microsoft.extensions.configuration.fileextensions.9.0.10.nupkg.sha512" }, - "Microsoft.Extensions.Configuration.Json/9.0.6": { + "Microsoft.Extensions.Configuration.Json/9.0.10": { "type": "package", "serviceable": true, - "sha512": "sha512-N0dgOYQ9tDzJouL9Tyx2dgMCcHV2pBaY8yVtorbDqYYwiDRS2zd1TbhTA2FMHqXF3SMjBoO+gONZcDoA79gdSA==", - "path": "microsoft.extensions.configuration.json/9.0.6", - "hashPath": "microsoft.extensions.configuration.json.9.0.6.nupkg.sha512" + "sha512": "sha512-bn+qnwuOaDelax8PUw30UTjLOuEd0lGWqUG4Z+oVr4D/gEWouCWOyvCVkyn+PWbftPlnmAmWxd4J+7ljwE8wVw==", + "path": "microsoft.extensions.configuration.json/9.0.10", + "hashPath": "microsoft.extensions.configuration.json.9.0.10.nupkg.sha512" }, - "Microsoft.Extensions.FileProviders.Abstractions/9.0.6": { + "Microsoft.Extensions.FileProviders.Abstractions/9.0.10": { "type": "package", "serviceable": true, - "sha512": "sha512-q9FPkSGVA9ipI255p3PBAvWNXas5Tzjyp/DwYSwT+46mIFw9fWZahsF6vHpoxLt5/vtANotH2sAm7HunuFIx9g==", - "path": "microsoft.extensions.fileproviders.abstractions/9.0.6", - "hashPath": "microsoft.extensions.fileproviders.abstractions.9.0.6.nupkg.sha512" + "sha512": "sha512-3+cLxZKUWBbpfIXLLuKcEok9C91PsV1h5xxfUsEnLSXXLNMiPDfrhpb1xajNFcejFPs9Ck/Fi3z71hYDqFBwYg==", + "path": "microsoft.extensions.fileproviders.abstractions/9.0.10", + "hashPath": "microsoft.extensions.fileproviders.abstractions.9.0.10.nupkg.sha512" }, - "Microsoft.Extensions.FileProviders.Physical/9.0.6": { + "Microsoft.Extensions.FileProviders.Physical/9.0.10": { "type": "package", "serviceable": true, - "sha512": "sha512-l+dFA0NRl90vSIiJNy5d7V0kpTEOWHTqbgoWYzlTwF5uiM5sWJ953haaELKE05jkyJdnemVTnqjrlgo4wo7oyg==", - "path": "microsoft.extensions.fileproviders.physical/9.0.6", - "hashPath": "microsoft.extensions.fileproviders.physical.9.0.6.nupkg.sha512" + "sha512": "sha512-Eg3YOEMpHWZzAgPD9YvGkQSv97AtG3II6maRQV/voDRORh4bRiyl0mVtT2PKnu1JoD9rJeYgjGCwRvVWMBaqgQ==", + "path": "microsoft.extensions.fileproviders.physical/9.0.10", + "hashPath": "microsoft.extensions.fileproviders.physical.9.0.10.nupkg.sha512" }, - "Microsoft.Extensions.FileSystemGlobbing/9.0.6": { + "Microsoft.Extensions.FileSystemGlobbing/9.0.10": { "type": "package", "serviceable": true, - "sha512": "sha512-1HJCAbwukNEoYbHgHbKHmenU0V/0huw8+i7Qtf5rLUG1E+3kEwRJQxpwD3wbTEagIgPSQisNgJTvmUX9yYVc6g==", - "path": "microsoft.extensions.filesystemglobbing/9.0.6", - "hashPath": "microsoft.extensions.filesystemglobbing.9.0.6.nupkg.sha512" + "sha512": "sha512-KdZAM2YMYBipVp/4tSEWPLnrocd17SL4iaXdgXjR5/nheBXbfR5QfPWYoTyh6C6IW3uKR7TRMwQr2qCvtaCTiA==", + "path": "microsoft.extensions.filesystemglobbing/9.0.10", + "hashPath": "microsoft.extensions.filesystemglobbing.9.0.10.nupkg.sha512" }, - "Microsoft.Extensions.Primitives/9.0.6": { + "Microsoft.Extensions.Primitives/9.0.10": { "type": "package", "serviceable": true, - "sha512": "sha512-BHniU24QV67qp1pJknqYSofAPYGmijGI8D+ci9yfw33iuFdyOeB9lWTg78ThyYLyQwZw3s0vZ36VMb0MqbUuLw==", - "path": "microsoft.extensions.primitives/9.0.6", - "hashPath": "microsoft.extensions.primitives.9.0.6.nupkg.sha512" + "sha512": "sha512-3pl8D1O5ZwMpDkZAT2uXrhQ6NipkwEgDLMFuURiHTf72TvkoMP61QYH3Vk1yrzVHnHBdNZk3cQACz8Zc7YGNhQ==", + "path": "microsoft.extensions.primitives/9.0.10", + "hashPath": "microsoft.extensions.primitives.9.0.10.nupkg.sha512" }, "Newtonsoft.Json/13.0.3": { "type": "package", diff --git a/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.dll b/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.dll new file mode 100644 index 0000000..d497599 Binary files /dev/null and b/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.dll differ diff --git a/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.pdb b/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.pdb new file mode 100644 index 0000000..80dc99b Binary files /dev/null and b/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.pdb differ diff --git a/Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.runtimeconfig.json b/Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.runtimeconfig.json similarity index 100% rename from Tools/NetworkProtocol/Fantasy.Tools.NetworkProtocol.runtimeconfig.json rename to Tools/ProtocolExportTool/Fantasy.Tools.NetworkProtocol.runtimeconfig.json diff --git a/Tools/NetworkProtocol/Microsoft.Extensions.Configuration.Abstractions.dll b/Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.Abstractions.dll similarity index 70% rename from Tools/NetworkProtocol/Microsoft.Extensions.Configuration.Abstractions.dll rename to Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.Abstractions.dll index e8f0c56..e2e531d 100644 Binary files a/Tools/NetworkProtocol/Microsoft.Extensions.Configuration.Abstractions.dll and b/Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/Tools/NetworkProtocol/Microsoft.Extensions.Configuration.FileExtensions.dll b/Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.FileExtensions.dll similarity index 65% rename from Tools/NetworkProtocol/Microsoft.Extensions.Configuration.FileExtensions.dll rename to Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.FileExtensions.dll index fa95e40..c213130 100644 Binary files a/Tools/NetworkProtocol/Microsoft.Extensions.Configuration.FileExtensions.dll and b/Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.FileExtensions.dll differ diff --git a/Tools/NetworkProtocol/Microsoft.Extensions.Configuration.Json.dll b/Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.Json.dll similarity index 64% rename from Tools/NetworkProtocol/Microsoft.Extensions.Configuration.Json.dll rename to Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.Json.dll index d0a3fb5..8e5b407 100644 Binary files a/Tools/NetworkProtocol/Microsoft.Extensions.Configuration.Json.dll and b/Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.Json.dll differ diff --git a/Tools/NetworkProtocol/Microsoft.Extensions.Configuration.dll b/Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.dll similarity index 76% rename from Tools/NetworkProtocol/Microsoft.Extensions.Configuration.dll rename to Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.dll index f40bb41..738ad85 100644 Binary files a/Tools/NetworkProtocol/Microsoft.Extensions.Configuration.dll and b/Tools/ProtocolExportTool/Microsoft.Extensions.Configuration.dll differ diff --git a/Tools/NetworkProtocol/Microsoft.Extensions.FileProviders.Abstractions.dll b/Tools/ProtocolExportTool/Microsoft.Extensions.FileProviders.Abstractions.dll similarity index 68% rename from Tools/NetworkProtocol/Microsoft.Extensions.FileProviders.Abstractions.dll rename to Tools/ProtocolExportTool/Microsoft.Extensions.FileProviders.Abstractions.dll index 7661f9a..b1a53fe 100644 Binary files a/Tools/NetworkProtocol/Microsoft.Extensions.FileProviders.Abstractions.dll and b/Tools/ProtocolExportTool/Microsoft.Extensions.FileProviders.Abstractions.dll differ diff --git a/Tools/NetworkProtocol/Microsoft.Extensions.FileProviders.Physical.dll b/Tools/ProtocolExportTool/Microsoft.Extensions.FileProviders.Physical.dll similarity index 80% rename from Tools/NetworkProtocol/Microsoft.Extensions.FileProviders.Physical.dll rename to Tools/ProtocolExportTool/Microsoft.Extensions.FileProviders.Physical.dll index f272fc2..43ec283 100644 Binary files a/Tools/NetworkProtocol/Microsoft.Extensions.FileProviders.Physical.dll and b/Tools/ProtocolExportTool/Microsoft.Extensions.FileProviders.Physical.dll differ diff --git a/Tools/NetworkProtocol/Microsoft.Extensions.FileSystemGlobbing.dll b/Tools/ProtocolExportTool/Microsoft.Extensions.FileSystemGlobbing.dll similarity index 78% rename from Tools/NetworkProtocol/Microsoft.Extensions.FileSystemGlobbing.dll rename to Tools/ProtocolExportTool/Microsoft.Extensions.FileSystemGlobbing.dll index d2c4b72..30731a4 100644 Binary files a/Tools/NetworkProtocol/Microsoft.Extensions.FileSystemGlobbing.dll and b/Tools/ProtocolExportTool/Microsoft.Extensions.FileSystemGlobbing.dll differ diff --git a/Tools/NetworkProtocol/Microsoft.Extensions.Primitives.dll b/Tools/ProtocolExportTool/Microsoft.Extensions.Primitives.dll similarity index 79% rename from Tools/NetworkProtocol/Microsoft.Extensions.Primitives.dll rename to Tools/ProtocolExportTool/Microsoft.Extensions.Primitives.dll index b2aa82b..c22ff4d 100644 Binary files a/Tools/NetworkProtocol/Microsoft.Extensions.Primitives.dll and b/Tools/ProtocolExportTool/Microsoft.Extensions.Primitives.dll differ diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Template.txt b/Tools/ProtocolExportTool/NetworkProtocolTemplate.txt similarity index 93% rename from Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Template.txt rename to Tools/ProtocolExportTool/NetworkProtocolTemplate.txt index 6eb76c5..37c9df6 100644 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Template.txt +++ b/Tools/ProtocolExportTool/NetworkProtocolTemplate.txt @@ -1,6 +1,7 @@ #if SERVER using ProtoBuf; (UsingNamespace) +using System; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using Fantasy; @@ -16,10 +17,11 @@ using Fantasy.Serialize; #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. #pragma warning disable CS8618 -namespace NBC -{ +namespace Fantasy +{ #else using ProtoBuf; +using System; (UsingNamespace) using System.Collections.Generic; using Fantasy; @@ -30,4 +32,4 @@ using Fantasy.Serialize; namespace Fantasy { #endif -(Content)} \ No newline at end of file +(Content)} diff --git a/Tools/NetworkProtocol/Newtonsoft.Json.dll b/Tools/ProtocolExportTool/Newtonsoft.Json.dll similarity index 100% rename from Tools/NetworkProtocol/Newtonsoft.Json.dll rename to Tools/ProtocolExportTool/Newtonsoft.Json.dll diff --git a/Tools/NetworkProtocol/Run.bat b/Tools/ProtocolExportTool/Run.bat similarity index 100% rename from Tools/NetworkProtocol/Run.bat rename to Tools/ProtocolExportTool/Run.bat diff --git a/Tools/NetworkProtocol/Run.sh b/Tools/ProtocolExportTool/Run.sh similarity index 100% rename from Tools/NetworkProtocol/Run.sh rename to Tools/ProtocolExportTool/Run.sh diff --git a/Tools/NetworkProtocol/System.IO.Pipelines.dll b/Tools/ProtocolExportTool/System.IO.Pipelines.dll similarity index 91% rename from Tools/NetworkProtocol/System.IO.Pipelines.dll rename to Tools/ProtocolExportTool/System.IO.Pipelines.dll index 8c1c6e5..12160e0 100644 Binary files a/Tools/NetworkProtocol/System.IO.Pipelines.dll and b/Tools/ProtocolExportTool/System.IO.Pipelines.dll differ diff --git a/Tools/NetworkProtocol/System.Text.Encodings.Web.dll b/Tools/ProtocolExportTool/System.Text.Encodings.Web.dll similarity index 93% rename from Tools/NetworkProtocol/System.Text.Encodings.Web.dll rename to Tools/ProtocolExportTool/System.Text.Encodings.Web.dll index 5bf355c..596a73f 100644 Binary files a/Tools/NetworkProtocol/System.Text.Encodings.Web.dll and b/Tools/ProtocolExportTool/System.Text.Encodings.Web.dll differ diff --git a/Tools/NetworkProtocol/System.Text.Json.dll b/Tools/ProtocolExportTool/System.Text.Json.dll similarity index 90% rename from Tools/NetworkProtocol/System.Text.Json.dll rename to Tools/ProtocolExportTool/System.Text.Json.dll index 1b52175..66e9b6d 100644 Binary files a/Tools/NetworkProtocol/System.Text.Json.dll and b/Tools/ProtocolExportTool/System.Text.Json.dll differ diff --git a/Tools/ProtocolExportTool/__MACOSX/._Run.bat b/Tools/ProtocolExportTool/__MACOSX/._Run.bat new file mode 100644 index 0000000..9747896 Binary files /dev/null and b/Tools/ProtocolExportTool/__MACOSX/._Run.bat differ diff --git a/Tools/ProtocolExportTool/__MACOSX/._Run.sh b/Tools/ProtocolExportTool/__MACOSX/._Run.sh new file mode 100644 index 0000000..cb3996a Binary files /dev/null and b/Tools/ProtocolExportTool/__MACOSX/._Run.sh differ diff --git a/Tools/ProtocolExportTool/__MACOSX/runtimes/._.DS_Store b/Tools/ProtocolExportTool/__MACOSX/runtimes/._.DS_Store new file mode 100644 index 0000000..a5b28df Binary files /dev/null and b/Tools/ProtocolExportTool/__MACOSX/runtimes/._.DS_Store differ diff --git a/Tools/ProtocolExportTool/__MACOSX/runtimes/browser/._.DS_Store b/Tools/ProtocolExportTool/__MACOSX/runtimes/browser/._.DS_Store new file mode 100644 index 0000000..a5b28df Binary files /dev/null and b/Tools/ProtocolExportTool/__MACOSX/runtimes/browser/._.DS_Store differ diff --git a/Tools/ProtocolExportTool/__MACOSX/runtimes/browser/lib/._.DS_Store b/Tools/ProtocolExportTool/__MACOSX/runtimes/browser/lib/._.DS_Store new file mode 100644 index 0000000..a5b28df Binary files /dev/null and b/Tools/ProtocolExportTool/__MACOSX/runtimes/browser/lib/._.DS_Store differ diff --git a/Tools/ProtocolExportTool/runtimes/.DS_Store b/Tools/ProtocolExportTool/runtimes/.DS_Store new file mode 100644 index 0000000..142ee7e Binary files /dev/null and b/Tools/ProtocolExportTool/runtimes/.DS_Store differ diff --git a/Tools/ProtocolExportTool/runtimes/browser/.DS_Store b/Tools/ProtocolExportTool/runtimes/browser/.DS_Store new file mode 100644 index 0000000..3cc62a8 Binary files /dev/null and b/Tools/ProtocolExportTool/runtimes/browser/.DS_Store differ diff --git a/Tools/ProtocolExportTool/runtimes/browser/lib/.DS_Store b/Tools/ProtocolExportTool/runtimes/browser/lib/.DS_Store new file mode 100644 index 0000000..6fb1349 Binary files /dev/null and b/Tools/ProtocolExportTool/runtimes/browser/lib/.DS_Store differ diff --git a/Tools/NetworkProtocol/runtimes/browser/lib/net8.0/System.Text.Encodings.Web.dll b/Tools/ProtocolExportTool/runtimes/browser/lib/net8.0/System.Text.Encodings.Web.dll similarity index 90% rename from Tools/NetworkProtocol/runtimes/browser/lib/net8.0/System.Text.Encodings.Web.dll rename to Tools/ProtocolExportTool/runtimes/browser/lib/net8.0/System.Text.Encodings.Web.dll index 0786a1d..0e075ed 100644 Binary files a/Tools/NetworkProtocol/runtimes/browser/lib/net8.0/System.Text.Encodings.Web.dll and b/Tools/ProtocolExportTool/runtimes/browser/lib/net8.0/System.Text.Encodings.Web.dll differ diff --git a/Tools/ProtocolTest/Config.json b/Tools/ProtocolTest/Config.json deleted file mode 100644 index 453faa6..0000000 --- a/Tools/ProtocolTest/Config.json +++ /dev/null @@ -1 +0,0 @@ -{"Server":"127.0.0.1:20001","Heartbeat":5,"ProtocolScriptPath":"D:\\myself\\Games\\Fishing2\\Assets\\Scripts\\Generate\\NetworkProtocol","Accounts":["test002","test003"]} \ No newline at end of file diff --git a/Tools/ProtocolTest/FantasyNetTest.deps.json b/Tools/ProtocolTest/FantasyNetTest.deps.json deleted file mode 100644 index 9964817..0000000 --- a/Tools/ProtocolTest/FantasyNetTest.deps.json +++ /dev/null @@ -1,429 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETCoreApp,Version=v8.0", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETCoreApp,Version=v8.0": { - "FantasyNetTest/1.0.0": { - "dependencies": { - "Microsoft.CodeAnalysis.CSharp": "4.14.0", - "Microsoft.CodeAnalysis.Scripting": "4.14.0", - "Newtonsoft.Json": "13.0.3", - "System.Buffers": "4.6.1", - "System.IO.Pipelines": "9.0.8" - }, - "runtime": { - "FantasyNetTest.dll": {} - } - }, - "Microsoft.CodeAnalysis.Analyzers/3.11.0": {}, - "Microsoft.CodeAnalysis.Common/4.14.0": { - "dependencies": { - "Microsoft.CodeAnalysis.Analyzers": "3.11.0", - "System.Collections.Immutable": "9.0.0", - "System.Reflection.Metadata": "9.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.CodeAnalysis.dll": { - "assemblyVersion": "4.14.0.0", - "fileVersion": "4.1400.25.26210" - } - }, - "resources": { - "lib/net8.0/cs/Microsoft.CodeAnalysis.resources.dll": { - "locale": "cs" - }, - "lib/net8.0/de/Microsoft.CodeAnalysis.resources.dll": { - "locale": "de" - }, - "lib/net8.0/es/Microsoft.CodeAnalysis.resources.dll": { - "locale": "es" - }, - "lib/net8.0/fr/Microsoft.CodeAnalysis.resources.dll": { - "locale": "fr" - }, - "lib/net8.0/it/Microsoft.CodeAnalysis.resources.dll": { - "locale": "it" - }, - "lib/net8.0/ja/Microsoft.CodeAnalysis.resources.dll": { - "locale": "ja" - }, - "lib/net8.0/ko/Microsoft.CodeAnalysis.resources.dll": { - "locale": "ko" - }, - "lib/net8.0/pl/Microsoft.CodeAnalysis.resources.dll": { - "locale": "pl" - }, - "lib/net8.0/pt-BR/Microsoft.CodeAnalysis.resources.dll": { - "locale": "pt-BR" - }, - "lib/net8.0/ru/Microsoft.CodeAnalysis.resources.dll": { - "locale": "ru" - }, - "lib/net8.0/tr/Microsoft.CodeAnalysis.resources.dll": { - "locale": "tr" - }, - "lib/net8.0/zh-Hans/Microsoft.CodeAnalysis.resources.dll": { - "locale": "zh-Hans" - }, - "lib/net8.0/zh-Hant/Microsoft.CodeAnalysis.resources.dll": { - "locale": "zh-Hant" - } - } - }, - "Microsoft.CodeAnalysis.CSharp/4.14.0": { - "dependencies": { - "Microsoft.CodeAnalysis.Analyzers": "3.11.0", - "Microsoft.CodeAnalysis.Common": "4.14.0", - "System.Collections.Immutable": "9.0.0", - "System.Reflection.Metadata": "9.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.CodeAnalysis.CSharp.dll": { - "assemblyVersion": "4.14.0.0", - "fileVersion": "4.1400.25.26210" - } - }, - "resources": { - "lib/net8.0/cs/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "cs" - }, - "lib/net8.0/de/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "de" - }, - "lib/net8.0/es/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "es" - }, - "lib/net8.0/fr/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "fr" - }, - "lib/net8.0/it/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "it" - }, - "lib/net8.0/ja/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "ja" - }, - "lib/net8.0/ko/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "ko" - }, - "lib/net8.0/pl/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "pl" - }, - "lib/net8.0/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "pt-BR" - }, - "lib/net8.0/ru/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "ru" - }, - "lib/net8.0/tr/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "tr" - }, - "lib/net8.0/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "zh-Hans" - }, - "lib/net8.0/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll": { - "locale": "zh-Hant" - } - } - }, - "Microsoft.CodeAnalysis.CSharp.Scripting/4.14.0": { - "dependencies": { - "Microsoft.CSharp": "4.7.0", - "Microsoft.CodeAnalysis.Analyzers": "3.11.0", - "Microsoft.CodeAnalysis.CSharp": "4.14.0", - "Microsoft.CodeAnalysis.Common": "4.14.0", - "Microsoft.CodeAnalysis.Scripting.Common": "4.14.0", - "System.Collections.Immutable": "9.0.0", - "System.Reflection.Metadata": "9.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.CodeAnalysis.CSharp.Scripting.dll": { - "assemblyVersion": "4.14.0.0", - "fileVersion": "4.1400.25.26210" - } - }, - "resources": { - "lib/net8.0/cs/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "cs" - }, - "lib/net8.0/de/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "de" - }, - "lib/net8.0/es/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "es" - }, - "lib/net8.0/fr/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "fr" - }, - "lib/net8.0/it/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "it" - }, - "lib/net8.0/ja/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "ja" - }, - "lib/net8.0/ko/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "ko" - }, - "lib/net8.0/pl/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "pl" - }, - "lib/net8.0/pt-BR/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "pt-BR" - }, - "lib/net8.0/ru/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "ru" - }, - "lib/net8.0/tr/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "tr" - }, - "lib/net8.0/zh-Hans/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "zh-Hans" - }, - "lib/net8.0/zh-Hant/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll": { - "locale": "zh-Hant" - } - } - }, - "Microsoft.CodeAnalysis.Scripting/4.14.0": { - "dependencies": { - "Microsoft.CSharp": "4.7.0", - "Microsoft.CodeAnalysis.Analyzers": "3.11.0", - "Microsoft.CodeAnalysis.CSharp.Scripting": "4.14.0", - "System.Buffers": "4.6.1", - "System.Collections.Immutable": "9.0.0", - "System.Memory": "4.5.5", - "System.Numerics.Vectors": "4.5.0", - "System.Reflection.Metadata": "9.0.0", - "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encoding.CodePages": "7.0.0", - "System.Threading.Tasks.Extensions": "4.5.4" - } - }, - "Microsoft.CodeAnalysis.Scripting.Common/4.14.0": { - "dependencies": { - "Microsoft.CodeAnalysis.Analyzers": "3.11.0", - "Microsoft.CodeAnalysis.Common": "4.14.0", - "System.Collections.Immutable": "9.0.0", - "System.Reflection.Metadata": "9.0.0" - }, - "runtime": { - "lib/net8.0/Microsoft.CodeAnalysis.Scripting.dll": { - "assemblyVersion": "4.14.0.0", - "fileVersion": "4.1400.25.26210" - } - }, - "resources": { - "lib/net8.0/cs/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "cs" - }, - "lib/net8.0/de/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "de" - }, - "lib/net8.0/es/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "es" - }, - "lib/net8.0/fr/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "fr" - }, - "lib/net8.0/it/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "it" - }, - "lib/net8.0/ja/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "ja" - }, - "lib/net8.0/ko/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "ko" - }, - "lib/net8.0/pl/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "pl" - }, - "lib/net8.0/pt-BR/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "pt-BR" - }, - "lib/net8.0/ru/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "ru" - }, - "lib/net8.0/tr/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "tr" - }, - "lib/net8.0/zh-Hans/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "zh-Hans" - }, - "lib/net8.0/zh-Hant/Microsoft.CodeAnalysis.Scripting.resources.dll": { - "locale": "zh-Hant" - } - } - }, - "Microsoft.CSharp/4.7.0": {}, - "Newtonsoft.Json/13.0.3": { - "runtime": { - "lib/net6.0/Newtonsoft.Json.dll": { - "assemblyVersion": "13.0.0.0", - "fileVersion": "13.0.3.27908" - } - } - }, - "System.Buffers/4.6.1": {}, - "System.Collections.Immutable/9.0.0": { - "runtime": { - "lib/net8.0/System.Collections.Immutable.dll": { - "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.24.52809" - } - } - }, - "System.IO.Pipelines/9.0.8": { - "runtime": { - "lib/net8.0/System.IO.Pipelines.dll": { - "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.825.36511" - } - } - }, - "System.Memory/4.5.5": {}, - "System.Numerics.Vectors/4.5.0": {}, - "System.Reflection.Metadata/9.0.0": { - "dependencies": { - "System.Collections.Immutable": "9.0.0" - }, - "runtime": { - "lib/net8.0/System.Reflection.Metadata.dll": { - "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.24.52809" - } - } - }, - "System.Runtime.CompilerServices.Unsafe/6.0.0": {}, - "System.Text.Encoding.CodePages/7.0.0": {}, - "System.Threading.Tasks.Extensions/4.5.4": {} - } - }, - "libraries": { - "FantasyNetTest/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - }, - "Microsoft.CodeAnalysis.Analyzers/3.11.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-v/EW3UE8/lbEYHoC2Qq7AR/DnmvpgdtAMndfQNmpuIMx/Mto8L5JnuCfdBYtgvalQOtfNCnxFejxuRrryvUTsg==", - "path": "microsoft.codeanalysis.analyzers/3.11.0", - "hashPath": "microsoft.codeanalysis.analyzers.3.11.0.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.Common/4.14.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-PC3tuwZYnC+idaPuoC/AZpEdwrtX7qFpmnrfQkgobGIWiYmGi5MCRtl5mx6QrfMGQpK78X2lfIEoZDLg/qnuHg==", - "path": "microsoft.codeanalysis.common/4.14.0", - "hashPath": "microsoft.codeanalysis.common.4.14.0.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.CSharp/4.14.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-568a6wcTivauIhbeWcCwfWwIn7UV7MeHEBvFB2uzGIpM2OhJ4eM/FZ8KS0yhPoNxnSpjGzz7x7CIjTxhslojQA==", - "path": "microsoft.codeanalysis.csharp/4.14.0", - "hashPath": "microsoft.codeanalysis.csharp.4.14.0.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.CSharp.Scripting/4.14.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-Ji6L9o7JY7tVMthoqInsksPLDE0tfAvJURC9Xe038N4FyXH2wKS4K/sG/bDbdJoK1oFIOLtyPEe2POJ+/AeGZg==", - "path": "microsoft.codeanalysis.csharp.scripting/4.14.0", - "hashPath": "microsoft.codeanalysis.csharp.scripting.4.14.0.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.Scripting/4.14.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-GE6S7aRRDgLfnzg5NWbKRqu1I0Jwdh1IPM3IxANRgLXtYQPqVr9FrtlNpnvMALSqMh0frPuB09+ZAHOIdnYUoQ==", - "path": "microsoft.codeanalysis.scripting/4.14.0", - "hashPath": "microsoft.codeanalysis.scripting.4.14.0.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.Scripting.Common/4.14.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-YRFoYZQU4VPlB+Xwwtj8gIHXxMyuhGXyj207IWHcsSNaJtW83My0FGv6jtN9gC/HkxgjdMYJORPjBwUx3+FVjQ==", - "path": "microsoft.codeanalysis.scripting.common/4.14.0", - "hashPath": "microsoft.codeanalysis.scripting.common.4.14.0.nupkg.sha512" - }, - "Microsoft.CSharp/4.7.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==", - "path": "microsoft.csharp/4.7.0", - "hashPath": "microsoft.csharp.4.7.0.nupkg.sha512" - }, - "Newtonsoft.Json/13.0.3": { - "type": "package", - "serviceable": true, - "sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", - "path": "newtonsoft.json/13.0.3", - "hashPath": "newtonsoft.json.13.0.3.nupkg.sha512" - }, - "System.Buffers/4.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==", - "path": "system.buffers/4.6.1", - "hashPath": "system.buffers.4.6.1.nupkg.sha512" - }, - "System.Collections.Immutable/9.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w==", - "path": "system.collections.immutable/9.0.0", - "hashPath": "system.collections.immutable.9.0.0.nupkg.sha512" - }, - "System.IO.Pipelines/9.0.8": { - "type": "package", - "serviceable": true, - "sha512": "sha512-6vPmJt73mgUo1gzc/OcXlJvClz/2jxZ4TQPRfriVaLoGRH2mye530D9WHJYbFQRNMxF3PWCoeofsFdCyN7fLzA==", - "path": "system.io.pipelines/9.0.8", - "hashPath": "system.io.pipelines.9.0.8.nupkg.sha512" - }, - "System.Memory/4.5.5": { - "type": "package", - "serviceable": true, - "sha512": "sha512-XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", - "path": "system.memory/4.5.5", - "hashPath": "system.memory.4.5.5.nupkg.sha512" - }, - "System.Numerics.Vectors/4.5.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==", - "path": "system.numerics.vectors/4.5.0", - "hashPath": "system.numerics.vectors.4.5.0.nupkg.sha512" - }, - "System.Reflection.Metadata/9.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ANiqLu3DxW9kol/hMmTWbt3414t9ftdIuiIU7j80okq2YzAueo120M442xk1kDJWtmZTqWQn7wHDvMRipVOEOQ==", - "path": "system.reflection.metadata/9.0.0", - "hashPath": "system.reflection.metadata.9.0.0.nupkg.sha512" - }, - "System.Runtime.CompilerServices.Unsafe/6.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==", - "path": "system.runtime.compilerservices.unsafe/6.0.0", - "hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512" - }, - "System.Text.Encoding.CodePages/7.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-LSyCblMpvOe0N3E+8e0skHcrIhgV2huaNcjUUEa8hRtgEAm36aGkRoC8Jxlb6Ra6GSfF29ftduPNywin8XolzQ==", - "path": "system.text.encoding.codepages/7.0.0", - "hashPath": "system.text.encoding.codepages.7.0.0.nupkg.sha512" - }, - "System.Threading.Tasks.Extensions/4.5.4": { - "type": "package", - "serviceable": true, - "sha512": "sha512-zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", - "path": "system.threading.tasks.extensions/4.5.4", - "hashPath": "system.threading.tasks.extensions.4.5.4.nupkg.sha512" - } - } -} \ No newline at end of file diff --git a/Tools/ProtocolTest/FantasyNetTest.dll b/Tools/ProtocolTest/FantasyNetTest.dll deleted file mode 100644 index 12e8dba..0000000 Binary files a/Tools/ProtocolTest/FantasyNetTest.dll and /dev/null differ diff --git a/Tools/ProtocolTest/FantasyNetTest.exe b/Tools/ProtocolTest/FantasyNetTest.exe deleted file mode 100644 index ff81337..0000000 Binary files a/Tools/ProtocolTest/FantasyNetTest.exe and /dev/null differ diff --git a/Tools/ProtocolTest/FantasyNetTest.pdb b/Tools/ProtocolTest/FantasyNetTest.pdb deleted file mode 100644 index e1e2b2d..0000000 Binary files a/Tools/ProtocolTest/FantasyNetTest.pdb and /dev/null differ diff --git a/Tools/ProtocolTest/Microsoft.CodeAnalysis.CSharp.Scripting.dll b/Tools/ProtocolTest/Microsoft.CodeAnalysis.CSharp.Scripting.dll deleted file mode 100644 index 174d05b..0000000 Binary files a/Tools/ProtocolTest/Microsoft.CodeAnalysis.CSharp.Scripting.dll and /dev/null differ diff --git a/Tools/ProtocolTest/Microsoft.CodeAnalysis.CSharp.dll b/Tools/ProtocolTest/Microsoft.CodeAnalysis.CSharp.dll deleted file mode 100644 index e2821ad..0000000 Binary files a/Tools/ProtocolTest/Microsoft.CodeAnalysis.CSharp.dll and /dev/null differ diff --git a/Tools/ProtocolTest/Microsoft.CodeAnalysis.Scripting.dll b/Tools/ProtocolTest/Microsoft.CodeAnalysis.Scripting.dll deleted file mode 100644 index 6c10588..0000000 Binary files a/Tools/ProtocolTest/Microsoft.CodeAnalysis.Scripting.dll and /dev/null differ diff --git a/Tools/ProtocolTest/Microsoft.CodeAnalysis.dll b/Tools/ProtocolTest/Microsoft.CodeAnalysis.dll deleted file mode 100644 index d3f985e..0000000 Binary files a/Tools/ProtocolTest/Microsoft.CodeAnalysis.dll and /dev/null differ diff --git a/Tools/ProtocolTest/Newtonsoft.Json.dll b/Tools/ProtocolTest/Newtonsoft.Json.dll deleted file mode 100644 index d035c38..0000000 Binary files a/Tools/ProtocolTest/Newtonsoft.Json.dll and /dev/null differ diff --git a/Tools/ProtocolTest/Protocol/C2A_LoginRequest b/Tools/ProtocolTest/Protocol/C2A_LoginRequest deleted file mode 100644 index cb9a3d0..0000000 --- a/Tools/ProtocolTest/Protocol/C2A_LoginRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"Username":"test002","Password":"test002","LoginType":1,"Region":3} \ No newline at end of file diff --git a/Tools/ProtocolTest/Protocol/C2Chat_SendMessageRequest b/Tools/ProtocolTest/Protocol/C2Chat_SendMessageRequest deleted file mode 100644 index c3ceae6..0000000 --- a/Tools/ProtocolTest/Protocol/C2Chat_SendMessageRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Type":1,"Message":"\u4F1A\u8986\u76D644545","Target":0} \ No newline at end of file diff --git a/Tools/ProtocolTest/System.Collections.Immutable.dll b/Tools/ProtocolTest/System.Collections.Immutable.dll deleted file mode 100644 index 9db8140..0000000 Binary files a/Tools/ProtocolTest/System.Collections.Immutable.dll and /dev/null differ diff --git a/Tools/ProtocolTest/System.IO.Pipelines.dll b/Tools/ProtocolTest/System.IO.Pipelines.dll deleted file mode 100644 index db15671..0000000 Binary files a/Tools/ProtocolTest/System.IO.Pipelines.dll and /dev/null differ diff --git a/Tools/ProtocolTest/System.Reflection.Metadata.dll b/Tools/ProtocolTest/System.Reflection.Metadata.dll deleted file mode 100644 index 2366da2..0000000 Binary files a/Tools/ProtocolTest/System.Reflection.Metadata.dll and /dev/null differ diff --git a/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index 99388a6..0000000 Binary files a/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 67560d7..0000000 Binary files a/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index c1aa507..0000000 Binary files a/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 155bcce..0000000 Binary files a/Tools/ProtocolTest/cs/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index e7f5900..0000000 Binary files a/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index daca134..0000000 Binary files a/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index 01ff784..0000000 Binary files a/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 0613dde..0000000 Binary files a/Tools/ProtocolTest/de/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index 73c3faa..0000000 Binary files a/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 6528338..0000000 Binary files a/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index 5c227db..0000000 Binary files a/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 1d20ff2..0000000 Binary files a/Tools/ProtocolTest/es/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index 7f94019..0000000 Binary files a/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index d5d4b24..0000000 Binary files a/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index 604ebf0..0000000 Binary files a/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index e7aee2a..0000000 Binary files a/Tools/ProtocolTest/fr/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index ef0dc8f..0000000 Binary files a/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 57a91a7..0000000 Binary files a/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index da42e6f..0000000 Binary files a/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 78cb09d..0000000 Binary files a/Tools/ProtocolTest/it/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index ef6374e..0000000 Binary files a/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index a301df0..0000000 Binary files a/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index 5fb2d12..0000000 Binary files a/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 77a390c..0000000 Binary files a/Tools/ProtocolTest/ja/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index 0379941..0000000 Binary files a/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 5108385..0000000 Binary files a/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index 9dd94c4..0000000 Binary files a/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 3c56215..0000000 Binary files a/Tools/ProtocolTest/ko/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index 0834667..0000000 Binary files a/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 965c984..0000000 Binary files a/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index 71ddd65..0000000 Binary files a/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 2915250..0000000 Binary files a/Tools/ProtocolTest/pl/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index eaa55bf..0000000 Binary files a/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 5afc260..0000000 Binary files a/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index f9526b3..0000000 Binary files a/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 700e2aa..0000000 Binary files a/Tools/ProtocolTest/pt-BR/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index 4f8d608..0000000 Binary files a/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index b4138f4..0000000 Binary files a/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index e74676e..0000000 Binary files a/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 2cf63e5..0000000 Binary files a/Tools/ProtocolTest/ru/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/test002/Protocol/C2Chat_JoinChannelRequest b/Tools/ProtocolTest/test002/Protocol/C2Chat_JoinChannelRequest deleted file mode 100644 index a38fa2c..0000000 --- a/Tools/ProtocolTest/test002/Protocol/C2Chat_JoinChannelRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Target":331859667959676928} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2Chat_SendMessageRequest b/Tools/ProtocolTest/test002/Protocol/C2Chat_SendMessageRequest deleted file mode 100644 index 06f15f6..0000000 --- a/Tools/ProtocolTest/test002/Protocol/C2Chat_SendMessageRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Type":1,"Message":"11111\u5927\u6CD5\u5E08\u7684\u65B9\u6CD5343411","Target":323063059205849090} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2S_CreateChannelRequest b/Tools/ProtocolTest/test002/Protocol/C2S_CreateChannelRequest deleted file mode 100644 index 5d8d033..0000000 --- a/Tools/ProtocolTest/test002/Protocol/C2S_CreateChannelRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Name":"34535"} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2S_DeleteMailRequest b/Tools/ProtocolTest/test002/Protocol/C2S_DeleteMailRequest deleted file mode 100644 index 980ca7a..0000000 --- a/Tools/ProtocolTest/test002/Protocol/C2S_DeleteMailRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Id":331929091475505154} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2S_GetConversationsRequest b/Tools/ProtocolTest/test002/Protocol/C2S_GetConversationsRequest deleted file mode 100644 index dcc6071..0000000 --- a/Tools/ProtocolTest/test002/Protocol/C2S_GetConversationsRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2S_JoinChannelRequest b/Tools/ProtocolTest/test002/Protocol/C2S_JoinChannelRequest deleted file mode 100644 index 67281cd..0000000 --- a/Tools/ProtocolTest/test002/Protocol/C2S_JoinChannelRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Target":334918114171158528} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2S_SendMailRequest b/Tools/ProtocolTest/test002/Protocol/C2S_SendMailRequest deleted file mode 100644 index 429d3fa..0000000 --- a/Tools/ProtocolTest/test002/Protocol/C2S_SendMailRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Target":337951357380329486,"Content":"\u5206\u516C\u53F8\u7535\u996D\u9505\u7535\u996D\u9505"} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2S_SendMessageRequest b/Tools/ProtocolTest/test002/Protocol/C2S_SendMessageRequest deleted file mode 100644 index 5d79aaa..0000000 --- a/Tools/ProtocolTest/test002/Protocol/C2S_SendMessageRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Type":1,"Message":"\u90FD\u662F\u6CD5\u5E08\u6253\u53D1\u65AF\u8482\u82AC\u6492\u61C2\u6CD5\u5B88\u6CD53434","Target":323063059205849090} \ No newline at end of file diff --git a/Tools/ProtocolTest/test003/Protocol/C2Chat_GetOfflineMessageRequest b/Tools/ProtocolTest/test003/Protocol/C2Chat_GetOfflineMessageRequest deleted file mode 100644 index dcc6071..0000000 --- a/Tools/ProtocolTest/test003/Protocol/C2Chat_GetOfflineMessageRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002} \ No newline at end of file diff --git a/Tools/ProtocolTest/test003/Protocol/C2Chat_JoinChannelRequest b/Tools/ProtocolTest/test003/Protocol/C2Chat_JoinChannelRequest deleted file mode 100644 index a38fa2c..0000000 --- a/Tools/ProtocolTest/test003/Protocol/C2Chat_JoinChannelRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Target":331859667959676928} \ No newline at end of file diff --git a/Tools/ProtocolTest/test003/Protocol/C2Chat_SendMessageRequest b/Tools/ProtocolTest/test003/Protocol/C2Chat_SendMessageRequest deleted file mode 100644 index d2d6bae..0000000 --- a/Tools/ProtocolTest/test003/Protocol/C2Chat_SendMessageRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Type":1,"Message":"\u554A\u6536\u5230\u53D1\u65AF\u8482\u82AC334","Target":324468767642091522} \ No newline at end of file diff --git a/Tools/ProtocolTest/test003/Protocol/C2S_JoinChannelRequest b/Tools/ProtocolTest/test003/Protocol/C2S_JoinChannelRequest deleted file mode 100644 index 67281cd..0000000 --- a/Tools/ProtocolTest/test003/Protocol/C2S_JoinChannelRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Target":334918114171158528} \ No newline at end of file diff --git a/Tools/ProtocolTest/test003/Protocol/C2S_SendMailRequest b/Tools/ProtocolTest/test003/Protocol/C2S_SendMailRequest deleted file mode 100644 index 3d9c462..0000000 --- a/Tools/ProtocolTest/test003/Protocol/C2S_SendMailRequest +++ /dev/null @@ -1 +0,0 @@ -{"ResponseType":null,"RouteType":1002,"Target":324468767642091522,"Content":"\u7B2C\u4E09\u65B9\u7B2C\u4E09\u65B9\u4EE3\u53D1111"} \ No newline at end of file diff --git a/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index c15a0a6..0000000 Binary files a/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 7ca2e8f..0000000 Binary files a/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index fe7b73b..0000000 Binary files a/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 0f76b86..0000000 Binary files a/Tools/ProtocolTest/tr/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index f98895e..0000000 Binary files a/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 8c80a88..0000000 Binary files a/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index 94d4cf6..0000000 Binary files a/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index 52f232d..0000000 Binary files a/Tools/ProtocolTest/zh-Hans/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll b/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll deleted file mode 100644 index b80e414..0000000 Binary files a/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.CSharp.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll b/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll deleted file mode 100644 index 1936f8d..0000000 Binary files a/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.Scripting.resources.dll b/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.Scripting.resources.dll deleted file mode 100644 index eb462c8..0000000 Binary files a/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.Scripting.resources.dll and /dev/null differ diff --git a/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.resources.dll b/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.resources.dll deleted file mode 100644 index fe815c6..0000000 Binary files a/Tools/ProtocolTest/zh-Hant/Microsoft.CodeAnalysis.resources.dll and /dev/null differ diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Core/Base/ExportType.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Core/Base/ExportType.cs deleted file mode 100644 index fa2b818..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Core/Base/ExportType.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Fantasy.Tools.ConfigTable; - -/// -/// 导出类型枚举,用于标识不同类型的导出操作。 -/// -public enum ExportType -{ - /// - /// 无导出类型。 - /// - None = 0, - /// - /// 所有数据的增量导出Excel类型。 - /// - AllExcelIncrement = 1, - /// - /// 所有数据的全量导出Excel类型。 - /// - AllExcel = 2, - /// - /// 导出类型枚举的最大值,一定要放在最后。 - /// - Max, -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/CustomExport/ConstValueToConst.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/CustomExport/ConstValueToConst.cs deleted file mode 100644 index 88e7197..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/CustomExport/ConstValueToConst.cs +++ /dev/null @@ -1,158 +0,0 @@ -// using System; -// using System.Text; -// using Exporter.Excel; -// using Fantasy.Exporter; -// using OfficeOpenXml; -// -// namespace Exporter; -// -// public class ConstValueToConst : ACustomExport -// { -// public override void Run() -// { -// if (!ExcelExporter.LoadIgnoreExcel("#ConstValue", out var excelPackage)) -// { -// Log.Error("ConstValueToConst: Load Excel failed."); -// return; -// } -// -// var worksheet = excelPackage.Workbook.Worksheets[0]; -// -// var serverHotfixStrBuilder = new StringBuilder(); -// serverHotfixStrBuilder.AppendLine("namespace Fantasy\n{"); -// serverHotfixStrBuilder.AppendLine("\t// 生成器自动生成,请不要手动编辑,修改请在#ConstValue.xsl里。"); -// serverHotfixStrBuilder.AppendLine("\tpublic partial class ConstValueHotfix\n\t{"); -// -// var serverModelStrBuilder = new StringBuilder(); -// serverModelStrBuilder.AppendLine("namespace Fantasy\n{"); -// serverModelStrBuilder.AppendLine("\t// 生成器自动生成,请不要手动编辑。"); -// serverModelStrBuilder.AppendLine("\tpublic partial class ConstValue\n\t{"); -// -// var clientStrBuilder = new StringBuilder(); -// clientStrBuilder.AppendLine("namespace Fantasy\n{"); -// clientStrBuilder.AppendLine("\t// 生成器自动生成,请不要手动编辑。"); -// clientStrBuilder.AppendLine("\tpublic class ConstValue\n\t{"); -// -// for (var row = 2; row <= worksheet.Dimension.Rows; row++) -// { -// var first = worksheet.GetCellValue(row, 1); -// var second = worksheet.GetCellValue(row, 2); -// var lower = first?.ToLower() ?? ""; -// var isClient = lower.Contains("c"); -// var isServerModel = lower.Contains("sh"); -// var isServerHotfix = lower.Contains("sm"); -// -// if (string.IsNullOrEmpty(second)) -// { -// continue; -// } -// -// string str; -// -// if (second.StartsWith("#")) -// { -// str = $"\t\t// {second}"; -// clientStrBuilder.AppendLine(str); -// serverModelStrBuilder.AppendLine(str); -// serverHotfixStrBuilder.AppendLine(str); -// continue; -// } -// -// str = GetCodeStr(worksheet, row); -// -// if (isServerModel) -// { -// serverModelStrBuilder.AppendLine(str); -// } -// -// if (isServerHotfix) -// { -// serverHotfixStrBuilder.AppendLine(str); -// } -// -// if (isClient) -// { -// clientStrBuilder.AppendLine(str); -// } -// } -// -// clientStrBuilder.AppendLine("\t}\n}"); -// serverModelStrBuilder.AppendLine("\t}\n}"); -// serverHotfixStrBuilder.AppendLine("\t}\n}"); -// -// Write("ConstValue.cs", clientStrBuilder.ToString(), CustomExportType.Client); -// Write("ConstValue.cs", serverModelStrBuilder.ToString(), CustomExportType.Server); -// Write("ConstValueHotfix.cs", serverHotfixStrBuilder.ToString(),"../../Server/Hotfix/Generate/CustomExport123" ,CustomExportType.Server); -// } -// -// private static string GetCodeStr(ExcelWorksheet sheet, int row) -// { -// var typeStr = sheet.GetCellValue(row, 3); -// var name = sheet.GetCellValue(row, 2); -// var value = sheet.GetCellValue(row, 4); -// var desc = sheet.GetCellValue(row, 5); -// -// try -// { -// if (typeStr.Contains("[]") || typeStr.Contains("[,]")) -// { -// return $"\t\tpublic static readonly {typeStr} {name} = {DefaultValue(typeStr, value)}; // {desc}"; -// } -// -// if (typeStr.Contains("Vector")) -// { -// return $"\t\tpublic static readonly {typeStr} {name} = {DefaultValue(typeStr, value)}; // {desc}"; -// } -// -// return $"\t\tpublic const {typeStr} {name} = {DefaultValue(typeStr, value)}; // {desc}"; -// } -// catch (Exception e) -// { -// Log.Error($"{name} 常量导出异常 : {e}"); -// return ""; -// } -// } -// -// private static string DefaultValue(string type, string value) -// { -// switch (type) -// { -// case "byte[]": -// case "int[]": -// case "long[]": -// case "string[]": -// case "double[]": -// case "float[]": -// return $"new {type} {{{value}}}"; -// case "byte[,]": -// case "int[,]": -// case "long[,]": -// case "string[,]": -// case "float[,]": -// case "double[,]": -// return $"new {type} {{{value}}}"; -// case "int": -// case "bool": -// case "uint": -// case "long": -// case "double": -// return $"{value}"; -// case "float": -// return value[^1] == 'f' ? value : $"{value}f"; -// case "string": -// return $"\"{value}\""; -// case "Vector2": -// { -// var strings = value.Split(',', StringSplitOptions.TrimEntries); -// return $"new Vector2({strings[0]},{strings[1]})"; -// } -// case "Vector3": -// { -// var strings = value.Split(',', StringSplitOptions.TrimEntries); -// return $"new Vector3({strings[0]},{strings[1]},{strings[2]})"; -// } -// default: -// throw new Exception($"不支持此类型: {type}"); -// } -// } -// } \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/CustomExport/SceneTypeConfigToEnum.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/CustomExport/SceneTypeConfigToEnum.cs deleted file mode 100644 index 95904f4..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/CustomExport/SceneTypeConfigToEnum.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Text; -using Fantasy.Tools.ConfigTable; -using System.Collections.Generic; - -namespace Exporter; - -/// -/// 将场景类型配置表转换为枚举和字典的自定义导出类。 -/// -public class SceneTypeConfigToEnum : ACustomExport -{ - public override void Run() - { - var sceneType = new Dictionary(); - // 获取场景配置表的完整路径 - if (!Worksheets.TryGetValue("SceneTypeConfig", out var sceneTypeConfig)) - { - return; - } - for (var row = 3; row <= sceneTypeConfig.Dimension.Rows; row++) - { - var sceneTypeId = sceneTypeConfig.GetCellValue(row, 1); - var sceneTypeStr = sceneTypeConfig.GetCellValue(row, 2); - - if (string.IsNullOrEmpty(sceneTypeId) || string.IsNullOrEmpty(sceneTypeStr)) - { - continue; - } - - sceneType.Add(sceneTypeId, sceneTypeStr); - } - // 如果存在场景类型或场景子类型,执行导出操作 - if (sceneType.Count > 0) - { - Write(CustomExportType.Server, sceneType); - } - } - - private void Write(CustomExportType customExportType, Dictionary sceneTypes) - { - var strBuilder = new StringBuilder(); - var dicBuilder = new StringBuilder(); - // 添加命名空间和注释头部 - strBuilder.AppendLine("namespace Fantasy\n{"); - strBuilder.AppendLine("\t// 生成器自动生成,请不要手动编辑。"); - // 生成场景类型的静态类 - strBuilder.AppendLine("\tpublic static class SceneType\n\t{"); - dicBuilder.AppendLine("\n\t\tpublic static readonly Dictionary SceneTypeDic = new Dictionary()\n\t\t{"); - // 遍历场景类型字典,生成场景类型的常量和字典项 - foreach (var (sceneTypeId, sceneTypeStr) in sceneTypes) - { - dicBuilder.AppendLine($"\t\t\t{{ \"{sceneTypeStr}\", {sceneTypeId} }},"); - strBuilder.AppendLine($"\t\tpublic const int {sceneTypeStr} = {sceneTypeId};"); - } - // 添加场景类型字典尾部,合并到主字符串构建器中 - dicBuilder.AppendLine("\t\t};"); - strBuilder.Append(dicBuilder); - strBuilder.AppendLine("\t}\n}"); - // 调用外部方法将生成的代码写入文件 - Write("SceneType.cs", strBuilder.ToString(), customExportType); - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ConfigTableHelper.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ConfigTableHelper.cs deleted file mode 100644 index 7a13fa9..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ConfigTableHelper.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Fantasy.Serialize; - -#pragma warning disable CS8603 // Possible null reference return. - -namespace Fantasy; - -public static class ConfigTableHelper -{ - public static T Load() where T : ASerialize - { - return default; - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/DynamicAssembly/DynamicAssembly.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/DynamicAssembly/DynamicAssembly.cs deleted file mode 100644 index 2cf3b29..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/DynamicAssembly/DynamicAssembly.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System.Reflection; -using Fantasy.Exporter; -using Fantasy.Serialize; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using ProtoBuf; -#pragma warning disable CS8601 // Possible null reference assignment. - -namespace Exporter.Excel; - -/// -/// 动态程序集类,用于加载动态生成的程序集并获取动态信息。 -/// -public static class DynamicAssembly -{ - private static void MetadataReference(out string assemblyName, out List metadataReferenceList) - { - AssemblyMetadata assemblyMetadata; - MetadataReference metadataReference; - var currentDomain = AppDomain.CurrentDomain; - assemblyName = Path.GetRandomFileName(); - var assemblyArray = currentDomain.GetAssemblies(); - metadataReferenceList = new List(); - - // 注册引用 - - foreach (var domainAssembly in assemblyArray) - { - if (string.IsNullOrEmpty(domainAssembly.Location)) - { - continue; - } - - assemblyMetadata = AssemblyMetadata.CreateFromFile(domainAssembly.Location); - metadataReference = assemblyMetadata.GetReference(); - metadataReferenceList.Add(metadataReference); - } - - // 添加Proto支持 - - assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ProtoMemberAttribute).Assembly.Location); - metadataReference = assemblyMetadata.GetReference(); - metadataReferenceList.Add(metadataReference); - - // 添加Fantasy支持 - - assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ASerialize).Assembly.Location); - metadataReference = assemblyMetadata.GetReference(); - metadataReferenceList.Add(metadataReference); - } - - /// - /// 加载指定路径下的动态程序集。 - /// - /// 程序集文件路径。 - /// 加载的动态程序集。 - public static Assembly Load(string path) - { - var fileList = new List(); - - // 找到所有需要加载的CS文件 - - foreach (string file in Directory.GetFiles(path)) - { - if (Path.GetExtension(file) != ".cs") - { - continue; - } - - fileList.Add(file); - } - - var syntaxTreeList = new List(); - - foreach (var file in fileList) - { - using var fileStream = new StreamReader(file); - var cSharp = CSharpSyntaxTree.ParseText(fileStream.ReadToEnd()); - syntaxTreeList.Add(cSharp); - } - - // 注册程序集 - MetadataReference(out var assemblyName, out var metadataReferenceList); - var compilation = CSharpCompilation.Create(assemblyName, syntaxTreeList, metadataReferenceList, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - using var ms = new MemoryStream(); - var result = compilation.Emit(ms); - if (!result.Success) - { - foreach (var resultDiagnostic in result.Diagnostics) - { - Log.Error(resultDiagnostic.GetMessage()); - } - - throw new Exception("failures"); - } - - ms.Seek(0, SeekOrigin.Begin); - return Assembly.Load(ms.ToArray()); - } - - /// - /// 获取动态程序集中指定表格的动态信息。 - /// - /// 动态程序集。 - /// 表格名称。 - /// 动态信息对象。 - public static DynamicConfigDataType GetDynamicInfo(Assembly dynamicAssembly, string tableName) - { - var dynamicConfigDataType = new DynamicConfigDataType - { - ConfigDataType = GetConfigType(dynamicAssembly, $"{tableName}Data"), - ConfigType = GetConfigType(dynamicAssembly, $"{tableName}") - }; - - dynamicConfigDataType.ConfigData = CreateInstance(dynamicConfigDataType.ConfigDataType); - - var listPropertyType = dynamicConfigDataType.ConfigDataType.GetProperty("List"); - - if (listPropertyType == null) - { - throw new Exception("No Property named Add was found"); - } - - dynamicConfigDataType.Obj = listPropertyType.GetValue(dynamicConfigDataType.ConfigData); - dynamicConfigDataType.Method = listPropertyType.PropertyType.GetMethod("Add"); - - if (dynamicConfigDataType.Method == null) - { - throw new Exception("No method named Add was found"); - } - - return dynamicConfigDataType; - } - - /// - /// 根据类型名称获取动态类型。 - /// - /// 动态程序集。 - /// 类型名称。 - /// 动态类型。 - private static Type GetConfigType(Assembly dynamicAssembly, string typeName) - { - var configType = dynamicAssembly.GetType($"Fantasy.{typeName}"); - - if (configType == null) - { - throw new FileNotFoundException($"Fantasy.{typeName} not found"); - } - - return configType; - // return dynamicAssembly.GetType($"Fantasy.{typeName}"); - } - - /// - /// 创建动态实例。 - /// - /// 动态类型。 - /// 动态实例。 - public static object CreateInstance(Type configType) - { - var config = Activator.CreateInstance(configType); - - if (config == null) - { - throw new Exception($"{configType.Name} is Activator.CreateInstance error"); - } - - return config; - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/DynamicAssembly/DynamicConfigDataType.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/DynamicAssembly/DynamicConfigDataType.cs deleted file mode 100644 index 6725f83..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/DynamicAssembly/DynamicConfigDataType.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Text; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Exporter.Excel; - -/// -/// 动态配置数据类型类,用于存储动态配置数据的相关信息。 -/// -public class DynamicConfigDataType -{ - /// - /// 配置数据对象,继承自 AProto 基类。 - /// - public object ConfigData; - /// - /// 配置数据类型。 - /// - public Type ConfigDataType; - /// - /// 配置类型。 - /// - public Type ConfigType; - /// - /// 反射方法信息,用于调用特定方法。 - /// - public MethodInfo Method; - /// - /// 配置数据对象实例。 - /// - public object Obj; - /// - /// 用于生成 JSON 格式数据的字符串构建器。 - /// - public StringBuilder Json = new StringBuilder(); -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/DynamicAssembly/OneDynamicAssembly.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/DynamicAssembly/OneDynamicAssembly.cs deleted file mode 100644 index 57de11e..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/DynamicAssembly/OneDynamicAssembly.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Reflection; -using Fantasy.Exporter; -using Fantasy.Serialize; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using ProtoBuf; - -namespace Exporter.Excel; - -public class OneDynamicAssembly -{ - private readonly List _syntaxTreeList = new List(); - - public void Load(string file) - { - using var fileStream = new StreamReader(file); - var cSharp = CSharpSyntaxTree.ParseText(fileStream.ReadToEnd()); - _syntaxTreeList.Add(cSharp); - } - - public Assembly Assembly - { - get - { - AssemblyMetadata assemblyMetadata; - MetadataReference metadataReference; - var currentDomain = AppDomain.CurrentDomain; - var assemblyName = Path.GetRandomFileName(); - var assemblyArray = currentDomain.GetAssemblies(); - var metadataReferenceList = new List(); - // 注册引用 - foreach (var domainAssembly in assemblyArray) - { - if (string.IsNullOrEmpty(domainAssembly.Location)) - { - continue; - } - - assemblyMetadata = AssemblyMetadata.CreateFromFile(domainAssembly.Location); - metadataReference = assemblyMetadata.GetReference(); - metadataReferenceList.Add(metadataReference); - } - // 添加ProtoEntity支持 - assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ASerialize).Assembly.Location); - metadataReference = assemblyMetadata.GetReference(); - metadataReferenceList.Add(metadataReference); - // 添加MessagePack支持 - assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ProtoMemberAttribute).Assembly.Location); - metadataReference = assemblyMetadata.GetReference(); - metadataReferenceList.Add(metadataReference); - CSharpCompilation compilation = CSharpCompilation.Create(assemblyName, _syntaxTreeList, metadataReferenceList, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - - using var ms = new MemoryStream(); - var result = compilation.Emit(ms); - - if (!result.Success) - { - foreach (var resultDiagnostic in result.Diagnostics) - { - Log.Error(resultDiagnostic.GetMessage()); - } - - throw new Exception("failures"); - } - - ms.Seek(0, SeekOrigin.Begin); - return Assembly.Load(ms.ToArray()); - } - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelExporter.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelExporter.cs deleted file mode 100644 index f11f6b0..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelExporter.cs +++ /dev/null @@ -1,1056 +0,0 @@ -using System.Collections.Concurrent; -using System.Reflection; -using System.Runtime.Loader; -using System.Security.Cryptography; -using System.Text; -using System.Text.RegularExpressions; -using Exporter; -using Exporter.Excel; -using Fantasy; -using Fantasy.Assembly; -using Fantasy.ConfigTable; -using Fantasy.DataStructure.Collection; -using Fantasy.Exporter; -using Fantasy.Helper; -using Fantasy.Serialize; -using Microsoft.CodeAnalysis; -using Newtonsoft.Json; -using OfficeOpenXml; -using static System.String; -// ReSharper disable InconsistentNaming -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8604 // Possible null reference argument. -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - -namespace Fantasy.Tools.ConfigTable; -using TableDictionary = SortedDictionary>; -/// -/// Excel 数据导出器,用于从 Excel 文件导出数据到二进制格式和生成 C# 类文件。 -/// -public sealed class ExcelExporter -{ - public ExportType ExportType; - private readonly string _excelProgramPath; - private readonly string _versionFilePath; - private readonly string _excelClientFileDirectory; - private readonly string _excelServerFileDirectory; - public readonly string ClientCustomExportDirectory; - public readonly string ServerCustomExportDirectory; - private readonly string _excelServerBinaryDirectory; - private readonly string _excelClientBinaryDirectory; - private readonly string _excelServerJsonDirectory; - private readonly string _excelClientJsonDirectory; - public VersionInfo VersionInfo; // 存储 Excel 文件的版本信息。 - private readonly Regex _regexName = new Regex("^[a-zA-Z][a-zA-Z0-9_]*$"); // 用于验证 Excel 表名的正则表达式。 - private readonly HashSet _loadFiles = [".xlsx", ".xlsm", ".csv"]; // 加载的支持文件扩展名。 - private readonly OneToManyList _tables = new OneToManyList(); // 存储 Excel 表及其导出信息。 - private readonly ConcurrentDictionary _excelTables = new ConcurrentDictionary(); // 存储解析后的 Excel 表。 - public readonly ConcurrentDictionary Worksheets = new ConcurrentDictionary(); // 存储已加载的 Excel 工作表。 - public readonly Dictionary IgnoreTable = new Dictionary(); // 存储以#开头的的表和路径 - /// - /// 导表支持的数据类型集合。 - /// - public static readonly HashSet ColTypeSet = - [ - "", "0", "bool", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "string", - "IntDictionaryConfig", "StringDictionaryConfig", - "short[]", "int[]", "long[]", "float[]", "string[]", "uint[]" - ]; - /// - /// 导出完成后自动删除的配置表代码文件。 - /// - private static readonly HashSet RemoveConfigSet = - [ - "WorldConfig.cs", "ServerConfig.cs", "SceneConfig.cs", "MachineConfig.cs", "ProcessConfig.cs" - ]; - static ExcelExporter() - { - ExcelPackage.License.SetNonCommercialOrganization("Fantasy"); - } - /// - /// 根据指定的 exportType 初始化 ExcelExporter 类的新实例。 - /// - /// 要执行的导出类型(AllExcel 或 AllExcelIncrement)。 - public ExcelExporter(ExportType exportType) - { - ExportType = exportType; - - if (ExporterSettingsHelper.ExcelVersionFile == null || ExporterSettingsHelper.ExcelVersionFile.Trim() == "") - { - Log.Info($"ExcelVersionFile Can not be empty!"); - return; - } - - if (ExporterSettingsHelper.ExcelProgramPath == null || ExporterSettingsHelper.ExcelProgramPath.Trim() == "") - { - Log.Info($"ExcelProgramPath Can not be empty!"); - return; - } - - _excelProgramPath = FileHelper.GetFullPath(ExporterSettingsHelper.ExcelProgramPath); - _versionFilePath = FileHelper.GetFullPath(ExporterSettingsHelper.ExcelVersionFile); - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Client)) - { - if (ExporterSettingsHelper.ExcelClientBinaryDirectory == null || - ExporterSettingsHelper.ExcelClientBinaryDirectory.Trim() == "") - { - Log.Info($"ExcelClientBinaryDirectory Can not be empty!"); - return; - } - - if (ExporterSettingsHelper.ExcelClientJsonDirectory == null || - ExporterSettingsHelper.ExcelClientJsonDirectory.Trim() == "") - { - Log.Info($"ExcelClientJsonDirectory Can not be empty!"); - return; - } - - if (ExporterSettingsHelper.ExcelClientFileDirectory == null || - ExporterSettingsHelper.ExcelClientFileDirectory.Trim() == "") - { - Log.Info($"ExcelServerFileDirectory Can not be empty!"); - return; - } - - if (ExporterSettingsHelper.ClientCustomExportDirectory == null || - ExporterSettingsHelper.ClientCustomExportDirectory.Trim() == "") - { - Log.Info($"ClientCustomExportDirectory Can not be empty!"); - return; - } - - _excelClientJsonDirectory = FileHelper.GetFullPath(ExporterSettingsHelper.ExcelClientJsonDirectory); - _excelClientBinaryDirectory = FileHelper.GetFullPath(ExporterSettingsHelper.ExcelClientBinaryDirectory); - ClientCustomExportDirectory = FileHelper.GetFullPath(ExporterSettingsHelper.ClientCustomExportDirectory); - _excelClientFileDirectory = FileHelper.GetFullPath(ExporterSettingsHelper.ExcelClientFileDirectory); - // FileHelper.ClearDirectoryFile(_excelClientFileDirectory); - } - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server)) - { - if (ExporterSettingsHelper.ExcelServerFileDirectory == null || ExporterSettingsHelper.ExcelServerFileDirectory.Trim() == "") - { - Log.Info($"ExcelServerFileDirectory Can not be empty!"); - return; - } - - if (ExporterSettingsHelper.ExcelServerJsonDirectory == null || ExporterSettingsHelper.ExcelServerJsonDirectory.Trim() == "") - { - Log.Info($"ExcelServerJsonDirectory Can not be empty!"); - return; - } - - if (ExporterSettingsHelper.ExcelServerBinaryDirectory == null || ExporterSettingsHelper.ExcelServerBinaryDirectory.Trim() == "") - { - Log.Info($"ExcelServerBinaryDirectory Can not be empty!"); - return; - } - - if (ExporterSettingsHelper.ServerCustomExportDirectory == null || ExporterSettingsHelper.ServerCustomExportDirectory.Trim() == "") - { - Log.Info($"ServerCustomExportDirectory Can not be empty!"); - return; - } - - _excelServerJsonDirectory = FileHelper.GetFullPath(ExporterSettingsHelper.ExcelServerJsonDirectory); - _excelServerBinaryDirectory = FileHelper.GetFullPath(ExporterSettingsHelper.ExcelServerBinaryDirectory); - ServerCustomExportDirectory = FileHelper.GetFullPath(ExporterSettingsHelper.ServerCustomExportDirectory); - _excelServerFileDirectory = FileHelper.GetFullPath(ExporterSettingsHelper.ExcelServerFileDirectory); - // FileHelper.ClearDirectoryFile(_excelServerFileDirectory); - } - - switch (ExportType) - { - case ExportType.AllExcelIncrement: - { - break; - } - case ExportType.AllExcel: - { - if (File.Exists(_versionFilePath)) - { - File.Delete(_versionFilePath); - } - - break; - } - } - - SerializerManager.Initialize(); - - } - - public void Run() - { - Find(); - Parsing(); - ExportToBinary(); - File.WriteAllText(_versionFilePath, JsonConvert.SerializeObject(VersionInfo)); - CustomExport(); - RemoveConfigCS(); - } - private static void RemoveConfigCS() - { - foreach (var removeConfigFile in RemoveConfigSet) - { - var serverFile = Path.Combine(ExporterSettingsHelper.ExcelServerFileDirectory, removeConfigFile); - var clientFile = Path.Combine(ExporterSettingsHelper.ExcelClientFileDirectory, removeConfigFile); - - if (File.Exists(serverFile)) - { - File.Delete(serverFile); - } - - if (File.Exists(clientFile)) - { - File.Delete(clientFile); - } - } - } - - private void CustomExport() - { - var task = new List(); - var excelWorksheets = new ExcelWorksheets(this); - var customConfigure = $"{_excelProgramPath}Custom.txt"; - - if (!File.Exists(customConfigure)) - { - using var streamWriter = File.CreateText(customConfigure); - var stringBuilder = new StringBuilder(); - stringBuilder.AppendLine("// 自定义导出配置文件,用于配置自定义导出自定义程序的路径,每行一个路径,路径是导表应用的相对路径。如:../../Config/Custom/1.cs"); - streamWriter.Write(stringBuilder); - return; - } - - var lineNumber = 0; - var oneDynamicAssembly = new OneDynamicAssembly(); - using var reader = new StreamReader(customConfigure); - - while (reader.ReadLine() is { } lineStr) - { - if (++lineNumber == 1 || string.IsNullOrEmpty(lineStr) || lineStr.StartsWith("#")) - { - continue; - } - - oneDynamicAssembly.Load(FileHelper.GetFullPath(lineStr)); - } - - long AssemblyIdentity(System.Reflection.Assembly assembly) - { - var assemblyName = assembly.GetName(); - var name = assemblyName.Name; - var version = assemblyName.Version.ToString(); - var culture = assemblyName.CultureInfo?.Name ?? "neutral"; - var publicKeyToken = BitConverter.ToString(assemblyName.GetPublicKeyToken()).Replace("-", string.Empty); - var assemblyIdentity = $"{name}|{version}|{culture}|{publicKeyToken}"; - var hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(assemblyIdentity)); - return BitConverter.ToInt64(hashBytes, 0); - } - - void AddCustomExportTask(System.Reflection.Assembly assembly) - { - var assemblyIdentity = AssemblyIdentity(assembly); - var assemblyInfo = new AssemblyInfo(assemblyIdentity); - assemblyInfo.Load(assembly); - - if (!assemblyInfo.AssemblyTypeGroupList.TryGetValue(typeof(ICustomExport), out var customExportList)) - { - return; - } - - foreach (var type in customExportList) - { - var customExport = (ICustomExport)Activator.CreateInstance(type); - - if (customExport != null) - { - customExport.Init(this, excelWorksheets); - task.Add(Task.Run(customExport.Run)); - } - } - } - - // 生成一个系统内置的自定义导出类 - var sceneTypeConfigToEnum = new SceneTypeConfigToEnum(); - sceneTypeConfigToEnum.Init(this, excelWorksheets); - task.Add(Task.Run(sceneTypeConfigToEnum.Run)); - // task.Add(Task.Run(constValueToConst.Run)); - // 加载自定义导出程序集 - AddCustomExportTask(oneDynamicAssembly.Assembly); - // 执行自定义导出任务 - Task.WaitAll(task.ToArray()); - } - - /// - /// 查找配置文件 - /// - private void Find() - { - VersionInfo = File.Exists(_versionFilePath) ? JsonConvert.DeserializeObject(File.ReadAllText(_versionFilePath)) : new VersionInfo(); - - var dir = new DirectoryInfo(_excelProgramPath); - var excelFiles = dir.GetFiles("*", SearchOption.AllDirectories); - - if (excelFiles.Length <= 0) - { - return; - } - - foreach (var excelFile in excelFiles) - { - // 过滤掉非指定后缀的文件 - - if (!_loadFiles.Contains(excelFile.Extension)) - { - continue; - } - - var lastIndexOf = excelFile.Name.LastIndexOf(".", StringComparison.Ordinal); - - if (lastIndexOf < 0) - { - continue; - } - - var fullName = excelFile.FullName; - var excelName = excelFile.Name.Substring(0, lastIndexOf); - var path = fullName.Substring(0, fullName.Length - excelFile.Name.Length); - - // 过滤~开头文件 - - if (excelName.StartsWith("~", StringComparison.Ordinal)) - { - continue; - } - - // 如果文件名以#开头,那么这个文件夹下的所有文件都不导出 - - if (excelName.StartsWith("#", StringComparison.Ordinal)) - { - IgnoreTable.Add(excelName, fullName); - continue; - } - - // 如果文件夹名包含#,那么这个文件夹下的所有文件都不导出 - - if (path.Contains("#", StringComparison.Ordinal)) - { - continue; - } - - if (!_regexName.IsMatch(excelName)) - { - Log.Info($"{excelName} 配置文件名非法"); - continue; - } - - var exportInfo = new ExportInfo() - { - Name = excelName, FileInfo = excelFile - }; - - _tables.Add(excelName.Split('_')[0], exportInfo); - } - - var removeTables = new List(); - - foreach (var (tableName, tableList) in _tables) - { - var isNeedExport = false; - - foreach (var exportInfo in tableList) - { - var key = HashCodeHelper.ComputeHash64(exportInfo.Name); - var timer = TimeHelper.Transition(exportInfo.FileInfo.LastWriteTime); - - if (!isNeedExport) - { - - if (VersionInfo.Tables.TryGetValue(key, out var lastWriteTime)) - { - isNeedExport = lastWriteTime != timer; - } - else - { - isNeedExport = true; - } - } - - VersionInfo.Tables[key] = timer; - } - - if (!isNeedExport) - { - removeTables.Add(tableName); - } - } - - foreach (var removeTable in removeTables) - { - _tables.Remove(removeTable); - } - - foreach (var (_, exportInfo) in _tables) - { - exportInfo.Sort((x, y) => Compare(x.Name, y.Name, StringComparison.Ordinal)); - } - } - /// - /// 生成配置文件 - /// - private void Parsing() - { - var generateTasks = new List(); - - foreach (var (tableName, tableList) in _tables) - { - var task = Task.Run(() => - { - var writeToClassTask = new List(); - var excelTable = new ExcelTable(tableName); - - // 筛选需要导出的列 - - foreach (var exportInfo in tableList) - { - try - { - var serverColInfoList = new List(); - var clientColInfoList = new List(); - var worksheet = LoadExcel(exportInfo.FileInfo.FullName, true); - - for (var col = 3; col <= worksheet.Columns.EndColumn; col++) - { - // 列名字第一个字符是#不参与导出 - - var colName = worksheet.GetCellValue(5, col); - if (colName.StartsWith("#", StringComparison.Ordinal)) - { - continue; - } - - // 数值列不参与导出 - - var numericalCol = worksheet.GetCellValue(3, col); - if (numericalCol != "" && numericalCol != "0") - { - continue; - } - - var serverType = worksheet.GetCellValue(1, col); - var clientType = worksheet.GetCellValue(2, col); - var isExportServer = !IsNullOrEmpty(serverType) && serverType != "0"; - var isExportClient = !IsNullOrEmpty(clientType) && clientType != "0"; - - if (!isExportServer && !isExportClient) - { - continue; - } - - if (isExportServer && isExportClient & serverType != clientType) - { - Log.Info($"配置表 {exportInfo.Name} {col} 列 [{colName}] 客户端类型 {clientType} 和 服务端类型 {serverType} 不一致"); - continue; - } - - if (!ColTypeSet.Contains(serverType) || !ColTypeSet.Contains(clientType)) - { - Log.Info($"配置表 {exportInfo.Name} {col} 列 [{colName}] 客户端类型 {clientType}, 服务端类型 {serverType} 不合法"); - continue; - } - - if (!_regexName.IsMatch(colName)) - { - Log.Info($"配置表 {exportInfo.Name} {col} 列 [{colName}] 列名非法"); - continue; - } - - serverColInfoList.Add(col); - - if (isExportClient) - { - clientColInfoList.Add(col); - } - } - - if (clientColInfoList.Count > 0) - { - excelTable.ClientColInfos.Add(exportInfo.FileInfo.FullName, clientColInfoList); - } - - if (serverColInfoList.Count > 0) - { - excelTable.ServerColInfos.Add(exportInfo.FileInfo.FullName, serverColInfoList); - } - } - catch (Exception e) - { - Log.Error($"Config : {tableName}, Name : {exportInfo.Name}, Error : {e}"); - } - } - - // 生成cs文件 - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server)) - { - writeToClassTask.Add(Task.Run(() => - { - WriteToClass(excelTable.ServerColInfos, _excelServerFileDirectory, true); - })); - } - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Client)) - { - writeToClassTask.Add(Task.Run(() => - { - WriteToClass(excelTable.ClientColInfos, _excelClientFileDirectory, false); - })); - } - - Task.WaitAll(writeToClassTask.ToArray()); - _excelTables.TryAdd(tableName, excelTable); - }); - - generateTasks.Add(task); - } - - Task.WaitAll(generateTasks.ToArray()); - } - /// - /// 把数据和实体类转换二进制导出到文件中 - /// - private void ExportToBinary() - { - System.Reflection.Assembly dynamicServerAssembly = null; - System.Reflection.Assembly dynamicClientAssembly = null; - var exportToBinaryTasks = new List(); - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server) && Directory.Exists(_excelServerFileDirectory)) - { - dynamicServerAssembly = DynamicAssembly.Load(_excelServerFileDirectory); - } - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Client) && Directory.Exists(_excelClientFileDirectory)) - { - dynamicClientAssembly = DynamicAssembly.Load(_excelClientFileDirectory); - } - - foreach (var (tableName, tableList) in _tables) - { - var task = Task.Run(() => - { - DynamicConfigDataType serverDynamicInfo = null; - DynamicConfigDataType clientDynamicInfo = null; - - var idCheck = new HashSet(); - var excelTable = _excelTables[tableName]; - var csName = Path.GetFileNameWithoutExtension(tableName); - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server)) - { - var serverColInfoCount = excelTable.ServerColInfos.Sum(d => d.Value.Count); - serverDynamicInfo = serverColInfoCount == 0 ? null : DynamicAssembly.GetDynamicInfo(dynamicServerAssembly, csName); - } - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Client)) - { - var clientColInfoCount = excelTable.ClientColInfos.Sum(d => d.Value.Count); - clientDynamicInfo = clientColInfoCount == 0 ? null : DynamicAssembly.GetDynamicInfo(dynamicClientAssembly, csName); - } - - for (var i = 0; i < tableList.Count; i++) - { - var tableListName = tableList[i]; - - try - { - var fileInfoFullName = tableListName.FileInfo.FullName; - var excelWorksheet = LoadExcel(fileInfoFullName, false); - var rows = excelWorksheet.Dimension.Rows; - excelTable.ServerColInfos.TryGetValue(fileInfoFullName, out var serverCols); - excelTable.ClientColInfos.TryGetValue(fileInfoFullName, out var clientCols); - - for (var row = 7; row <= rows; row++) - { - if (excelWorksheet.GetCellValue(row, 1).StartsWith("#", StringComparison.Ordinal)) - { - continue; - } - - var id = excelWorksheet.GetCellValue(row, 3); - - if (idCheck.Contains(id)) - { - Log.Info($"{tableListName.Name} 存在重复Id {id} 行号 {row}"); - continue; - } - - idCheck.Add(id); - var isLast = row == rows && (i == tableList.Count - 1); - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server)) - { - GenerateBinary(fileInfoFullName, excelWorksheet, serverDynamicInfo, serverCols, id, row, isLast, true); - } - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Client)) - { - GenerateBinary(fileInfoFullName, excelWorksheet, clientDynamicInfo, clientCols, id, row, isLast, false); - } - } - } - catch (Exception e) - { - Log.Error($"Table:{tableListName} error! \n{e}"); - throw; - } - } - - if (serverDynamicInfo?.ConfigData != null) - { - var memoryStream = new MemoryStreamBuffer(); - SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf).Serialize(serverDynamicInfo.ConfigData, memoryStream); - if (!Directory.Exists(_excelServerBinaryDirectory)) - { - Directory.CreateDirectory(_excelServerBinaryDirectory); - } - var asSpan = memoryStream.GetBuffer().AsSpan(0, (int)memoryStream.Position); - File.WriteAllBytes(Path.Combine(_excelServerBinaryDirectory, $"{csName}Data.bytes"), asSpan.ToArray()); - if (serverDynamicInfo.Json.Length > 0) - { - if (!Directory.Exists(_excelServerJsonDirectory)) - { - Directory.CreateDirectory(_excelServerJsonDirectory); - } - using var sw = new StreamWriter(Path.Combine(_excelServerJsonDirectory, $"{csName}Data.Json")); - sw.WriteLine("{\"List\":["); - sw.Write(serverDynamicInfo.Json.ToString()); - sw.WriteLine("]}"); - } - } - - if (clientDynamicInfo?.ConfigData != null) - { - var memoryStream = new MemoryStreamBuffer(); - SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf).Serialize(clientDynamicInfo.ConfigData, memoryStream); - if (!Directory.Exists(_excelClientBinaryDirectory)) - { - Directory.CreateDirectory(_excelClientBinaryDirectory); - } - var asSpan = memoryStream.GetBuffer().AsSpan(0, (int)memoryStream.Position); - File.WriteAllBytes(Path.Combine(_excelClientBinaryDirectory, $"{csName}Data.bytes"), asSpan.ToArray()); - - if (clientDynamicInfo.Json.Length > 0) - { - if (!Directory.Exists(_excelClientJsonDirectory)) - { - Directory.CreateDirectory(_excelClientJsonDirectory); - } - using var sw = new StreamWriter(Path.Combine(_excelClientJsonDirectory, $"{csName}Data.Json")); - sw.WriteLine("{\"List\":["); - sw.Write(clientDynamicInfo.Json.ToString()); - sw.WriteLine("]}"); - } - } - }); - exportToBinaryTasks.Add(task); - } - - Task.WaitAll(exportToBinaryTasks.ToArray()); - } - - private void GenerateBinary(string fileInfoFullName, ExcelWorksheet excelWorksheet, DynamicConfigDataType dynamicInfo, List cols, string id, int row, bool isLast, bool isServer) - { - if (cols == null || IsNullOrEmpty(id) || cols.Count <= 0 || dynamicInfo?.ConfigType == null) - { - return; - } - - var config = DynamicAssembly.CreateInstance(dynamicInfo.ConfigType); - - for (var i = 0; i < cols.Count; i++) - { - string colType; - var colIndex = cols[i]; - var colName = excelWorksheet.GetCellValue(5, colIndex); - var value = excelWorksheet.GetCellValue(row, colIndex); - - if (isServer) - { - colType = excelWorksheet.GetCellValue(1, colIndex); - - if (IsNullOrEmpty(colType) || colType == "0") - { - colType = excelWorksheet.GetCellValue(2, colIndex); - } - } - else - { - colType = excelWorksheet.GetCellValue(2, colIndex); - } - - try - { - SetNewValue(dynamicInfo.ConfigType.GetProperty(colName), config, colType, value); - } - catch (Exception e) - { - Log.Error($"Error Table {fileInfoFullName} Col:{colName} colType:{colType} Row:{row} value:{value} {e}"); - throw; - } - } - - dynamicInfo.Method.Invoke(dynamicInfo.Obj, new object[] {config}); - - var json = JsonConvert.SerializeObject(config); - - if (isLast) - { - dynamicInfo.Json.AppendLine(json); - } - else - { - dynamicInfo.Json.AppendLine($"{json},"); - } - } - - /// - /// 从 Excel 文件加载工作表并返回 ExcelWorksheet 对象。 - /// - /// 工作表的名称或文件路径。 - /// 是否将加载的工作表添加到缓存字典中。 - /// 表示 Excel 工作表的 ExcelWorksheet 对象。 - public ExcelWorksheet LoadExcel(string name, bool isAddToDic) - { - if (Worksheets.TryGetValue(name, out var worksheet)) - { - return worksheet; - } - - var workbookWorksheets = ExcelHelper.LoadExcel(name).Workbook.Worksheets; - worksheet = workbookWorksheets[0]; - - if (isAddToDic) - { - Worksheets.TryAdd(name, worksheet); - - foreach (var workbookWorksheet in workbookWorksheets) - { - VersionInfo.WorksheetNames.Add(HashCodeHelper.ComputeHash64(workbookWorksheet.Name)); - Worksheets.TryAdd(workbookWorksheet.Name, workbookWorksheet); - } - } - - Log.Info(name); - return workbookWorksheets[0]; - } - /// - /// 写入到cs - /// - /// - /// - /// - private void WriteToClass(TableDictionary colInfos, string exportPath, bool isServer) - { - if (colInfos.Count <= 0) - { - return; - } - - var index = 0; - var fileBuilder = new StringBuilder(); - var colNameSet = new HashSet(); - - if (colInfos.Count == 0) - { - return; - } - - var csName = Path.GetFileNameWithoutExtension(colInfos.First().Key)?.Split('_')[0]; - - foreach (var (tableName, cols) in colInfos) - { - if (cols == null || cols.Count == 0) - { - continue; - } - - var excelWorksheet = LoadExcel(tableName, false); - - foreach (var colIndex in cols) - { - var colName = excelWorksheet.GetCellValue(5, colIndex); - - if (colNameSet.Contains(colName)) - { - continue; - } - - colNameSet.Add(colName); - - string colType; - - if (isServer) - { - colType = excelWorksheet.GetCellValue(1, colIndex); - - if (IsNullOrEmpty(colType) || colType == "0") - { - colType = excelWorksheet.GetCellValue(2, colIndex); - } - } - else - { - colType = excelWorksheet.GetCellValue(2, colIndex); - } - - var remarks = excelWorksheet.GetCellValue(4, colIndex); - - // 解决不同平台换行符不一致的问题 - - switch (Environment.OSVersion.Platform) - { - case PlatformID.Win32NT: - case PlatformID.Win32S: - case PlatformID.Win32Windows: - case PlatformID.WinCE: - { - fileBuilder.Append($"\r\n\t\t[ProtoMember({++index})]\r\n"); - break; - } - default: - { - fileBuilder.Append($"\n\t\t[ProtoMember({++index})]\n"); - break; - } - } - - fileBuilder.Append( - IsArray(colType,out var t) - ? $"\t\tpublic {colType} {colName} {{ get; set; }} = Array.Empty<{t}>(); // {remarks}" - : $"\t\tpublic {colType} {colName} {{ get; set; }} // {remarks}"); - } - } - - var template = ExcelTemplate.Template; - - if (fileBuilder.Length > 0) - { - if (!Directory.Exists(exportPath)) - { - FileHelper.CreateDirectory(exportPath); - } - - var content = template.Replace("(namespace)", "Fantasy") - .Replace("(ConfigName)", csName) - .Replace("(Fields)", fileBuilder.ToString()); - File.WriteAllText(Path.Combine(exportPath, $"{csName}.cs"), content); - } - } - private void SetNewValue(PropertyInfo propertyInfo, object config, string type, string value) - { - if (IsNullOrWhiteSpace(value)) - { - return; - } - - switch (type) - { - case "short": - { - propertyInfo.SetValue(config, Convert.ToInt16(value)); - return; - } - case "ushort": - { - propertyInfo.SetValue(config, Convert.ToUInt16(value)); - return; - } - case "uint": - { - propertyInfo.SetValue(config, Convert.ToUInt32(value)); - return; - } - case "int": - { - propertyInfo.SetValue(config, Convert.ToInt32(value)); - return; - } - case "decimal": - { - propertyInfo.SetValue(config, Convert.ToDecimal(value)); - return; - } - case "string": - { - try - { - propertyInfo.SetValue(config, value); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - - return; - } - case "bool": - { - // 空字符串 - - value = value.ToLower(); - - if (IsNullOrEmpty(value)) - { - propertyInfo.SetValue(config, false); - } - else if (bool.TryParse(value, out bool b)) - { - propertyInfo.SetValue(config, b); - } - else if (int.TryParse(value, out int v)) - { - propertyInfo.SetValue(config, v != 0); - } - else - { - propertyInfo.SetValue(config, false); - } - - return; - } - case "ulong": - { - propertyInfo.SetValue(config, Convert.ToUInt64(value)); - return; - } - case "long": - { - propertyInfo.SetValue(config, Convert.ToInt64(value)); - return; - } - case "double": - { - propertyInfo.SetValue(config, Convert.ToDouble(value)); - return; - } - case "float": - { - propertyInfo.SetValue(config, Convert.ToSingle(value)); - return; - } - case "int32[]": - case "int[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToInt32(d)).ToArray()); - } - - return; - } - case "uint[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToUInt32(d)).ToArray()); - } - return; - } - case "long[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToInt64(d)).ToArray()); - } - - return; - } - case "double[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToDouble(d)).ToArray()); - } - - return; - } - case "string[]": - { - if (value == "0") - { - return; - } - - var list = value.Split(",").ToArray(); - - for (var i = 0; i < list.Length; i++) - { - list[i] = list[i].Replace("\"", ""); - } - - propertyInfo.SetValue(config, value.Split(",").ToArray()); - - return; - } - case "float[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToSingle(d)).ToArray()); - } - - return; - } - case "IntDictionaryConfig": - { - if (value.Trim() == "" || value.Trim() == "{}") - { - propertyInfo.SetValue(config, null); - return; - } - - var attr = new IntDictionaryConfig {Dic = JsonConvert.DeserializeObject>(value)}; - - propertyInfo.SetValue(config, attr); - - return; - } - case "StringDictionaryConfig": - { - if (value.Trim() == "" || value.Trim() == "{}") - { - propertyInfo.SetValue(config, null); - return; - } - - var attr = new StringDictionaryConfig {Dic = JsonConvert.DeserializeObject>(value)}; - - propertyInfo.SetValue(config, attr); - - return; - } - default: - throw new NotSupportedException($"不支持此类型: {type}"); - } - } - private bool IsArray(string type, out string t) - { - t = null; - var index = type.IndexOf("[]", StringComparison.Ordinal); - - if (index >= 0) - { - t = type.Remove(index, 2); - } - - return index >= 0; - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelHelper.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelHelper.cs deleted file mode 100644 index 05e63d5..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelHelper.cs +++ /dev/null @@ -1,47 +0,0 @@ -using OfficeOpenXml; - -namespace Fantasy.Tools.ConfigTable; - -/// -/// 提供操作 Excel 文件的辅助方法。 -/// -public static class ExcelHelper -{ - /// - /// 加载 Excel 文件并返回 ExcelPackage 实例。 - /// - /// Excel 文件的路径。 - /// ExcelPackage 实例。 - public static ExcelPackage LoadExcel(string name) - { - return new ExcelPackage(name); - } - - /// - /// 获取指定工作表中指定行列位置的单元格值。 - /// - /// Excel 工作表。 - /// 行索引。 - /// 列索引。 - /// 单元格值。 - public static string GetCellValue(this ExcelWorksheet sheet, int row, int column) - { - ExcelRange cell = sheet.Cells[row, column]; - - try - { - if (cell.Value == null) - { - return ""; - } - - string s = cell.GetValue(); - - return s.Trim(); - } - catch (Exception e) - { - throw new Exception($"Rows {row} Columns {column} Content {cell.Text} {e}"); - } - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelTable.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelTable.cs deleted file mode 100644 index 9a645a8..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelTable.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Fantasy.Tools.ConfigTable; - -/// -/// Excel表格类,用于存储表格的名称和列信息。 -/// -public sealed class ExcelTable -{ - /// - /// 表格的名称。 - /// - public readonly string Name; - /// - /// 客户端列信息,使用排序字典存储列名和列索引列表。 - /// - public readonly SortedDictionary> ClientColInfos = new(); - /// - /// 服务器端列信息,使用排序字典存储列名和列索引列表。 - /// - public readonly SortedDictionary> ServerColInfos = new(); - /// - /// 构造函数,初始化Excel表格对象并设置表格名称。 - /// - /// 表格名称。 - public ExcelTable(string name) - { - Name = name; - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelTemplate.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelTemplate.cs deleted file mode 100644 index 3558e86..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelTemplate.cs +++ /dev/null @@ -1,98 +0,0 @@ -namespace Fantasy.Tools.ConfigTable; - -public static class ExcelTemplate -{ - public static readonly string Template = """ - using System; - using ProtoBuf; - using Fantasy; - using System.Linq; - using System.Reflection; - using System.Collections.Generic; - using System.Collections.Concurrent; - using Fantasy.ConfigTable; - using Fantasy.Serialize; - // ReSharper disable CollectionNeverUpdated.Global - // ReSharper disable UnusedAutoPropertyAccessor.Global - #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - #pragma warning disable CS0169 - #pragma warning disable CS8618 - #pragma warning disable CS8625 - #pragma warning disable CS8603 - - namespace (namespace) - { - [ProtoContract] - public sealed partial class (ConfigName)Data : ASerialize, IConfigTable, IProto - { - [ProtoMember(1)] - public List<(ConfigName)> List { get; set; } = new List<(ConfigName)>(); - #if FANTASY_NET - [ProtoIgnore] - private readonly ConcurrentDictionary _configs = new ConcurrentDictionary(); - #else - [ProtoIgnore] - private readonly Dictionary _configs = new Dictionary(); - #endif - private static (ConfigName)Data _instance = null; - - public static (ConfigName)Data Instance - { - get { return _instance ??= ConfigTableHelper.Load<(ConfigName)Data>(); } - private set => _instance = value; - } - - public (ConfigName) Get(uint id, bool check = true) - { - if (_configs.ContainsKey(id)) - { - return _configs[id]; - } - - if (check) - { - throw new Exception($"(ConfigName) not find {id} Id"); - } - - return null; - } - public bool TryGet(uint id, out (ConfigName) config) - { - config = null; - - if (!_configs.ContainsKey(id)) - { - return false; - } - - config = _configs[id]; - return true; - } - public override void AfterDeserialization() - { - foreach (var config in List) - { - #if FANTASY_NET - _configs.TryAdd(config.Id, config); - #else - _configs.Add(config.Id, config); - #endif - config.AfterDeserialization(); - } - - EndInit(); - } - - public override void Dispose() - { - Instance = null; - } - } - - [ProtoContract] - public sealed partial class (ConfigName) : ASerialize, IProto - {(Fields) - } - } - """; -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelWorksheets.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelWorksheets.cs deleted file mode 100644 index dc57062..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExcelWorksheets.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Fantasy.Exporter; -using Fantasy.Helper; -using OfficeOpenXml; -#pragma warning disable CS8601 // Possible null reference assignment. - -namespace Fantasy.Tools.ConfigTable; - -public sealed class ExcelWorksheets(ExcelExporter excelExporter) -{ - public bool TryGetValue(string worksheetName, out ExcelWorksheet excelWorksheet) - { - if (excelExporter.Worksheets.TryGetValue(worksheetName, out excelWorksheet)) - { - return true; - } - - var computeHash64 = HashCodeHelper.ComputeHash64(worksheetName); - if (!excelExporter.VersionInfo.WorksheetNames.Contains(computeHash64)) - { - Log.Info($"{worksheetName} is not exist!"); - } - - return false; - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExportInfo.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExportInfo.cs deleted file mode 100644 index d2150af..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ExportInfo.cs +++ /dev/null @@ -1,17 +0,0 @@ -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Tools.ConfigTable; - -/// -/// 导出信息类,用于存储导出操作的名称和文件信息。 -/// -public class ExportInfo -{ - /// - /// 导出操作的名称。 - /// - public string Name; - /// - /// 导出操作生成的文件信息。 - /// - public FileInfo FileInfo; -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ICustomExport.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ICustomExport.cs deleted file mode 100644 index 0703eff..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/ICustomExport.cs +++ /dev/null @@ -1,148 +0,0 @@ -using Fantasy.Exporter; -using Fantasy.Helper; -// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Tools.ConfigTable; - -/// -/// 自定义导出接口 -/// -public interface ICustomExport -{ - /// - /// 执行导出操作 - /// - void Run(); - /// - /// 内部操作用于初始化、不明白原理不要修改这里和调用这个方法 - /// - /// - /// - void Init(ExcelExporter excelExporter, ExcelWorksheets worksheets); -} - -/// -/// 抽象自定义导出基类 -/// -public abstract class ACustomExport : ICustomExport -{ - protected ExcelExporter ExcelExporter; - protected ExcelWorksheets Worksheets; - - /// - /// 自定义导出类型枚举:客户端、服务器 - /// - protected enum CustomExportType - { - /// - /// 客户端 - /// - Client, - /// - /// 服务器 - /// - Server - } - - /// - /// 内部操作用于初始化、不明白原理不要修改这里 - /// - /// - /// - public void Init(ExcelExporter excelExporter, ExcelWorksheets worksheets) - { - ExcelExporter = excelExporter; - Worksheets = worksheets; - } - - /// - /// 执行导出操作的抽象方法 - /// - public abstract void Run(); - - /// - /// 写入文件内容到指定位置 - /// - /// 文件名 - /// 文件内容 - /// 相对的导出的目录 - /// 自定义导出类型 - protected void Write(string fileName, string fileContent, string filePath, CustomExportType customExportType) - { - if (filePath == null) - { - Log.Error($" {nameof(filePath)} is null"); - return; - } - - filePath = FileHelper.GetFullPath(filePath); - - if (!Directory.Exists(filePath)) - { - FileHelper.CreateDirectory(filePath); - } - - var combine = Path.Combine(filePath, fileName); - File.WriteAllText(combine, fileContent); - - switch (customExportType) - { - case CustomExportType.Client: - { - Log.Info($"导出客户端自定义文件:{filePath}/{fileName}"); - return; - } - case CustomExportType.Server: - { - Log.Info($"导出服务器自定义文件:{filePath}/{fileName}"); - return; - } - } - } - - /// - /// 写入文件内容到指定位置 - /// - /// 文件名 - /// 文件内容 - /// 自定义导出类型 - protected void Write(string fileName, string fileContent, CustomExportType customExportType) - { - switch (customExportType) - { - case CustomExportType.Client: - { - if (string.IsNullOrEmpty(ExcelExporter.ClientCustomExportDirectory)) - { - return; - } - - if (!Directory.Exists(ExcelExporter.ClientCustomExportDirectory)) - { - Directory.CreateDirectory(ExcelExporter.ClientCustomExportDirectory); - } - - File.WriteAllText($"{ExcelExporter.ClientCustomExportDirectory}/{fileName}", fileContent); - Log.Info($"导出客户端自定义文件:{ExcelExporter.ClientCustomExportDirectory}/{fileName}"); - return; - } - case CustomExportType.Server: - { - if (string.IsNullOrEmpty(ExcelExporter.ServerCustomExportDirectory)) - { - return; - } - - if (!Directory.Exists(ExcelExporter.ServerCustomExportDirectory)) - { - Directory.CreateDirectory(ExcelExporter.ServerCustomExportDirectory); - } - - File.WriteAllText($"{ExcelExporter.ServerCustomExportDirectory}/{fileName}", fileContent); - Log.Info($"导出服务器自定义文件:{ExcelExporter.ServerCustomExportDirectory}/{fileName}"); - return; - } - } - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/VersionInfo.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/VersionInfo.cs deleted file mode 100644 index df3b0e1..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Exporter/VersionInfo.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Fantasy.Tools.ConfigTable; - -public class VersionInfo -{ - public SortedSet WorksheetNames = []; - public SortedDictionary Tables = new(); -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/ExporterAges.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/ExporterAges.cs deleted file mode 100644 index 5b712d0..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/ExporterAges.cs +++ /dev/null @@ -1,21 +0,0 @@ -using CommandLine; -using Fantasy.Tools.ConfigTable; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Tools; - -public class ExporterAges -{ - public static ExporterAges Instance; - /// - /// 导出目标平台枚举,用于标识导出到哪个平台 - /// - [Option('p',"ExportPlatform", Required = false, Default = ExportPlatform.None, HelpText = "Export target platform:\n/// Client target platform \nClient = 1\n/// Server target platform\nServer = 2\n/// Client and Server target platform\nAll = 3")] - public ExportPlatform ExportPlatform { get; set; } - /// - /// 导出类型 - /// - [Option('e',"ExportType", Required = false, Default = ExportType.None, HelpText = "Export Type:\n/// Incremental export of all data in Excel format.\nAllExcelIncrement = 1\n/// Export all data to Excel format.\nAllExcel = 2")] - public ExportType ExportType { get; set; } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/ExporterSettings.json b/Tools/SourceCode/Fantasy.Tools.ConfigTable/ExporterSettings.json deleted file mode 100644 index 7499bd6..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/ExporterSettings.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "Export": { - "ExcelProgramPath": { - "Value": "../../../Examples/Config/Excel/", - "Comment": "Excel文件夹的根目录" - }, - "ExcelVersionFile": { - "Value": "../../../Examples/Config/Excel/Version.txt", - "Comment": "Excel的Version文件位置、这个文件用于记录每次导出对比是否需要再次导出的文件" - }, - "ExcelServerFileDirectory": { - "Value": "../../../Examples/Server/Entity/Generate/ConfigTable/Entity/", - "Comment": "Excel生成的代码文件、在服务端文件夹位置" - }, - "ExcelClientFileDirectory": { - "Value": "../../../Examples/Client/Unity/Assets/Scripts/Hotfix/Generate/ConfigTable/Entity/", - "Comment": "Excel生成的代码文件、在客户端文件夹位置" - }, - "ExcelServerBinaryDirectory": { - "Value": "../../../Examples/Config/Binary/", - "Comment": "Excel生成服务器二进制数据文件夹位置" - }, - "ExcelClientBinaryDirectory": { - "Value": "../../../Examples/Client/Unity/Assets/Bundles/Config/", - "Comment": "Excel生成在客户端的二进制数据文件夹位置" - }, - "ExcelServerJsonDirectory": { - "Value": "../../../Examples/Config/Json/Server/", - "Comment": "Excel生成在服务端的Json数据文件夹位置" - }, - "ExcelClientJsonDirectory": { - "Value": "../../../Examples/Config/Json/Client/", - "Comment": "Excel生成在客户端的Json数据文件夹位置" - }, - "ServerCustomExportDirectory": { - "Value": "../../../Examples/Server/Entity/Generate/CustomExport/", - "Comment": "Excel在服务端生成自定义代码的文件夹位置" - }, - "ClientCustomExportDirectory": { - "Value": "../../../Examples/Client/Unity/Assets/Scripts/Hotfix/Generate/CustomExport", - "Comment": "Excel在客户端端生成自定义代码的文件夹位置" - } - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/ExporterSettingsHelper.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/ExporterSettingsHelper.cs deleted file mode 100644 index c39858c..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/ExporterSettingsHelper.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Fantasy.Helper; -using Microsoft.Extensions.Configuration; -#pragma warning disable CS8604 // Possible null reference argument. - -namespace Fantasy.Tools.ConfigTable; - -public class ExporterSettingsHelper -{ - public static string? ExcelProgramPath { get; private set; } - public static string? ExcelVersionFile { get; private set; } - public static string? ExcelServerFileDirectory { get; private set; } - public static string? ExcelClientFileDirectory { get; private set; } - public static string? ExcelServerBinaryDirectory { get; private set; } - public static string? ExcelClientBinaryDirectory { get; private set; } - public static string? ExcelServerJsonDirectory { get; private set; } - public static string? ExcelClientJsonDirectory { get; private set; } - public static string? ServerCustomExportDirectory { get; private set; } - public static string? ClientCustomExportDirectory { get; private set; } - - public static void Initialize() - { - const string settingsName = "ExporterSettings.json"; - var currentDirectory = Directory.GetCurrentDirectory(); - - if (!File.Exists(Path.Combine(currentDirectory, settingsName))) - { - throw new FileNotFoundException($"not found {settingsName} in OutputDirectory"); - } - - var root = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(settingsName).Build(); - - ExcelProgramPath = FileHelper.GetFullPath(root["Export:ExcelProgramPath:Value"]); - ExcelVersionFile = FileHelper.GetFullPath(root["Export:ExcelVersionFile:Value"]); - ExcelServerFileDirectory = FileHelper.GetFullPath(root["Export:ExcelServerFileDirectory:Value"]); - ExcelClientFileDirectory = FileHelper.GetFullPath(root["Export:ExcelClientFileDirectory:Value"]); - ExcelServerBinaryDirectory = FileHelper.GetFullPath(root["Export:ExcelServerBinaryDirectory:Value"]); - ExcelClientBinaryDirectory = FileHelper.GetFullPath(root["Export:ExcelClientBinaryDirectory:Value"]); - ExcelServerJsonDirectory = FileHelper.GetFullPath(root["Export:ExcelServerJsonDirectory:Value"]); - ExcelClientJsonDirectory = FileHelper.GetFullPath(root["Export:ExcelClientJsonDirectory:Value"]); - ServerCustomExportDirectory = FileHelper.GetFullPath(root["Export:ServerCustomExportDirectory:Value"]); - ClientCustomExportDirectory = FileHelper.GetFullPath(root["Export:ClientCustomExportDirectory:Value"]); - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Fantasy.Tools.ConfigTable.csproj b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Fantasy.Tools.ConfigTable.csproj deleted file mode 100644 index b58a43e..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Fantasy.Tools.ConfigTable.csproj +++ /dev/null @@ -1,118 +0,0 @@ - - - - Exe - enable - enable - default - net8.0;net9.0 - - - - false - en - - - - true - TRACE;FANTASY_EXPORTER - ../../Exporter/ConfigTable/ - - - - true - TRACE;FANTASY_EXPORTER - ../../Exporter/ConfigTable/ - - - - - - - - - - - - - - Core\Base\Pool.cs - - - Core\Dictionary\IntDictionaryConfig.cs - - - Core\Dictionary\StringDictionaryConfig.cs - - - Core\Interface\IConfigTable.cs - - - Core\Serialize\ProtoBufPackHelper\IProto.cs - - - Excel\Base\TimeHelper.cs - - - Excel\Base\IPool.cs - - - Excel\Base\AssemblyInfo.cs - - - Excel\Base\OneToManyList.cs - - - Core\ConsoleLog.cs - - - Core\ExportPlatform.cs - - - Core\FileHelper.cs - - - Core\HashCodeHelper.cs - - - Core\JsonHelper.cs - - - Core\Serialize\BsonPack\BsonPackHelperNet.cs - - - Core\Serialize\BsonPack\StructBsonSerialize.cs - - - Core\Serialize\BsonPack\SupportInitializeChecker.cs - - - Core\Serialize\Interface\ASerialize.cs - - - Core\Serialize\Interface\ISerialize.cs - - - Core\Serialize\SerializerManager.cs - - - Core\Serialize\ProtoBufPackHelper\ProtoBufPackHelperNet.cs - - - Excel\Base\MemoryStreamBuffer.cs - - - - - - Always - - - Always - - - Always - - - - diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Program.cs b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Program.cs deleted file mode 100644 index 7352d46..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Program.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Text; -using CommandLine; -using Fantasy.Exporter; -using Fantasy.Tools; -using Fantasy.Tools.ConfigTable; - -try -{ - Parser.Default.ParseArguments(Environment.GetCommandLineArgs()) - .WithNotParsed(error => throw new Exception("Command line format error!")) - .WithParsed(ages => ExporterAges.Instance = ages); - // 初始化配置 - ExporterSettingsHelper.Initialize(); - // 加载配置 - Console.OutputEncoding = Encoding.UTF8; - // 判断启动参数,如果没有选择目标平台就让用户选择 - if (ExporterAges.Instance.ExportPlatform == ExportPlatform.None) - { - Log.Info("请输入你想要导出的目标平台:"); - Log.Info("1:Client(客户端)"); - Log.Info("2:Server(服务器)"); - Log.Info("3:All(客户端和服务器)"); - var inputKeyChar = Console.ReadKey().KeyChar; - if (!int.TryParse(inputKeyChar.ToString(), out var exportPlatformKey) || exportPlatformKey is < 1 or >= (int)ExportPlatform.All) - { - Console.WriteLine(""); - Log.Error("无法识别的导出类型请,输入正确导出的目标平台。"); - return; - } - ExporterAges.Instance.ExportPlatform = (ExportPlatform)exportPlatformKey; - } - - var selectExportType = ExporterAges.Instance.ExportType; - - if (selectExportType == ExportType.None) - { - // 检查启动参数 - Log.Info("请输入你想要做的操作:"); - Log.Info("1:所有增量导出Excel(包含常量枚举)"); - Log.Info("2:所有全量导出Excel(包含常量枚举)"); - // 获取用户输入 - var keyChar = Console.ReadKey().KeyChar; - // 判断用户输入 - if (!int.TryParse(keyChar.ToString(), out var key) || key is < 1 or >= (int)ExportType.Max) - { - Console.WriteLine(""); - Log.Error("无法识别的导出类型请,输入正确的操作类型。"); - return; - } - - selectExportType = (ExportType)key; - } - Log.Info($"selectExportType:{selectExportType} ExportPlatform:{ExporterAges.Instance.ExportPlatform}"); - // 转换用户输入 - Log.Info(""); - new ExcelExporter(selectExportType).Run(); -} -catch (Exception e) -{ - Log.Error(e); -} -finally -{ - Log.Info("按任意键退出程序"); - Console.ReadKey(); - Environment.Exit(0); -} diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Properties/launchSettings.json b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Properties/launchSettings.json deleted file mode 100644 index e468f8b..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Properties/launchSettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "profiles": { - "Fantasy.Tools.ConfigTable": { - "commandName": "Project", - "environmentVariables": {}, - "commandLineArgs": "--ExportPlatform 3" - } - } -} diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Run.bat b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Run.bat deleted file mode 100644 index 082d6b0..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Run.bat +++ /dev/null @@ -1,33 +0,0 @@ -@echo off - -echo Please select an option: -echo 1. Client Increment -echo 2. Client all -echo 3. Server Increment -echo 4. Server all -echo 5. Client and Server Increment -echo 6. Client and Server all - -set /p choice=Please select an option: - -if "%choice%"=="1" ( - echo Client Increment - dotnet Fantasy.Tools.ConfigTable.dll --p 1 --e 1 -) else if "%choice%"=="2" ( - echo Client all - dotnet Fantasy.Tools.ConfigTable.dll --p 1 --e 2 -) else if "%choice%"=="3" ( - echo Server Increment - dotnet Fantasy.Tools.ConfigTable.dll --p 2 --e 1 -) else if "%choice%"=="4" ( - echo Server all - dotnet Fantasy.Tools.ConfigTable.dll --p 2 --e 2 -) else if "%choice%"=="5" ( - echo Client and Server Increment - dotnet Fantasy.Tools.ConfigTable.dll --p 3 --e 1 -) else if "%choice%"=="6" ( - echo Client and Server all - dotnet Fantasy.Tools.ConfigTable.dll --p 3 --e 2 -) else ( - echo Invalid option -) diff --git a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Run.sh b/Tools/SourceCode/Fantasy.Tools.ConfigTable/Run.sh deleted file mode 100644 index 7ac9f52..0000000 --- a/Tools/SourceCode/Fantasy.Tools.ConfigTable/Run.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -echo "1. Client Increment" -echo "2. Client all" -echo "3. Server Increment" -echo "4. Server all" -echo "5. Client and Server Increment" -echo "6. Client and Server all" - -read -n 1 -p "Please select an option:" choice -echo "" -case $choice in - 1) - dotnet Fantasy.Tools.ConfigTable.dll --p 1 --e 1 - ;; - 2) - dotnet Fantasy.Tools.ConfigTable.dll --p 1 --e 2 - ;; - 3) - dotnet Fantasy.Tools.ConfigTable.dll --p 2 --e 1 - ;; - 4) - dotnet Fantasy.Tools.ConfigTable.dll --p 2 --e 2 - ;; - 5) - dotnet Fantasy.Tools.ConfigTable.dll --p 3 --e 1 - ;; - 6) - dotnet Fantasy.Tools.ConfigTable.dll --p 3 --e 2 - ;; - *) - echo "Invalid option" - ;; -esac diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Core/Base/ConsoleLog.cs b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Core/Base/ConsoleLog.cs deleted file mode 100644 index cbfc5a1..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Core/Base/ConsoleLog.cs +++ /dev/null @@ -1,176 +0,0 @@ -using System.Diagnostics; - -namespace Fantasy.Exporter; - -/// -/// 定义日志记录功能的接口。 -/// -public interface ILog -{ - /// - /// 记录跟踪级别的日志消息。 - /// - /// 日志消息。 - void Trace(string message); - /// - /// 记录警告级别的日志消息。 - /// - /// 日志消息。 - void Warning(string message); - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - void Info(string message); - /// - /// 记录调试级别的日志消息。 - /// - /// 日志消息。 - void Debug(string message); - /// - /// 记录错误级别的日志消息。 - /// - /// 日志消息。 - void Error(string message); - /// - /// 记录跟踪级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Trace(string message, params object[] args); - /// - /// 记录警告级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Warning(string message, params object[] args); - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Info(string message, params object[] args); - /// - /// 记录调试级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Debug(string message, params object[] args); - /// - /// 记录错误级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - void Error(string message, params object[] args); -} - -public static class Log -{ - private static readonly ILog LogCore; - - static Log() - { - LogCore = new ConsoleLog(); - } - - /// - /// 记录信息级别的日志消息。 - /// - /// 日志消息。 - public static void Info(string msg) - { - LogCore.Info(msg); - } - - /// - /// 记录错误级别的日志消息,并附带调用栈信息。 - /// - /// 日志消息。 - public static void Error(string msg) - { - var st = new StackTrace(1, true); - LogCore.Error($"{msg}\n{st}"); - } - - /// - /// 记录异常的错误级别的日志消息,并附带调用栈信息。 - /// - /// 异常对象。 - public static void Error(Exception e) - { - if (e.Data.Contains("StackTrace")) - { - LogCore.Error($"{e.Data["StackTrace"]}\n{e}"); - return; - } - - var str = e.ToString(); - LogCore.Error(str); - } - - /// - /// 记录信息级别的格式化日志消息。 - /// - /// 日志消息模板。 - /// 格式化参数。 - public static void Info(string message, params object[] args) - { - LogCore.Info(string.Format(message, args)); - } -} - -public class ConsoleLog : ILog -{ - public void Info(string message) - { - Console.WriteLine(message); - } - - public void Error(string message) - { - ConsoleColor color = Console.ForegroundColor; - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($"{message}\n{new StackTrace(1, true)}"); - Console.ForegroundColor = color; - } - - public void Trace(string message) - { - throw new NotImplementedException(); - } - - public void Warning(string message) - { - throw new NotImplementedException(); - } - - public void Debug(string message) - { - throw new NotImplementedException(); - } - - public void Trace(string message, params object[] args) - { - throw new NotImplementedException(); - } - - public void Warning(string message, params object[] args) - { - throw new NotImplementedException(); - } - - public void Info(string message, params object[] args) - { - throw new NotImplementedException(); - } - - public void Debug(string message, params object[] args) - { - throw new NotImplementedException(); - } - - public void Error(string message, params object[] args) - { - throw new NotImplementedException(); - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Core/Base/CustomSerialize.cs b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Core/Base/CustomSerialize.cs deleted file mode 100644 index ec5bc60..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Core/Base/CustomSerialize.cs +++ /dev/null @@ -1,13 +0,0 @@ -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace Fantasy.Tools.ProtocalExporter; - -public sealed class CustomSerialize -{ - public string NameSpace { get; set; } - public int KeyIndex { get; set; } - public string SerializeName { get; set; } - public string Attribute { get; set; } - public string Ignore { get; set; } - public string Member { get; set; } - public uint OpCodeType { get; set; } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Core/Base/ExportPlatform.cs b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Core/Base/ExportPlatform.cs deleted file mode 100644 index c7ed325..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Core/Base/ExportPlatform.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Fantasy.Tools; - -/// -/// 导出目标平台枚举,用于标识导出到哪个平台。 -/// -[Flags] -public enum ExportPlatform : byte -{ - None = 0, - Client = 1, - Server = 1 << 1, - All = Client | Server, -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Exporter/OpCodeCache.cs b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Exporter/OpCodeCache.cs deleted file mode 100644 index 6fd8af0..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Exporter/OpCodeCache.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Fantasy.Helper; - -namespace Fantasy.Tools.ProtocalExporter; - -internal class OpCodeCache -{ - private readonly List _opCodes = new List(); - private readonly Dictionary _opcodeCache; - private readonly Dictionary _saveOpCodeCache = new(); - private readonly string _opcodeCachePath = $"{ExporterSettingsHelper.NetworkProtocolDirectory}OpCode.Cache"; - - /// - /// 构造函数,用于初始化网络协议操作码缓存 - /// - public OpCodeCache(bool regenerate) - { - if (File.Exists(_opcodeCachePath) && !regenerate) - { - var readAllText = File.ReadAllText(_opcodeCachePath); - _opcodeCache = readAllText.Deserialize>(); - _opCodes.AddRange(_opcodeCache.Values); - } - else - { - _opcodeCache = new Dictionary(); - } - } - - /// - /// 保存网络协议操作码 - /// - public void Save() - { - File.WriteAllText(_opcodeCachePath, _saveOpCodeCache.ToJson()); - } - - /// - /// 根据className获得OpCode、如果是新增的会产生一个新的OpCode - /// - /// 协议名 - /// 操作码 - /// - public uint GetOpcodeCache(string className, ref uint opcode) - { - if (!_opcodeCache.TryGetValue(className, out var opCode)) - { - while (_opCodes.Contains(++opcode)) - { - - } - opCode = opcode; - _opCodes.Add(opCode); - } - - _saveOpCodeCache.Add(className, opCode); - return opCode; - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Exporter/ProtocolExporter.cs b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Exporter/ProtocolExporter.cs deleted file mode 100644 index f59b1db..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Exporter/ProtocolExporter.cs +++ /dev/null @@ -1,961 +0,0 @@ -using System.Text; -using Fantasy.Exporter; -using Fantasy.Helper; -using Fantasy.Network; -using OpCode = Fantasy.Network.OpCode; -using OpCodeType = Fantasy.Network.OpCodeType; - -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -// ReSharper disable PossibleNullReferenceException -// ReSharper disable ConditionIsAlwaysTrueOrFalse -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8604 // Possible null reference argument. - -namespace Fantasy.Tools.ProtocalExporter; - -public enum NetworkProtocolOpCodeType -{ - None = 0, - Outer = 1, - Inner = 2, -} - -public sealed class OpcodeInfo -{ - public uint Code; - public string Name; -} - -public sealed class ProtocolExporter -{ - private string _serverTemplate; - private string _clientTemplate; - private readonly List _opcodes = new(); - private static readonly char[] SplitChars = [' ', '\t']; - private readonly string _networkProtocolDirectory; - private readonly string _networkProtocolClientDirectory; - private readonly string _networkProtocolServerDirectory; - private readonly string _networkProtocolDirectoryOuter; - private readonly string _networkProtocolDirectoryInner; - - public ProtocolExporter() - { - Console.OutputEncoding = Encoding.UTF8; - - if (ExporterSettingsHelper.NetworkProtocolDirectory == null || - ExporterSettingsHelper.NetworkProtocolDirectory.Trim() == "") - { - Log.Info($"NetworkProtocolDirectory Can not be empty!"); - return; - } - - _networkProtocolDirectory = ExporterSettingsHelper.NetworkProtocolDirectory; - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Client)) - { - if (ExporterSettingsHelper.NetworkProtocolClientDirectory?.Trim() == "") - { - Log.Info($"NetworkProtocolClientDirectory Can not be empty!"); - return; - } - - _networkProtocolClientDirectory = ExporterSettingsHelper.NetworkProtocolClientDirectory ?? string.Empty; - if (!Directory.Exists(_networkProtocolClientDirectory)) - { - Directory.CreateDirectory(_networkProtocolClientDirectory); - } - } - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server)) - { - if (ExporterSettingsHelper.NetworkProtocolServerDirectory?.Trim() == "") - { - Log.Info($"NetworkProtocolServerDirectory Can not be empty!"); - return; - } - - _networkProtocolServerDirectory = ExporterSettingsHelper.NetworkProtocolServerDirectory ?? string.Empty; - if (!Directory.Exists(_networkProtocolServerDirectory)) - { - Directory.CreateDirectory(_networkProtocolServerDirectory); - } - - _networkProtocolDirectoryInner = $"{_networkProtocolDirectory}Inner"; - - if (!Directory.Exists(_networkProtocolDirectoryInner)) - { - Directory.CreateDirectory(_networkProtocolDirectoryInner); - } - } - - _networkProtocolDirectoryOuter = $"{_networkProtocolDirectory}Outer"; - - if (!Directory.Exists(_networkProtocolDirectoryOuter)) - { - Directory.CreateDirectory(_networkProtocolDirectoryOuter); - } - } - - public void Run() - { - var tasks = new Task[3]; - tasks[0] = Task.Run(RouteType); - tasks[1] = Task.Run(RoamingType); - tasks[2] = Task.Run(async () => - { - LoadTemplate(); - await Start(NetworkProtocolOpCodeType.Outer); - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server)) - { - await Start(NetworkProtocolOpCodeType.Inner); - } - }); - Task.WaitAll(tasks); - } - - private async Task Start(NetworkProtocolOpCodeType opCodeType) - { - var className = ""; - var opCodeName = ""; - var file = new StringBuilder(); - var messageStr = new StringBuilder(); - var disposeStr = new StringBuilder(); - var errorCodeStr = new StringBuilder(); - var usingNamespace = new HashSet(); - var saveDirectory = new Dictionary(); - - OpcodeInfo opcodeInfo = null; - ProtocolOpCode protocolOpCode = null; - string[] protocolFiles = null; - _opcodes.Clear(); - - switch (opCodeType) - { - case NetworkProtocolOpCodeType.Outer: - { - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server)) - { - saveDirectory.Add(_networkProtocolServerDirectory, _serverTemplate); - } - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Client)) - { - saveDirectory.Add(_networkProtocolClientDirectory, _clientTemplate); - } - - protocolOpCode = new ProtocolOpCode() - { - Message = OpCodeType.OuterMessage, - Request = OpCodeType.OuterRequest, - Response = OpCodeType.OuterResponse, - RouteMessage = 0, - RouteRequest = 0, - RouteResponse = 0, - AddressableMessage = OpCodeType.OuterAddressableMessage, - AddressableRequest = OpCodeType.OuterAddressableRequest, - AddressableResponse = OpCodeType.OuterAddressableResponse, - CustomRouteMessage = OpCodeType.OuterCustomRouteMessage, - CustomRouteRequest = OpCodeType.OuterCustomRouteRequest, - CustomRouteResponse = OpCodeType.OuterCustomRouteResponse, - RoamingMessage = OpCodeType.OuterRoamingMessage, - RoamingRequest = OpCodeType.OuterRoamingRequest, - RoamingResponse = OpCodeType.OuterRoamingResponse, - }; - opCodeName = "OuterOpcode"; - protocolFiles = FileHelper.GetDirectoryFile(_networkProtocolDirectoryOuter, "*.proto", - SearchOption.AllDirectories); - break; - } - case NetworkProtocolOpCodeType.Inner: - { - protocolOpCode = new ProtocolOpCode() - { - Message = OpCodeType.InnerMessage, - Request = OpCodeType.InnerRequest, - Response = OpCodeType.InnerResponse, - RouteMessage = OpCodeType.InnerRouteMessage, - RouteRequest = OpCodeType.InnerRouteRequest, - RouteResponse = OpCodeType.InnerRouteResponse, - AddressableMessage = OpCodeType.InnerAddressableMessage, - AddressableRequest = OpCodeType.InnerAddressableRequest, - AddressableResponse = OpCodeType.InnerAddressableResponse, - CustomRouteMessage = 0, - CustomRouteRequest = 0, - CustomRouteResponse = 0, - RoamingMessage = OpCodeType.InnerRoamingMessage, - RoamingRequest = OpCodeType.InnerRoamingRequest, - RoamingResponse = OpCodeType.InnerRoamingResponse, - }; - opCodeName = "InnerOpcode"; - saveDirectory.Add(_networkProtocolServerDirectory, _serverTemplate); - protocolFiles = FileHelper.GetDirectoryFile(_networkProtocolDirectoryInner, "*.proto", - SearchOption.AllDirectories); - break; - } - } - - if (protocolFiles == null || protocolFiles.Length == 0) - { - return; - } - - #region GenerateFiles - - foreach (var filePath in protocolFiles) - { - var keyIndex = 1; - var parameter = ""; - var hasOpCode = false; - var isMsgHead = false; - var isSetProtocol = false; - string responseTypeStr = null; - string customRouteType = null; - string protocolMember = "ProtoMember"; - string protocolType = "\t[ProtoContract]"; - string protocolIgnore = "\t\t[ProtoIgnore]"; - var protocolOpCodeType = OpCodeProtocolType.ProtoBuf; - var fileText = await File.ReadAllTextAsync(filePath); - - foreach (var line in fileText.Split('\n')) - { - var currentLine = line.Trim(); - - if (string.IsNullOrWhiteSpace(currentLine)) - { - continue; - } - - if (currentLine.StartsWith("///")) - { - messageStr.AppendFormat(" /// \r\n" + " /// {0}\r\n" + " /// \r\n", - currentLine.Substring("///".Length)); - continue; - } - - if (currentLine.StartsWith("// Protocol")) - { - isSetProtocol = true; - var protocol = currentLine.Substring("// Protocol".Length).Trim(); - - switch (protocol) - { - case "ProtoBuf": - { - protocolType = "\t[ProtoContract]"; - protocolIgnore = "\t\t[ProtoIgnore]"; - protocolMember = "ProtoMember"; - protocolOpCodeType = OpCodeProtocolType.ProtoBuf; - break; - } - // case "MemoryPack": - // { - // keyIndex = 0; - // protocolType = "\t[MemoryPackable]"; - // protocolIgnore = "\t\t[MemoryPackIgnore]"; - // protocolMember = "MemoryPackOrder"; - // // protocolOpCodeType = OpCodeProtocolType.MemoryPack; - // break; - // } - case "Bson": - { - if (opCodeType == NetworkProtocolOpCodeType.Outer) - { - Log.Error("Under Outer, /// does not support the Bson protocol!"); - return; - } - - protocolType = null; - protocolIgnore = "\t\t[BsonIgnore]"; - protocolMember = null; - protocolOpCodeType = OpCodeProtocolType.Bson; - break; - } - default: - { - if (!ExporterSettingsHelper.CustomSerializes.TryGetValue(protocol, out var customSerialize)) - { - Log.Error($"// Protocol {protocol} is not supported!"); - return; - } - - usingNamespace.Add(customSerialize.NameSpace); - keyIndex = customSerialize.KeyIndex; - protocolType = customSerialize.Attribute; - protocolIgnore = customSerialize.Ignore; - protocolMember = customSerialize.Member; - protocolOpCodeType = customSerialize.OpCodeType; - break; - } - } - } - - if (currentLine.StartsWith("message")) - { - isMsgHead = true; - className = currentLine.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries)[1]; - var splits = currentLine.Split(new[] { "//" }, StringSplitOptions.RemoveEmptyEntries); - - if (isSetProtocol) - { - if (protocolType != null) - { - messageStr.AppendLine(protocolType); - } - } - else - { - messageStr.AppendLine("\t[ProtoContract]"); - } - - if (splits.Length > 1) - { - hasOpCode = true; - var parameterArray = currentLine.Split(new[] { "//" }, StringSplitOptions.RemoveEmptyEntries)[1] - .Trim().Split(','); - parameter = parameterArray[0].Trim(); - opcodeInfo = new OpcodeInfo() - { - Name = className - }; - switch (parameterArray.Length) - { - case 2: - { - switch (parameter) - { - case "ICustomRouteMessage": - { - customRouteType = $"Fantasy.RouteType.{parameterArray[1].Trim()}"; - break; - } - case "IRoamingMessage": - { - customRouteType = $"Fantasy.RoamingType.{parameterArray[1].Trim()}"; - break; - } - default: - { - responseTypeStr = parameterArray[1].Trim(); - break; - } - } - - break; - } - case 3: - { - responseTypeStr = parameterArray[1].Trim(); - customRouteType = parameter.Contains("IRoaming") - ? $"Fantasy.RoamingType.{parameterArray[2].Trim()}" - : $"Fantasy.RouteType.{parameterArray[2].Trim()}"; - break; - } - } - } - else - { - parameter = ""; - hasOpCode = false; - } - - messageStr.Append(string.IsNullOrWhiteSpace(parameter) - ? $"\tpublic partial class {className} : AMessage" - : $"\tpublic partial class {className} : AMessage, {parameter}"); - if (protocolMember == "ProtoMember") - { - messageStr.Append(", IProto"); - } - - continue; - } - - if (!isMsgHead) - { - continue; - } - - switch (currentLine) - { - case "{": - { - messageStr.AppendLine("\n\t{"); - messageStr.AppendLine($"\t\tpublic static {className} Create(Scene scene)"); - messageStr.AppendLine( - $"\t\t{{\n\t\t\treturn scene.MessagePoolComponent.Rent<{className}>();\n\t\t}}"); - messageStr.AppendLine($"\t\tpublic override void Dispose()"); - messageStr.AppendLine($"\t\t{{"); - messageStr.AppendLine( - $"<<<>>#if FANTASY_NET || FANTASY_UNITY\n\t\t\tGetScene().MessagePoolComponent.Return<{className}>(this);\n#endif"); - messageStr.AppendLine($"\t\t}}"); - - if (parameter == "IMessage") - { - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, protocolOpCode.Message, - protocolOpCode.AMessage++); - messageStr.AppendLine($"\t\tpublic uint OpCode() {{ return {opCodeName}.{className}; }}"); - } - else - { - if (responseTypeStr != null) - { - messageStr.AppendLine(protocolIgnore); - messageStr.AppendLine($"\t\tpublic {responseTypeStr} ResponseType {{ get; set; }}"); - responseTypeStr = null; - } - else - { - if (parameter.Contains("RouteRequest")) - { - Log.Error($"{opcodeInfo.Name} 没指定ResponseType"); - return; - } - } - - if (hasOpCode) - { - messageStr.AppendLine( - $"\t\tpublic uint OpCode() {{ return {opCodeName}.{className}; }}"); - } - - if (customRouteType != null) - { - messageStr.AppendLine(protocolIgnore); - messageStr.AppendLine($"\t\tpublic int RouteType => {customRouteType};"); - customRouteType = null; - } - - switch (parameter) - { - case "IRequest": - { - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, protocolOpCode.Request, - protocolOpCode.ARequest++); - break; - } - case "IResponse": - { - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, protocolOpCode.Response, - protocolOpCode.AResponse++); - if (!string.IsNullOrEmpty(protocolMember)) - { - errorCodeStr.AppendLine($"\t\t[{protocolMember}(ErrorCodeKeyIndex)]"); - } - - errorCodeStr.AppendLine("\t\tpublic uint ErrorCode { get; set; }"); - disposeStr.AppendLine($"\t\t\tErrorCode = default;"); - break; - } - default: - { - switch (parameter) - { - case "IAddressableRouteMessage": - { - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.AddressableMessage, - protocolOpCode.AAddressableMessage++); - break; - } - case "IAddressableRouteRequest": - { - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.AddressableRequest, - protocolOpCode.AAddressableRequest++); - break; - } - case "IAddressableRouteResponse": - { - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.AddressableResponse, - protocolOpCode.AAddressableResponse++); - if (!string.IsNullOrEmpty(protocolMember)) - { - errorCodeStr.AppendLine($"\t\t[{protocolMember}(ErrorCodeKeyIndex)]"); - } - - errorCodeStr.AppendLine("\t\tpublic uint ErrorCode { get; set; }"); - disposeStr.AppendLine($"\t\t\tErrorCode = default;"); - break; - } - case "ICustomRouteMessage": - { - if (opCodeType == NetworkProtocolOpCodeType.Inner) - { - throw new NotSupportedException( - "Under Inner, /// does not support the ICustomRouteMessage!"); - } - - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.CustomRouteMessage, - protocolOpCode.ACustomRouteMessage++); - break; - } - case "ICustomRouteRequest": - { - if (opCodeType == NetworkProtocolOpCodeType.Inner) - { - throw new NotSupportedException( - "Under Inner, /// does not support the ICustomRouteMessage!"); - } - - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.CustomRouteRequest, - protocolOpCode.ACustomRouteRequest++); - break; - } - case "ICustomRouteResponse": - { - if (opCodeType == NetworkProtocolOpCodeType.Inner) - { - throw new NotSupportedException( - "Under Inner, /// does not support the ICustomRouteMessage!"); - } - - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.CustomRouteResponse, - protocolOpCode.ACustomRouteResponse++); - if (!string.IsNullOrEmpty(protocolMember)) - { - errorCodeStr.AppendLine($"\t\t[{protocolMember}(ErrorCodeKeyIndex)]"); - } - - errorCodeStr.AppendLine("\t\tpublic uint ErrorCode { get; set; }"); - disposeStr.AppendLine($"\t\t\tErrorCode = default;"); - break; - } - case "IRoamingMessage": - { - // if (opCodeType == NetworkProtocolOpCodeType.Inner) - // { - // throw new NotSupportedException("Under Inner, /// does not support the IRoamingMessage!"); - // } - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.RoamingMessage, protocolOpCode.ARoamingMessage++); - break; - } - case "IRoamingRequest": - { - // if (opCodeType == NetworkProtocolOpCodeType.Inner) - // { - // throw new NotSupportedException("Under Inner, /// does not support the IRoamingRequest!"); - // } - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.RoamingRequest, protocolOpCode.ARoamingRequest++); - break; - } - case "IRoamingResponse": - { - // if (opCodeType == NetworkProtocolOpCodeType.Inner) - // { - // throw new NotSupportedException("Under Inner, /// does not support the IRoamingResponse!"); - // } - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.RoamingResponse, protocolOpCode.ARoamingResponse++); - if (!string.IsNullOrEmpty(protocolMember)) - { - errorCodeStr.AppendLine($"\t\t[{protocolMember}(ErrorCodeKeyIndex)]"); - } - - errorCodeStr.AppendLine("\t\tpublic uint ErrorCode { get; set; }"); - disposeStr.AppendLine($"\t\t\tErrorCode = default;"); - break; - } - case "IRouteMessage": - { - if (opCodeType == NetworkProtocolOpCodeType.Outer) - { - throw new NotSupportedException( - "Under Inner, /// does not support the ICustomRouteMessage!"); - } - - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.RouteMessage, protocolOpCode.ARouteMessage++); - break; - } - case "IRouteRequest": - { - if (opCodeType == NetworkProtocolOpCodeType.Outer) - { - throw new NotSupportedException( - "Under Inner, /// does not support the ICustomRouteMessage!"); - } - - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.RouteRequest, protocolOpCode.ARouteRequest++); - break; - } - case "IRouteResponse": - { - if (opCodeType == NetworkProtocolOpCodeType.Outer) - { - throw new NotSupportedException( - "Under Inner, /// does not support the ICustomRouteMessage!"); - } - - opcodeInfo.Code = OpCode.Create(protocolOpCodeType, - protocolOpCode.RouteResponse, protocolOpCode.ARouteResponse++); - if (!string.IsNullOrEmpty(protocolMember)) - { - errorCodeStr.AppendLine($"\t\t[{protocolMember}(ErrorCodeKeyIndex)]"); - } - - errorCodeStr.AppendLine("\t\tpublic uint ErrorCode { get; set; }"); - disposeStr.AppendLine($"\t\t\tErrorCode = default;"); - break; - } - } - - break; - } - } - } - - if (hasOpCode) - { - _opcodes.Add(opcodeInfo); - } - - continue; - } - case "}": - { - isMsgHead = false; - errorCodeStr = errorCodeStr.Replace("ErrorCodeKeyIndex", keyIndex.ToString()); - messageStr = messageStr.Replace("<<<>>", disposeStr.ToString()); - messageStr.Append(errorCodeStr); - messageStr.AppendLine("\t}"); - file.Append(messageStr); - messageStr.Clear(); - disposeStr.Clear(); - errorCodeStr.Clear(); - keyIndex = 1; - protocolType = "\t[ProtoContract]"; - protocolIgnore = "\t\t[ProtoIgnore]"; - protocolMember = "ProtoMember"; - protocolOpCodeType = OpCodeProtocolType.ProtoBuf; - continue; - } - case "": - { - continue; - } - } - - if (currentLine.StartsWith("//")) - { - messageStr.AppendFormat("\t\t///\r\n" + "\t\t/// {0}\r\n" + "\t\t///\r\n", - currentLine.TrimStart('/', '/')); - continue; - } - - if (currentLine.StartsWith("repeated")) - { - Repeated(messageStr, disposeStr, currentLine, protocolMember, ref keyIndex); - } - else - { - Members(messageStr, disposeStr, currentLine, protocolMember, ref keyIndex); - } - } - - var namespaceBuilder = new StringBuilder(); - - foreach (var @namespace in usingNamespace) - { - namespaceBuilder.Append($"using {@namespace};\n"); - } - - var csName = $"{Path.GetFileNameWithoutExtension(filePath)}.cs"; - foreach (var (directory, template) in saveDirectory) - { - var csFile = Path.Combine(directory, csName); - var content = template.Replace("(Content)", file.ToString()); - content = content.Replace("(UsingNamespace)", namespaceBuilder.ToString()); - await File.WriteAllTextAsync(csFile, content); - } - - file.Clear(); - } - - #endregion - - #region GenerateOpCode - - file.Clear(); - file.AppendLine("namespace Fantasy"); - file.AppendLine("{"); - file.AppendLine($"\tpublic static partial class {opCodeName}"); - file.AppendLine("\t{"); - - foreach (var opcode in _opcodes) - { - file.AppendLine($"\t\t public const uint {opcode.Name} = {opcode.Code};"); - } - - _opcodes.Clear(); - file.AppendLine("\t}"); - file.AppendLine("}"); - - foreach (var (directory, _) in saveDirectory) - { - var csFile = Path.Combine(directory, $"{opCodeName}.cs"); - await File.WriteAllTextAsync(csFile, file.ToString()); - } - - #endregion - } - - private void Repeated(StringBuilder file, StringBuilder disposeStr, string newline, string protocolMember, - ref int keyIndex) - { - try - { - var index = newline.IndexOf(";", StringComparison.Ordinal); - newline = newline.Remove(index); - var property = newline.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries); - var type = property[1]; - var name = property[2]; - // var memberIndex = int.Parse(property[4]); - type = ConvertType(type); - - file.AppendLine($"\t\t[{protocolMember}({keyIndex++})]"); - file.AppendLine($"\t\tpublic List<{type}> {name} = new List<{type}>();"); - disposeStr.AppendLine($"\t\t\t{name}.Clear();"); - } - catch (Exception e) - { - Log.Error($"{newline}\n {e}"); - } - } - - private void Members(StringBuilder file, StringBuilder disposeStr, string currentLine, string protocolMember, - ref int keyIndex) - { - try - { - var index = currentLine.IndexOf(";", StringComparison.Ordinal); - currentLine = currentLine.Remove(index); - var property = currentLine.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries); - var type = property[0]; - var name = property[1]; - // var memberIndex = int.Parse(property[3]); - var typeCs = ConvertType(type); - if (protocolMember != null) - { - file.AppendLine($"\t\t[{protocolMember}({keyIndex++})]"); - } - - file.AppendLine($"\t\tpublic {typeCs} {name} {{ get; set; }}"); - disposeStr.AppendLine($"\t\t\t{name} = default;"); - } - catch (Exception e) - { - Log.Error($"{currentLine}\n {e}"); - } - } - - private string ConvertType(string type) - { - return type switch - { - "int[]" => "int[] { }", - "int32[]" => "int[] { }", - "int64[]" => "long[] { }", - "int32" => "int", - "uint32" => "uint", - "int64" => "long", - "uint64" => "ulong", - _ => type - }; - } - - private async Task RoamingType() - { - var routeTypeFile = $"{_networkProtocolDirectory}RoamingType.Config"; - var protoFileText = ""; - if (!File.Exists(routeTypeFile)) - { - protoFileText = "// Roaming协议定义(需要定义10000以上、因为10000以内的框架预留)\n"; - await File.WriteAllTextAsync(routeTypeFile, protoFileText); - } - else - { - protoFileText = await File.ReadAllTextAsync(routeTypeFile); - } - - var roamingTypes = new HashSet(); - var roamingTypeFileSb = new StringBuilder(); - roamingTypeFileSb.AppendLine("using System.Collections.Generic;"); - roamingTypeFileSb.AppendLine("namespace Fantasy\n{"); - roamingTypeFileSb.AppendLine("\t// Roaming协议定义(需要定义10000以上、因为10000以内的框架预留)\t"); - roamingTypeFileSb.AppendLine("\tpublic static class RoamingType\n\t{"); - - foreach (var line in protoFileText.Split('\n')) - { - var currentLine = line.Trim(); - - if (currentLine == "" || currentLine.StartsWith("//")) - { - continue; - } - - var splits = currentLine.Split(["//"], StringSplitOptions.RemoveEmptyEntries); - var routeTypeStr = splits[0].Split("=", StringSplitOptions.RemoveEmptyEntries); - var roamingType = routeTypeStr[1].Trim(); - roamingTypes.Add(int.Parse(roamingType)); - roamingTypeFileSb.Append($"\t\tpublic const int {routeTypeStr[0].Trim()} = {roamingType};"); - - if (splits.Length > 1) - { - roamingTypeFileSb.Append($" // {splits[1].Trim()}\n"); - } - else - { - roamingTypeFileSb.Append('\n'); - } - } - - if (roamingTypes.Count > 0) - { - roamingTypeFileSb.AppendLine("\t\tpublic static IEnumerable RoamingTypes"); - roamingTypeFileSb.AppendLine("\t\t{\n\t\t\tget\n\t\t\t{"); - foreach (var roamingType in roamingTypes) - { - roamingTypeFileSb.AppendLine($"\t\t\t\tyield return {roamingType};"); - } - - roamingTypeFileSb.AppendLine("\t\t\t}\n\t\t}"); - } - - - roamingTypeFileSb.AppendLine("\t}\n}"); - var file = roamingTypeFileSb.ToString(); - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server)) - { - await File.WriteAllTextAsync($"{_networkProtocolServerDirectory}RoamingType.cs", file); - } - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Client)) - { - await File.WriteAllTextAsync($"{_networkProtocolClientDirectory}RoamingType.cs", file); - } - } - - private async Task RouteType() - { - var routeTypeFile = $"{_networkProtocolDirectory}RouteType.Config"; - var protoFileText = ""; - if (!File.Exists(routeTypeFile)) - { - protoFileText = "// Route协议定义(需要定义1000以上、因为1000以内的框架预留)\n"; - await File.WriteAllTextAsync(routeTypeFile, protoFileText); - } - else - { - protoFileText = await File.ReadAllTextAsync(routeTypeFile); - } - - var routeTypeFileSb = new StringBuilder(); - routeTypeFileSb.AppendLine("namespace Fantasy\n{"); - routeTypeFileSb.AppendLine("\t// Route协议定义(需要定义1000以上、因为1000以内的框架预留)\t"); - routeTypeFileSb.AppendLine("\tpublic static class RouteType\n\t{"); - - foreach (var line in protoFileText.Split('\n')) - { - var currentLine = line.Trim(); - - if (currentLine.StartsWith("//")) - { - continue; - } - - var splits = currentLine.Split(new[] { "//" }, StringSplitOptions.RemoveEmptyEntries); - var routeTypeStr = splits[0].Split("=", StringSplitOptions.RemoveEmptyEntries); - routeTypeFileSb.Append($"\t\tpublic const int {routeTypeStr[0].Trim()} = {routeTypeStr[1].Trim()};"); - - if (splits.Length > 1) - { - routeTypeFileSb.Append($" // {splits[1].Trim()}\n"); - } - else - { - routeTypeFileSb.Append('\n'); - } - } - - routeTypeFileSb.AppendLine("\t}\n}"); - var file = routeTypeFileSb.ToString(); - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Server)) - { - await File.WriteAllTextAsync($"{_networkProtocolServerDirectory}RouteType.cs", file); - } - - if (ExporterAges.Instance.ExportPlatform.HasFlag(ExportPlatform.Client)) - { - await File.WriteAllTextAsync($"{_networkProtocolClientDirectory}RouteType.cs", file); - } - } - - - private void LoadTemplate() - { - // 获取当前运行根目录(即应用程序的工作目录) - string currentDirectory = Directory.GetCurrentDirectory(); - string filePath = Path.Combine(currentDirectory, "Template.txt"); - - // 读取文件所有行 - string[] lines = File.ReadAllLines(filePath); - - StringBuilder serverSb = new StringBuilder(); - StringBuilder clientSb = new StringBuilder(); - - int flag = 0; - foreach (string line in lines) - { - string trim = line.Trim(); - - if (trim.StartsWith("#if") && trim.Contains("SERVER")) - { - flag = 1; - continue; - } - - if (trim.StartsWith("#else")) - { - flag = 2; - continue; - } - - if (trim.StartsWith($"#endif")) - { - flag = 0; - continue; - } - - switch (flag) - { - case 1: // 服务端 - { - serverSb.AppendLine(line); - break; - } - case 2: // 客户端 - { - clientSb.AppendLine(line); - break; - } - default: // 双端 - { - serverSb.AppendLine(line); - clientSb.AppendLine(line); - break; - } - } - } - - _serverTemplate = serverSb.Replace("(NetworkProtocol)", "ProtoBuf").ToString(); - _clientTemplate = clientSb.Replace("(NetworkProtocol)", "ProtoBuf").ToString(); - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Exporter/ProtocolOpCode.cs b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Exporter/ProtocolOpCode.cs deleted file mode 100644 index ec62d3a..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Exporter/ProtocolOpCode.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Fantasy.Tools.ProtocalExporter; - -public class ProtocolOpCode -{ - private const int Start = 10001; - - public uint Message; - public uint Request; - public uint Response; - public uint RouteMessage; - public uint RouteRequest; - public uint RouteResponse; - public uint AddressableMessage; - public uint AddressableRequest; - public uint AddressableResponse; - public uint CustomRouteMessage; - public uint CustomRouteRequest; - public uint CustomRouteResponse; - public uint RoamingMessage; - public uint RoamingRequest; - public uint RoamingResponse; - - public uint AMessage = Start; - public uint ARequest = Start; - public uint AResponse = Start; - public uint ARouteMessage = Start; - public uint ARouteRequest = Start; - public uint ARouteResponse = Start; - public uint AAddressableMessage = Start; - public uint AAddressableRequest = Start; - public uint AAddressableResponse = Start; - public uint ACustomRouteMessage = Start; - public uint ACustomRouteRequest = Start; - public uint ACustomRouteResponse = Start; - public uint ARoamingMessage = Start; - public uint ARoamingRequest = Start; - public uint ARoamingResponse = Start; -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/ExporterAges.cs b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/ExporterAges.cs deleted file mode 100644 index 8b55367..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/ExporterAges.cs +++ /dev/null @@ -1,18 +0,0 @@ -using CommandLine; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -namespace Fantasy.Tools; - -public class ExporterAges -{ - public static ExporterAges Instance; - /// - /// 导出目标平台枚举,用于标识导出到哪个平台 - /// - [Option('p',"ExportPlatform", Required = false, Default = ExportPlatform.None, HelpText = "Export target platform:\n/// Client target platform \nClient = 1\n/// Server target platform\nServer = 2\n/// Client and Server target platform\nAll = 3")] - public ExportPlatform ExportPlatform { get; set; } - - [Option('f',"Folder", Required = false, HelpText = "ExporterSetting.json file path")] - public string Folder { get; set; } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/ExporterSettings.json b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/ExporterSettings.json deleted file mode 100644 index 809f350..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/ExporterSettings.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "Export": { - "NetworkProtocolDirectory": { - "Value": "../../../Config/NetworkProtocol/", - "Comment": "ProtoBuf文件所在的文件夹位置" - }, - "NetworkProtocolServerDirectory": { - "Value": "../../../Entity/Generate/NetworkProtocol/", - "Comment": "ProtoBuf生成到服务端的文件夹位置" - }, - "NetworkProtocolClientDirectory": { - "Value": "../../../../Fishing2/Assets/Scripts/Generate/NetworkProtocol/", - "Comment": "ProtoBuf生成到客户端的文件夹位置" - }, - "Serializes": { - "Value": [ -// { -// "KeyIndex": 0, -// "NameSpace" : "MemoryPack", -// "SerializeName": "MemoryPack", -// "Attribute": "\t[MemoryPackable]", -// "Ignore": "\t\t[MemoryPackIgnore]", -// "Member": "MemoryPackOrder" -// } - ], - "Comment": "自定义序列化器" - } - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/ExporterSettingsHelper.cs b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/ExporterSettingsHelper.cs deleted file mode 100644 index 434b72a..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/ExporterSettingsHelper.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Fantasy.Exporter; -using Fantasy.Helper; -using Microsoft.Extensions.Configuration; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -#pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8604 // Possible null reference argument. - -namespace Fantasy.Tools.ProtocalExporter; - -public class ExporterSettingsHelper -{ - public static string? NetworkProtocolDirectory { get; private set; } - public static string NetworkProtocolServerDirectory { get; private set; } - public static string NetworkProtocolClientDirectory { get; private set; } - public static Dictionary CustomSerializes { get; private set; } - - public static void Initialize() - { - const string settingsName = "ExporterSettings.json"; - var currentDirectory = ExporterAges.Instance.Folder; - if (string.IsNullOrEmpty(currentDirectory)) - { - currentDirectory = Directory.GetCurrentDirectory(); - } - - if (!File.Exists(Path.Combine(currentDirectory, settingsName))) - { - throw new FileNotFoundException($"not found {settingsName} in OutputDirectory"); - } - - var root = new ConfigurationBuilder().SetBasePath(currentDirectory).AddJsonFile(settingsName).Build(); - - NetworkProtocolDirectory = FileHelper.GetFullPath(root["Export:NetworkProtocolDirectory:Value"], currentDirectory); - NetworkProtocolServerDirectory = FileHelper.GetFullPath(root["Export:NetworkProtocolServerDirectory:Value"], currentDirectory); - NetworkProtocolClientDirectory = FileHelper.GetFullPath(root["Export:NetworkProtocolClientDirectory:Value"], currentDirectory); - - CustomSerializes = []; - var sort = new SortedList(); - var arrayOfValuesSection = root.GetSection("Export:Serializes:Value"); - - foreach (var item in arrayOfValuesSection.GetChildren()) - { - var serializeItem = new CustomSerialize - { - KeyIndex = Convert.ToInt32(item.GetSection("KeyIndex").Value), - NameSpace = item.GetSection("NameSpace").Value, - SerializeName = item.GetSection("SerializeName").Value, - Attribute = item.GetSection("Attribute").Value, - Ignore = item.GetSection("Ignore").Value, - Member = item.GetSection("Member").Value - }; - - sort.Add(HashCodeHelper.ComputeHash64(serializeItem.SerializeName), serializeItem); - } - - for (var i = 0; i < sort.Count; i++) - { - var customSerialize = sort.GetValueAtIndex(i); - customSerialize.OpCodeType = (uint)(i + 2); - CustomSerializes.Add(customSerialize.SerializeName, customSerialize); - } - } -} \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Fantasy.Tools.NetworkProtocol.csproj b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Fantasy.Tools.NetworkProtocol.csproj deleted file mode 100644 index 01b17d9..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Fantasy.Tools.NetworkProtocol.csproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - Exe - enable - enable - default - net8.0;net9.0 - - - - false - en - - - - true - ../../Exporter/NetworkProtocol/ - TRACE;FANTASY_NET - - - - true - ../../Exporter/NetworkProtocol/ - TRACE;FANTASY_NET - - - - - - - - - - - Core\FileHelper.cs - - - Core\HashCodeHelper.cs - - - Core\JsonHelper.cs - - - ProtocalExporter\OpCode.cs - - - Never - - - - - - Always - - - Always - - - Always - - - Always - - - - diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Program.cs b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Program.cs deleted file mode 100644 index 7f83f0c..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Program.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text; -using CommandLine; -using Fantasy.Exporter; -using Fantasy.Tools; -using Fantasy.Tools.ProtocalExporter; -// 解析命令行参数 -Parser.Default.ParseArguments(Environment.GetCommandLineArgs()) - .WithNotParsed(error => throw new Exception("Command line format error!")) - .WithParsed(ages => ExporterAges.Instance = ages); -try -{ - // 初始化配置 - ExporterSettingsHelper.Initialize(); - // 加载配置 - Console.OutputEncoding = Encoding.UTF8; - // 运行导出协议的代码 - new ProtocolExporter().Run(); -} -catch (Exception e) -{ - Log.Error(e); -} -finally -{ - Log.Info("按任意键退出程序"); - Console.ReadKey(); - Environment.Exit(0); -} diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Properties/launchSettings.json b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Properties/launchSettings.json deleted file mode 100644 index 02fbcba..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Properties/launchSettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "profiles": { - "Fantasy.Tools.NetworkProtocol": { - "commandName": "Project", - "environmentVariables": {}, - "commandLineArgs": "--ExportPlatform 3" - } - } -} diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Run.bat b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Run.bat deleted file mode 100644 index fe41258..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Run.bat +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -echo Please select an option: -echo 1. Client -echo 2. Server -echo 3. All - -set /p choice=Please select an option: - -if "%choice%"=="1" ( - echo Client - dotnet Fantasy.Tools.NetworkProtocol.dll --p 1 -) else if "%choice%"=="2" ( - echo Server - dotnet Fantasy.Tools.NetworkProtocol.dll --p 2 -) else if "%choice%"=="3" ( - echo All - dotnet Fantasy.Tools.NetworkProtocol.dll --p 3 -) else ( - echo Invalid option -) \ No newline at end of file diff --git a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Run.sh b/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Run.sh deleted file mode 100644 index d5ed8b3..0000000 --- a/Tools/SourceCode/Fantasy.Tools.NetworkProtocol/Run.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -echo "1. Client" -echo "2. Server" -echo "3. All" - -read -n 1 -p "Please select an option:" choice -echo "" -echo "" -script_dir=$(cd $(dirname $0) && pwd) -case $choice in - 1) - dotnet $script_dir/Fantasy.Tools.NetworkProtocol.dll --p 1 --f $script_dir - ;; - 2) - dotnet $script_dir/Fantasy.Tools.NetworkProtocol.dll --p 2 --f $script_dir - ;; - 3) - dotnet $script_dir/Fantasy.Tools.NetworkProtocol.dll --p 3 --f $script_dir - ;; - *) - echo "Invalid option" - ;; -esac diff --git a/Tools/SourceCode/Fantasy.Tools.SourceCode.sln b/Tools/SourceCode/Fantasy.Tools.SourceCode.sln deleted file mode 100644 index 47d417f..0000000 --- a/Tools/SourceCode/Fantasy.Tools.SourceCode.sln +++ /dev/null @@ -1,44 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fantasy.Tools.NetworkProtocol", "Fantasy.Tools.NetworkProtocol\Fantasy.Tools.NetworkProtocol.csproj", "{72D45E2D-EF78-4D80-8BFC-ED95FA8543C7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fantasy.Tools.ConfigTable", "Fantasy.Tools.ConfigTable\Fantasy.Tools.ConfigTable.csproj", "{F01BD146-FDEA-46D6-9A08-F3CCF05D817E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{CCF6F6B1-50D8-4B0D-91B9-035CDCC4B1CA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fantasy.Tools.ExporterNetworkProtocol", "..\NuGet\Fantasy.Tools.ExporterNetworkProtocol\Fantasy.Tools.ExporterNetworkProtocol.csproj", "{E0F9231E-F057-4121-B167-7AC47D48E7E3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fantasy.Tools.ExporterConfigTable", "..\NuGet\Fantasy.Tools.ExporterConfigTable\Fantasy.Tools.ExporterConfigTable.csproj", "{5A236869-283F-4046-860B-E295963139AB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SourceCode", "SourceCode", "{A402EB74-8BF8-4A53-82F2-F77E59D9F4C6}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {72D45E2D-EF78-4D80-8BFC-ED95FA8543C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {72D45E2D-EF78-4D80-8BFC-ED95FA8543C7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {72D45E2D-EF78-4D80-8BFC-ED95FA8543C7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {72D45E2D-EF78-4D80-8BFC-ED95FA8543C7}.Release|Any CPU.Build.0 = Release|Any CPU - {F01BD146-FDEA-46D6-9A08-F3CCF05D817E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F01BD146-FDEA-46D6-9A08-F3CCF05D817E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F01BD146-FDEA-46D6-9A08-F3CCF05D817E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F01BD146-FDEA-46D6-9A08-F3CCF05D817E}.Release|Any CPU.Build.0 = Release|Any CPU - {E0F9231E-F057-4121-B167-7AC47D48E7E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E0F9231E-F057-4121-B167-7AC47D48E7E3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E0F9231E-F057-4121-B167-7AC47D48E7E3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E0F9231E-F057-4121-B167-7AC47D48E7E3}.Release|Any CPU.Build.0 = Release|Any CPU - {5A236869-283F-4046-860B-E295963139AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5A236869-283F-4046-860B-E295963139AB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5A236869-283F-4046-860B-E295963139AB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5A236869-283F-4046-860B-E295963139AB}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {E0F9231E-F057-4121-B167-7AC47D48E7E3} = {CCF6F6B1-50D8-4B0D-91B9-035CDCC4B1CA} - {5A236869-283F-4046-860B-E295963139AB} = {CCF6F6B1-50D8-4B0D-91B9-035CDCC4B1CA} - {F01BD146-FDEA-46D6-9A08-F3CCF05D817E} = {A402EB74-8BF8-4A53-82F2-F77E59D9F4C6} - {72D45E2D-EF78-4D80-8BFC-ED95FA8543C7} = {A402EB74-8BF8-4A53-82F2-F77E59D9F4C6} - EndGlobalSection -EndGlobal diff --git a/Tools/SourceCode/Fantasy.Tools.SourceCode.sln.DotSettings.user b/Tools/SourceCode/Fantasy.Tools.SourceCode.sln.DotSettings.user deleted file mode 100644 index a2fe3b5..0000000 --- a/Tools/SourceCode/Fantasy.Tools.SourceCode.sln.DotSettings.user +++ /dev/null @@ -1,22 +0,0 @@ - - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - <AssemblyExplorer> - <Assembly Path="/Users/sining/.nuget/packages/memorypack.core/1.21.1/lib/net8.0/MemoryPack.Core.dll" /> -</AssemblyExplorer> \ No newline at end of file