更新最新框架

This commit is contained in:
Bob.Song
2025-11-11 17:43:11 +08:00
parent 7b10d4cb31
commit fd3c6ec38d
1048 changed files with 11041 additions and 87002 deletions

35
.gitignore vendored
View File

@@ -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

13
.idea/.idea.Server/.idea/.gitignore generated vendored Normal file
View File

@@ -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

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@@ -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-----

View File

@@ -1,9 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz4LybzjFcMs4cAozF6Zr
qKZ7Ij1beTggJWGuLt9jMS20P4cxlreQRJyba85R0c4CNtGeaTbXKOsOUSVNusvk
YsZnDadvJFiFZhygOOex4nsXWpp04XQ1Ro7E2ffAWR0DVgHZpUdAFo8mhUntMP+6
gQy4Hm5/jhDcSn4GtdIu41YFX8LaJkwwcBZdnQ8C/q2Fca7e4lhbQLyem2lfVAI5
jV78vzB/aSAVDgCeprw5Kv8DUk06wV9Srp/zO2saIXmmeXw23S6x5zhHsCwI7J3E
Zdfl18BG4R2u1EJOKmuwyYVEJMetQk9lktfquOYNmdDeQmqKfgqVWT1gXcjZC23n
TQIDAQAB
-----END PUBLIC KEY-----

View File

@@ -1 +0,0 @@
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6EL7hSzceNVL5NFa8HLhtqvxEUHSVh8ChDRhHmltDyZ7pdsesiOBPS2lU++LztOrwNv4Q4KyUnoJ2OPHZAObaZyxXMW89SDJo8hkfx7mgPxhCtLxazcnBBoq+FVEbV24hRlYYpXpEkc2gAu7EmnphnCLpsMLn1WP2d+URxCNbHxy8IKD6Cl9NErKTgbmm5AB0bL+fd2vtxH/u3rVPBHM7Cu3rO37NjsUdY62nE88+IBp6jLT099F7ixz2mVqFeCvubnWv8vowl0Sj9zOhx+xz+h9UjysnJA0fPK6xl0s2ArGfGmNJNHQncAPxDj8t7t4/8oJr4oBiYrw4TChMikmwIDAQAB

View File

@@ -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==

View File

@@ -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
// 注意此方法仅用于热重载场景JITNative AOT 不支持动态加载
// 拿到Assembly就用EnsureLoaded()方法强制触发
assembly.EnsureLoaded();
return assembly;
}
}
}
}

View File

@@ -1,39 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<LangVersion>default</LangVersion>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Entity</RootNamespace>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>TRACE;FANTASY_NET</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Fantasy-Net" Version="2025.2.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.14.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.14.0" />
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>TRACE;FANTASY_NET</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ThirdParty\ThirdParty.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Fantasy\Fantasy.Net\Fantasy.Net\Fantasy.Net.csproj" />
<ProjectReference Include="..\Fantasy\Fantasy.Packages\Fantasy.ConfigTable\Net\Fantasy.ConfigTable.csproj" />
<ProjectReference Include="..\ThirdParty\ThirdParty.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.12.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.12.1" />
<PackageReference Include="ToolGood.Words" Version="3.1.0.2" />
</ItemGroup>
<ItemGroup>
<Folder Include="Game\Shop\" />
<Folder Include="Generate\ConfigTable\Entity\" />
<Folder Include="Generate\ConfigTable\Partial\" />
<Folder Include="Social\Entity\" />
<Folder Include="Social\Mail\" />
</ItemGroup>
</Project>
</Project>

77
Entity/Fantasy.config Normal file
View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<fantasy xmlns="http://fantasy.net/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://fantasy.net/config Fantasy.xsd">
<!-- ↓这是为了兼容旧版Fantasy的导表Json配置↓, 如果这个XML节点被注释掉, 就会以 Fantasy.config 配置为准 -->
<!--<configTable path="../../../../Config/Json/Server" />-->
<!-- ↓这是目前推荐使用的Fantasy框架启服配置↓ -->
<network inner="TCP" maxMessageSize="1048560" />
<session idleTimeout="8000" idleInterval="5000" />
<server>
<!-- 机器配置 -->
<machines>
<machine id="1" outerIP="127.0.0.1" outerBindIP="127.0.0.1" innerBindIP="127.0.0.1" />
</machines>
<!-- 进程配置 -->
<processes>
<process id="1" machineId="1" startupGroup="0" />
</processes>
<!-- 世界配置 -->
<worlds>
<world id="1" worldName="WorldA">
<database dbType="MongoDB" dbName="fantasy_main" dbConnection="mongodb://127.0.0.1" />
</world>
</worlds>
<!-- 场景配置 -->
<scenes>
<scene id="1001"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Authentication"
networkProtocol="KCP"
outerPort="20001" innerPort="11001" />
<scene id="1002"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Addressable"
networkProtocol=""
outerPort="0" innerPort="11011" />
<scene id="1003"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Gate"
networkProtocol="KCP"
outerPort="20000" innerPort="11021" />
<scene id="1004"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Game"
networkProtocol=""
outerPort="0" innerPort="11031" />
<scene id="1006"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Social"
networkProtocol=""
outerPort="0" innerPort="11051" />
<scene id="1007"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Map"
networkProtocol=""
outerPort="0" innerPort="11061" />
</scenes>
</server>
</fantasy>

345
Entity/Fantasy.xsd Normal file
View File

@@ -0,0 +1,345 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://fantasy.net/config"
xmlns="http://fantasy.net/config"
elementFormDefault="qualified">
<!-- Root element -->
<xs:element name="fantasy">
<xs:annotation>
<xs:documentation>Fantasy框架配置文件根元素</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="configTable" type="configTableType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>配置表路径设置</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="network" type="networkRuntimeType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>网络运行时配置</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="session" type="sessionRuntimeType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>会话运行时配置</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="server" type="serverType" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:documentation>服务器配置</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- ConfigTable type -->
<xs:complexType name="configTableType">
<xs:attribute name="path" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>配置表文件路径</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Server type -->
<xs:complexType name="serverType">
<xs:sequence>
<xs:element name="machines" type="machinesType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>机器配置列表</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="processes" type="processesType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>进程配置列表</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="worlds" type="worldsType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>世界配置列表</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="scenes" type="scenesType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>场景配置列表</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="units" type="unitsType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>单位配置列表</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<!-- Machines types -->
<xs:complexType name="machinesType">
<xs:sequence>
<xs:element name="machine" type="machineType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="machineType">
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>机器ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="outerIP" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>外网IP地址</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="outerBindIP" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>外网绑定IP地址</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="innerBindIP" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>内网绑定IP地址</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Processes types -->
<xs:complexType name="processesType">
<xs:sequence>
<xs:element name="process" type="processType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="processType">
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>进程ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="machineId" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>所属机器ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="startupGroup" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>启动分组</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Worlds types -->
<xs:complexType name="worldsType">
<xs:sequence>
<xs:element name="world" type="worldType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- database的选择 -->
<xs:complexType name="databaseType">
<xs:attribute name="dbType" use="required">
<xs:annotation>
<xs:documentation>数据库类型</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<!-- PostgreSQL -->
<xs:enumeration value="PostgreSQL"/>
<xs:enumeration value="Postgres"/>
<xs:enumeration value="PgSQL"/>
<xs:enumeration value="Pg"/>
<xs:enumeration value="PG"/>
<!-- MongoDB -->
<xs:enumeration value="MongoDB"/>
<xs:enumeration value="Mongo"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="dbName" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>数据库名称</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="dbConnection" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>数据库连接字符串</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="worldType">
<!-- 每个world允许包含1或n个database -->
<xs:sequence>
<xs:annotation>
<xs:documentation>世界中配置的数据库</xs:documentation>
</xs:annotation>
<xs:element name="database" type="databaseType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<!-- world需要id和worldName -->
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>世界ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="worldName" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>世界名称</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Scenes types -->
<xs:complexType name="scenesType">
<xs:sequence>
<xs:element name="scene" type="sceneType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sceneType">
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>场景ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="processConfigId" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>进程配置ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="worldConfigId" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>世界配置ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="sceneRuntimeMode" use="required">
<xs:annotation>
<xs:documentation>场景运行模式</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="MainThread"/>
<xs:enumeration value="MultiThread"/>
<xs:enumeration value="ThreadPool"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="sceneTypeString" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>场景类型字符串</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="networkProtocol" use="optional">
<xs:annotation>
<xs:documentation>网络协议类型</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="TCP"/>
<xs:enumeration value="KCP"/>
<xs:enumeration value="WebSocket"/>
<xs:enumeration value="HTTP"/>
<xs:enumeration value=""/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="outerPort" type="xs:unsignedInt" use="optional" default="0">
<xs:annotation>
<xs:documentation>外网端口</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="innerPort" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>内网端口</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Network Runtime type -->
<xs:complexType name="networkRuntimeType">
<xs:attribute name="inner" use="optional" default="TCP">
<xs:annotation>
<xs:documentation>服务器内部网络协议</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="TCP"/>
<xs:enumeration value="KCP"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="maxMessageSize" type="xs:int" use="optional" default="1048560">
<xs:annotation>
<xs:documentation>消息体最大长度(字节)默认1048560字节(约1.02MB)</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Session Runtime type -->
<xs:complexType name="sessionRuntimeType">
<xs:attribute name="idleTimeout" type="xs:int" use="optional" default="8000">
<xs:annotation>
<xs:documentation>Session idle check timeout (in milliseconds)</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="idleInterval" type="xs:int" use="optional" default="5000">
<xs:annotation>
<xs:documentation>Session idle check interval (in milliseconds)</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Units types -->
<xs:complexType name="unitsType">
<xs:sequence>
<xs:element name="unit" type="unitType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="unitType">
<xs:sequence>
<xs:element name="dic" type="unitDicType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>单位字典数据</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>单位ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>单位名称</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="model" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>单位模型</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="unitDicType">
<xs:sequence>
<xs:element name="item" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="key" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>字典键</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="value" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>字典值</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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<BobberConfig> Context => ConfigTableHelper.Table<BobberConfig>();
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<BobberConfig>(arr);
}
#endregion
}
}

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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<string, int> SceneTypeDic = new Dictionary<string, int>()
{
{ "Authentication", 1 },
{ "Addressable", 2 },
{ "Gate", 3 },
{ "Game", 4 },
{ "Map", 5 },
{ "Activity", 6 },
{ "Cache", 7 },
{ "Social", 8 },
};
}
}

View File

@@ -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
{
{
/// <summary>
/// 角色基础信息
/// </summary>
[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
/// 角色信息
/// </summary>
[ProtoContract]
public partial class RoleInfo : AMessage, IProto
public partial class RoleInfo : AMessage
{
public static RoleInfo Create(Scene scene)
{
@@ -123,7 +124,7 @@ namespace Fantasy
/// 角色信息
/// </summary>
[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信息
/// </summary>
[ProtoContract]
public partial class VipInfo : AMessage, IProto
public partial class VipInfo : AMessage
{
public static VipInfo Create(Scene scene)
{
@@ -187,7 +188,7 @@ namespace Fantasy
/// 奖励信息
/// </summary>
[ProtoContract]
public partial class AwardInfo : AMessage, IProto
public partial class AwardInfo : AMessage
{
public static AwardInfo Create(Scene scene)
{
@@ -210,7 +211,7 @@ namespace Fantasy
/// 玩家当前使用钓组信息
/// </summary>
[ProtoContract]
public partial class ItemBindInfo : AMessage, IProto
public partial class ItemBindInfo : AMessage
{
public static ItemBindInfo Create(Scene scene)
{
@@ -233,7 +234,7 @@ namespace Fantasy
/// 物品信息
/// </summary>
[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信息
/// </summary>
[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
/// 技能情况
/// </summary>
[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; }
}
}

View File

@@ -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
{
{
/// <summary>
/// /////////// ******** 物品信息 *******/////////////
/// </summary>
@@ -24,7 +25,7 @@ namespace Fantasy
/// 请求背包列表
/// </summary>
[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
/// 请求背包列表响应
/// </summary>
[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
/// 请求使用物品
/// </summary>
[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
/// 请求使用物品响应
/// </summary>
[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
/// 物品变化
/// </summary>
[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
/// 请求安装或取下配件
/// </summary>
[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
/// 请求安装配件响应
/// </summary>
[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
/// 请求鱼护列表
/// </summary>
[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
/// 请求鱼护列表响应
/// </summary>
[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
/// 鱼护变化
/// </summary>
[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
/// 请求出售
/// </summary>
[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
/// 请求出售响应
/// </summary>
[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
/// 请求购买
/// </summary>
[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
/// 请求购买响应
/// </summary>
[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; }
}
}

View File

@@ -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
{
{
/// <summary>
/// 通知游戏服角色进入该游戏服
/// </summary>
[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
/// 获取玩家基础信息
/// </summary>
[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
/// 获取玩家基础信息响应
/// </summary>
[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
/// 创建聊天频道
/// </summary>
[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
/// 请求进入房间
/// </summary>
[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
/// 请求进入房间响应
/// </summary>
[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
/// 请求离开房间
/// </summary>
[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
/// 请求离开房间响应
/// </summary>
[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; }
}
}

View File

@@ -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
{
{
/// <summary>
/// 请求创建房间
/// </summary>
[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
/// 请求创建房间成功
/// </summary>
[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
/// 请求网关离开房间(离开房间,但是不离开地图)
/// </summary>
[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
/// 请求网关进入离开响应
/// </summary>
[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
/// 请求网关进入地图
/// </summary>
[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
/// 请求网关进入房间响应
/// </summary>
[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
/// 通知客户端切换地图
/// </summary>
[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; }
}
}

View File

@@ -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
/// 玩家当前使用钓组信息
/// </summary>
[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<KeyValueInt64> Propertys = new List<KeyValueInt64>();
}
[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<KeyValueInt64> Propertys = new List<KeyValueInt64>();
}
[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<KeyValueInt64> Propertys = new List<KeyValueInt64>();
}
}

View File

@@ -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服务器
/// </summary>
[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
/// 通知客户端重复登录
/// </summary>
[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; }
}
}

View File

@@ -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
{
{
/// <summary>
/// 用户进入地图
/// </summary>
[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
/// 用户离开地图
/// </summary>
[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
/// 玩家状态变化同步
/// </summary>
[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
/// 玩家钓组变化
/// </summary>
[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<GearInfo> Gears = new List<GearInfo>();
}
[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<KeyValueInt64> Propertys = new List<KeyValueInt64>();
}
[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
/// 玩家移动推送
/// </summary>
[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
/// 玩家旋转推送
/// </summary>
[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; }
}
}

View File

@@ -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
{
{
/// <summary>
/// /////////// ******** 私聊/邮件 *******/////////////
/// </summary>
@@ -24,7 +25,7 @@ namespace Fantasy
/// 会话信息
/// </summary>
[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<MailInfo> List = new List<MailInfo>();
}
[ProtoContract]
public partial class MailInfo : AMessage, IProto
public partial class MailInfo : AMessage
{
public static MailInfo Create(Scene scene)
{
@@ -82,7 +83,7 @@ namespace Fantasy
/// 请求会话列表
/// </summary>
[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
/// 请求会话列表响应
/// </summary>
[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
/// 发送邮件消息
/// </summary>
[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
/// 发送邮件消息响应
/// </summary>
[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
/// 发送删除会话消息
/// </summary>
[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
/// 发送删除会话消息响应
/// </summary>
[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
/// 新邮件推送
/// </summary>
[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
/// /////////// ******** 频道聊天 *******/////////////
/// </summary>
[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
/// 创建频道
/// </summary>
[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
/// 创建频道响应
/// </summary>
[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
/// 请求进入频道
/// </summary>
[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
/// 进入频道响应
/// </summary>
[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
/// 发送消息
/// </summary>
[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
/// 发送消息响应
/// </summary>
[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
/// 推送消息
/// </summary>
[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
/// /////////// ******** 工会 *******/////////////
/// </summary>
[ProtoContract]
public partial class ClubInfo : AMessage, IProto
public partial class ClubInfo : AMessage
{
public static ClubInfo Create(Scene scene)
{
@@ -529,7 +530,7 @@ namespace Fantasy
/// 请求创建工会
/// </summary>
[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
/// 创建工会响应
/// </summary>
[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
/// 请求工会信息
/// </summary>
[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
/// 响应工会信息
/// </summary>
[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
/// 请求工会成员列表
/// </summary>
[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
/// 响应工会成员列表
/// </summary>
[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
/// 获取工会列表请求
/// </summary>
[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
/// 获取工会列表响应
/// </summary>
[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
/// 请求加入工会
/// </summary>
[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
/// 响应加入工会
/// </summary>
[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
/// 请求退出工会
/// </summary>
[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
/// 响应退出工会
/// </summary>
[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
/// 请求解散工会
/// </summary>
[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
/// 响应解散工会
/// </summary>
[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
/// 请求操作申请
/// </summary>
[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
/// 响应操作申请
/// </summary>
[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
/// 推送消息
/// </summary>
[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; }
}
}

View File

@@ -1,4 +1,4 @@
namespace Fantasy.ConfigTable;
namespace NBF.ConfigTable;
public interface IConfigContext
{

View File

@@ -0,0 +1,122 @@
using System.Reflection;
using Fantasy;
using Fantasy.Helper;
using Newtonsoft.Json.Linq;
// ReSharper disable SuspiciousTypeConversion.Global
namespace NBF.ConfigTable
{
/// <summary>
/// 配置表帮助类
/// </summary>
public static class ConfigTableHelper
{
private static readonly Dictionary<Type, IConfigContext> _dictionary = new Dictionary<Type, IConfigContext>();
public static void Initialize()
{
//解析配置文件
var gameConfigText = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "configs.Json"));
Initialize(gameConfigText, typeof(Fantasy.AssemblyHelper).Assembly);
}
/// <summary>
/// 初始化ConfigTableHelper
/// </summary>
public static void Initialize(string json, params System.Reflection.Assembly[] assemblies)
{
_dictionary.Clear();
var jsonObj = JObject.Parse(json);
Dictionary<string, JArray> 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<T>? Table<T>() where T : IConfigTable
{
var type = typeof(T);
if (_dictionary.TryGetValue(type, out var context))
{
return context as ConfigContext<T>;
}
var jsonContext = new ConfigContext<T>();
_dictionary[type] = jsonContext;
return jsonContext;
}
public static List<T> ParseLine<T>(JArray arr) where T : IConfigTable, new()
{
List<T> list = new List<T>();
foreach (var jToken in arr)
{
T? instance = jToken.ToObject<T>();
if (instance != null)
{
list.Add(instance);
}
}
var context = Table<T>();
context?.Association(list);
return list;
}
/// <summary>
/// 获取所有实现了 IConfigTable 接口的非抽象类
/// </summary>
/// <returns>所有非抽象的配置对象类</returns>
private static List<Type> GetAllConfigTableTypes(params System.Reflection.Assembly[] assemblies)
{
var types = new List<Type>();
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;
}
}
}

View File

@@ -1,4 +1,4 @@
namespace Fantasy.ConfigTable
namespace NBF.ConfigTable
{
/// <summary>
/// 表示是一个配置文件

View File

@@ -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": ""
}
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<fantasy xmlns="http://fantasy.net/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://fantasy.net/config Fantasy.xsd">
<!-- ↓这是为了兼容旧版Fantasy的导表Json配置↓, 如果这个XML节点被注释掉, 就会以 Fantasy.config 配置为准 -->
<!--<configTable path="../../../../Config/Json/Server" />-->
<!-- ↓这是目前推荐使用的Fantasy框架启服配置↓ -->
<network inner="TCP" maxMessageSize="1048560" />
<session idleTimeout="8000" idleInterval="5000" />
<server>
<!-- 机器配置 -->
<machines>
<machine id="1" outerIP="127.0.0.1" outerBindIP="127.0.0.1" innerBindIP="127.0.0.1" />
</machines>
<!-- 进程配置 -->
<processes>
<process id="1" machineId="1" startupGroup="0" />
</processes>
<!-- 世界配置 -->
<worlds>
<world id="1" worldName="WorldA">
<database dbType="MongoDB" dbName="fantasy_main" dbConnection="mongodb://127.0.0.1" />
</world>
</worlds>
<!-- 场景配置 -->
<scenes>
<scene id="1001"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Authentication"
networkProtocol="KCP"
outerPort="20001" innerPort="11001" />
<scene id="1002"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Addressable"
networkProtocol=""
outerPort="0" innerPort="11011" />
<scene id="1003"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Gate"
networkProtocol="KCP"
outerPort="20000" innerPort="11021" />
<scene id="1004"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Game"
networkProtocol=""
outerPort="0" innerPort="11031" />
<scene id="1006"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Social"
networkProtocol=""
outerPort="0" innerPort="11051" />
<scene id="1007"
processConfigId="1"
worldConfigId="1"
sceneRuntimeMode="MultiThread"
sceneTypeString="Map"
networkProtocol=""
outerPort="0" innerPort="11061" />
</scenes>
</server>
</fantasy>

View File

@@ -0,0 +1,345 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://fantasy.net/config"
xmlns="http://fantasy.net/config"
elementFormDefault="qualified">
<!-- Root element -->
<xs:element name="fantasy">
<xs:annotation>
<xs:documentation>Fantasy框架配置文件根元素</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="configTable" type="configTableType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>配置表路径设置</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="network" type="networkRuntimeType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>网络运行时配置</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="session" type="sessionRuntimeType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>会话运行时配置</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="server" type="serverType" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:documentation>服务器配置</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- ConfigTable type -->
<xs:complexType name="configTableType">
<xs:attribute name="path" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>配置表文件路径</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Server type -->
<xs:complexType name="serverType">
<xs:sequence>
<xs:element name="machines" type="machinesType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>机器配置列表</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="processes" type="processesType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>进程配置列表</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="worlds" type="worldsType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>世界配置列表</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="scenes" type="scenesType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>场景配置列表</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="units" type="unitsType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>单位配置列表</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<!-- Machines types -->
<xs:complexType name="machinesType">
<xs:sequence>
<xs:element name="machine" type="machineType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="machineType">
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>机器ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="outerIP" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>外网IP地址</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="outerBindIP" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>外网绑定IP地址</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="innerBindIP" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>内网绑定IP地址</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Processes types -->
<xs:complexType name="processesType">
<xs:sequence>
<xs:element name="process" type="processType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="processType">
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>进程ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="machineId" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>所属机器ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="startupGroup" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>启动分组</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Worlds types -->
<xs:complexType name="worldsType">
<xs:sequence>
<xs:element name="world" type="worldType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- database的选择 -->
<xs:complexType name="databaseType">
<xs:attribute name="dbType" use="required">
<xs:annotation>
<xs:documentation>数据库类型</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<!-- PostgreSQL -->
<xs:enumeration value="PostgreSQL"/>
<xs:enumeration value="Postgres"/>
<xs:enumeration value="PgSQL"/>
<xs:enumeration value="Pg"/>
<xs:enumeration value="PG"/>
<!-- MongoDB -->
<xs:enumeration value="MongoDB"/>
<xs:enumeration value="Mongo"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="dbName" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>数据库名称</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="dbConnection" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>数据库连接字符串</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="worldType">
<!-- 每个world允许包含1或n个database -->
<xs:sequence>
<xs:annotation>
<xs:documentation>世界中配置的数据库</xs:documentation>
</xs:annotation>
<xs:element name="database" type="databaseType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<!-- world需要id和worldName -->
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>世界ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="worldName" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>世界名称</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Scenes types -->
<xs:complexType name="scenesType">
<xs:sequence>
<xs:element name="scene" type="sceneType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sceneType">
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>场景ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="processConfigId" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>进程配置ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="worldConfigId" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>世界配置ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="sceneRuntimeMode" use="required">
<xs:annotation>
<xs:documentation>场景运行模式</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="MainThread"/>
<xs:enumeration value="MultiThread"/>
<xs:enumeration value="ThreadPool"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="sceneTypeString" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>场景类型字符串</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="networkProtocol" use="optional">
<xs:annotation>
<xs:documentation>网络协议类型</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="TCP"/>
<xs:enumeration value="KCP"/>
<xs:enumeration value="WebSocket"/>
<xs:enumeration value="HTTP"/>
<xs:enumeration value=""/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="outerPort" type="xs:unsignedInt" use="optional" default="0">
<xs:annotation>
<xs:documentation>外网端口</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="innerPort" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>内网端口</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Network Runtime type -->
<xs:complexType name="networkRuntimeType">
<xs:attribute name="inner" use="optional" default="TCP">
<xs:annotation>
<xs:documentation>服务器内部网络协议</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="TCP"/>
<xs:enumeration value="KCP"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="maxMessageSize" type="xs:int" use="optional" default="1048560">
<xs:annotation>
<xs:documentation>消息体最大长度(字节)默认1048560字节(约1.02MB)</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Session Runtime type -->
<xs:complexType name="sessionRuntimeType">
<xs:attribute name="idleTimeout" type="xs:int" use="optional" default="8000">
<xs:annotation>
<xs:documentation>Session idle check timeout (in milliseconds)</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="idleInterval" type="xs:int" use="optional" default="5000">
<xs:annotation>
<xs:documentation>Session idle check interval (in milliseconds)</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- Units types -->
<xs:complexType name="unitsType">
<xs:sequence>
<xs:element name="unit" type="unitType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="unitType">
<xs:sequence>
<xs:element name="dic" type="unitDicType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>单位字典数据</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required">
<xs:annotation>
<xs:documentation>单位ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>单位名称</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="model" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>单位模型</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="unitDicType">
<xs:sequence>
<xs:element name="item" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="key" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>字典键</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="value" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>字典值</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")]

View File

@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
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 类生成。

View File

@@ -0,0 +1 @@
4925a41a1713fbdc3c4b16a99814eedf9add8ff230ff3e204d8dc265b8ca499e

View File

@@ -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 =

View File

@@ -0,0 +1,8 @@
// <auto-generated/>
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;

Binary file not shown.

View File

@@ -0,0 +1 @@
6062551d1ab69f267bcbdefc9b276d4b2471f6b61b2a4e2cc6c5f261ac8ee2b5

View File

@@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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"
}
}
}
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\FIREBAT\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.14.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\FIREBAT\.nuget\packages\" />
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
</ItemGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)fantasy-net\2025.2.0\build\Fantasy-Net.props" Condition="Exists('$(NuGetPackageRoot)fantasy-net\2025.2.0\build\Fantasy-Net.props')" />
</ImportGroup>
</Project>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
<Import Project="$(NuGetPackageRoot)fantasy-net\2025.2.0\buildTransitive\Fantasy-Net.targets" Condition="Exists('$(NuGetPackageRoot)fantasy-net\2025.2.0\buildTransitive\Fantasy-Net.targets')" />
</ImportGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -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": []
}

View File

@@ -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"}}

View File

@@ -0,0 +1 @@
17628533859030116

View File

@@ -0,0 +1 @@
17628541514897177

View File

@@ -1,8 +0,0 @@
using System.Collections.Generic;
namespace Fantasy
{
// Roaming协议定义(需要定义10000以上、因为10000以内的框架预留)
public static class RoamingType
{
}
}

View File

@@ -1 +0,0 @@
// Roaming协议定义(需要定义10000以上、因为10000以内的框架预留)

View File

@@ -1 +0,0 @@
// Route协议定义(需要定义1000以上、因为1000以内的框架预留)

View File

@@ -1,8 +0,0 @@
using System.Collections.Generic;
namespace Fantasy
{
// Roaming协议定义(需要定义10000以上、因为10000以内的框架预留)
public static class RoamingType
{
}
}

View File

@@ -1,138 +0,0 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
namespace Fantasy
{
/// <summary>
/// 标准的控制台Log
/// </summary>
public sealed class ConsoleLog : ILog
{
/// <summary>
/// 记录跟踪级别的日志消息。
/// </summary>
/// <param name="message">日志消息。</param>
public void Trace(string message)
{
System.Console.ForegroundColor = ConsoleColor.White;
System.Console.WriteLine(message);
}
/// <summary>
/// 记录警告级别的日志消息。
/// </summary>
/// <param name="message">日志消息。</param>
public void Warning(string message)
{
System.Console.ForegroundColor = ConsoleColor.Yellow;
System.Console.WriteLine(message);
}
/// <summary>
/// 记录信息级别的日志消息。
/// </summary>
/// <param name="message">日志消息。</param>
public void Info(string message)
{
System.Console.ForegroundColor = ConsoleColor.Gray;
System.Console.WriteLine(message);
}
/// <summary>
/// 记录调试级别的日志消息。
/// </summary>
/// <param name="message">日志消息。</param>
public void Debug(string message)
{
System.Console.ForegroundColor = ConsoleColor.DarkGreen;
System.Console.WriteLine(message);
}
/// <summary>
/// 记录错误级别的日志消息。
/// </summary>
/// <param name="message">日志消息。</param>
public void Error(string message)
{
System.Console.ForegroundColor = ConsoleColor.DarkRed;
System.Console.WriteLine(message);
}
/// <summary>
/// 记录严重错误级别的日志消息。
/// </summary>
/// <param name="message">日志消息。</param>
public void Fatal(string message)
{
System.Console.ForegroundColor = ConsoleColor.Red;
System.Console.WriteLine(message);
}
/// <summary>
/// 记录跟踪级别的格式化日志消息。
/// </summary>
/// <param name="message">日志消息模板。</param>
/// <param name="args">格式化参数。</param>
public void Trace(string message, params object[] args)
{
System.Console.ForegroundColor = ConsoleColor.White;
System.Console.WriteLine(message, args);
}
/// <summary>
/// 记录警告级别的格式化日志消息。
/// </summary>
/// <param name="message">日志消息模板。</param>
/// <param name="args">格式化参数。</param>
public void Warning(string message, params object[] args)
{
System.Console.ForegroundColor = ConsoleColor.Yellow;
System.Console.WriteLine(message, args);
}
/// <summary>
/// 记录信息级别的格式化日志消息。
/// </summary>
/// <param name="message">日志消息模板。</param>
/// <param name="args">格式化参数。</param>
public void Info(string message, params object[] args)
{
System.Console.ForegroundColor = ConsoleColor.Gray;
System.Console.WriteLine(message, args);
}
/// <summary>
/// 记录调试级别的格式化日志消息。
/// </summary>
/// <param name="message">日志消息模板。</param>
/// <param name="args">格式化参数。</param>
public void Debug(string message, params object[] args)
{
System.Console.ForegroundColor = ConsoleColor.DarkGreen;
System.Console.WriteLine(message, args);
}
/// <summary>
/// 记录错误级别的格式化日志消息。
/// </summary>
/// <param name="message">日志消息模板。</param>
/// <param name="args">格式化参数。</param>
public void Error(string message, params object[] args)
{
System.Console.ForegroundColor = ConsoleColor.DarkRed;
System.Console.WriteLine(message, args);
}
/// <summary>
/// 记录严重错误级别的格式化日志消息。
/// </summary>
/// <param name="message">日志消息模板。</param>
/// <param name="args">格式化参数。</param>
public void Fatal(string message, params object[] args)
{
System.Console.ForegroundColor = ConsoleColor.Red;
System.Console.WriteLine(message, args);
}
}
}

View File

@@ -1,33 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<LangVersion>default</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>TRACE;FANTASY_CONSOLE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>TRACE;FANTASY_CONSOLE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
<PackageReference Include="MongoDB.Bson" Version="2.29.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="protobuf-net" Version="3.2.30" />
<PackageReference Include="System.IO.Pipelines" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Fantays.Console\Fantasy.Console.csproj" />
</ItemGroup>
</Project>

View File

@@ -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<NetworkBenchmark>();
Console.WriteLine(summary);
},
() => { Log.Debug("无法连接到目标服务器"); },
() => { Log.Debug("与服务器断开连接"); }, false);
}
[Benchmark]
public async FTask Call()
{
await _session.Call(_benchmarkRequest);
}
}

View File

@@ -1,2 +0,0 @@
Fantasy.Benchmark.NetworkBenchmark.Initialize().Coroutine();
Console.ReadKey();

View File

@@ -1,6 +0,0 @@
# Fantasy.Benchmark
使用 Fantasy.Benchmark 工具,我们能够快速评估框架网络的处理性能。目前,该工具提供的基准测试主要集中在 RPC远程过程调用消息 方面。这一项测试能够有效测量系统在处理远程调用时的响应时间、吞吐量和资源利用率,帮助开发者优化网络通信性能,确保在高负载情况下系统依然能够稳定运行
## 操作步骤
- 1.打开位于 Examples/Server/Server.sln 的解决方案文件。
- 2.在解决方案中选择并启动 Main 项目。
- 3.接着,启动 Fantasy.Benchmark 应用程序,并耐心等待其测试结果的生成。

View File

@@ -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

View File

@@ -1,34 +0,0 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- &lt;!&ndash; 物理复制 Excel 配置文件到项目根目录 &ndash;&gt;-->
<!-- <Target Name="CopyExcelFilesToProject" BeforeTargets="PrepareForBuild">-->
<!-- <ItemGroup>-->
<!-- <ExcelFilesToCopy Include="$(MSBuildThisFileDirectory)..\build\MachineConfig.xlsx" />-->
<!-- <ExcelFilesToCopy Include="$(MSBuildThisFileDirectory)..\build\SceneConfig.xlsx" />-->
<!-- <ExcelFilesToCopy Include="$(MSBuildThisFileDirectory)..\build\ProcessConfig.xlsx" />-->
<!-- <ExcelFilesToCopy Include="$(MSBuildThisFileDirectory)..\build\WorldConfig.xlsx" />-->
<!-- </ItemGroup>-->
<!-- <Copy SourceFiles="@(ExcelFilesToCopy)" DestinationFolder="$(MSBuildProjectDirectory)/ServerConfig" SkipUnchangedFiles="true" />-->
<!-- </Target>-->
<!-- &lt;!&ndash; 物理复制 NLog 配置文件到项目根目录 &ndash;&gt;-->
<!-- <Target Name="CopyNLogFilesToProject" BeforeTargets="PrepareForBuild">-->
<!-- <ItemGroup>-->
<!-- &lt;!&ndash; 定义源文件路径,指向 NuGet 包中的文件 &ndash;&gt;-->
<!-- <FilesToCopy Include="$(MSBuildThisFileDirectory)..\build\NLog.config" />-->
<!-- <FilesToCopy Include="$(MSBuildThisFileDirectory)..\build\NLog.xsd" />-->
<!-- </ItemGroup>-->
<!-- &lt;!&ndash; 使用 Copy 任务将文件复制到项目物理根目录 &ndash;&gt;-->
<!-- <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(MSBuildProjectDirectory)" SkipUnchangedFiles="true" /> -->
<!-- &lt;!&ndash; 将复制的文件添加到解决方案中,并设置复制到输出目录 &ndash;&gt;-->
<!-- <ItemGroup>-->
<!-- &lt;!&ndash; 使用 Include 确保文件在解决方案中显示 &ndash;&gt;-->
<!-- <None Include="NLog.config">-->
<!-- &lt;!&ndash; 确保复制到输出目录,并设置复制模式 &ndash;&gt;-->
<!-- <CopyToOutputDirectory>Always</CopyToOutputDirectory>-->
<!-- </None>-->
<!-- <None Include="NLog.xsd">-->
<!-- &lt;!&ndash; 确保复制到输出目录,并设置复制模式 &ndash;&gt;-->
<!-- <CopyToOutputDirectory>Always</CopyToOutputDirectory>-->
<!-- </None>-->
<!-- </ItemGroup>-->
<!-- </Target>-->
</Project>

View File

@@ -1,60 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>Fantasy-Net</PackageId>
<PackageVersion>2024.2.26</PackageVersion>
<Title>Fantasy-Net</Title>
<Authors>qq362946</Authors>
<owners>qq362946</owners>
<PackageOutputPath>../../nupkg</PackageOutputPath>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<Description>
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.</Description>
<Copyright>Copyright 2026 qq362946</Copyright>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageProjectUrl>https://www.code-fantasy.com/</PackageProjectUrl>
<RepositoryUrl>https://github.com/qq362946/Fantasy</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>Net, c#, Server, Game, GameServer, Fantasy , Network</PackageTags>
<PackageIcon>icon.png</PackageIcon>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>Fantasy-Net</AssemblyName>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<LangVersion>default</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>TRACE;FANTASY_NET</DefineConstants>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin\Debug\net8.0\Fantasy.Net.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>TRACE;FANTASY_NET</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<FrameworkReference Include="Microsoft.AspNetCore.App"/>
<PackageReference Include="MongoDB.Bson" Version="3.4.3" />
<PackageReference Include="MongoDB.Driver" Version="3.4.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="protobuf-net" Version="3.2.56" />
</ItemGroup>
<ItemGroup>
<None Include="Fantasy-Net.targets" Pack="true" PackagePath="buildTransitive" />
<None Include="icon.png" Pack="true" PackagePath="\"/>
<None Include="LICENSE" Pack="true" PackagePath="\"/>
<None Include="README.md" Pack="true" PackagePath="\"/>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="System.IO.Pipelines" Version="9.0.8" />
</ItemGroup>
</Project>

View File

@@ -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.

View File

@@ -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 __

View File

@@ -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
{
/// <summary>
/// AssemblyInfo提供有关程序集和类型的信息
/// </summary>
public sealed class AssemblyInfo
{
/// <summary>
/// 唯一标识
/// </summary>
public readonly long AssemblyIdentity;
/// <summary>
/// 获取或设置与此程序集相关联的 <see cref="Assembly"/> 实例。
/// </summary>
public System.Reflection.Assembly Assembly { get; private set; }
/// <summary>
/// 程序集类型集合,获取一个列表,包含从程序集加载的所有类型。
/// </summary>
public readonly List<Type> AssemblyTypeList = new List<Type>();
/// <summary>
/// 程序集类型分组集合,获取一个分组列表,将接口类型映射到实现这些接口的类型。
/// </summary>
public readonly OneToManyList<Type, Type> AssemblyTypeGroupList = new OneToManyList<Type, Type>();
/// <summary>
/// 初始化 <see cref="AssemblyInfo"/> 类的新实例。
/// </summary>
/// <param name="assemblyIdentity"></param>
public AssemblyInfo(long assemblyIdentity)
{
AssemblyIdentity = assemblyIdentity;
}
/// <summary>
/// 从指定的程序集加载类型信息并进行分类。
/// </summary>
/// <param name="assembly">要加载信息的程序集。</param>
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);
}
/// <summary>
/// 重新加载程序集的类型信息。
/// </summary>
/// <param name="assembly"></param>
public void ReLoad(System.Reflection.Assembly assembly)
{
Unload();
Load(assembly);
}
/// <summary>
/// 卸载程序集的类型信息。
/// </summary>
public void Unload()
{
AssemblyTypeList.Clear();
AssemblyTypeGroupList.Clear();
}
}
}

View File

@@ -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
{
/// <summary>
/// 管理程序集加载和卸载的帮助类。
/// </summary>
public static class AssemblySystem
{
#if FANTASY_WEBGL
private static readonly List<IAssembly> AssemblySystems = new List<IAssembly>();
private static readonly Dictionary<long, AssemblyInfo> AssemblyList = new Dictionary<long, AssemblyInfo>();
#else
private static readonly ConcurrentQueue<IAssembly> AssemblySystems = new ConcurrentQueue<IAssembly>();
private static readonly ConcurrentDictionary<long, AssemblyInfo> AssemblyList = new ConcurrentDictionary<long, AssemblyInfo>();
#endif
/// <summary>
/// 初始化 AssemblySystem。仅限内部
/// </summary>
/// <param name="assemblies"></param>
internal static async FTask InnerInitialize(params System.Reflection.Assembly[] assemblies)
{
await LoadAssembly(typeof(AssemblySystem).Assembly);
foreach (var assembly in assemblies)
{
await LoadAssembly(assembly);
}
}
/// <summary>
/// 加载指定的程序集,并触发相应的事件。
/// </summary>
/// <param name="assembly">要加载的程序集。</param>
/// <param name="isCurrentDomain">如果当前Domain中已经存在同名的Assembly,使用Domain中的程序集。</param>
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);
}
}
}
/// <summary>
/// 卸载程序集
/// </summary>
/// <param name="assembly"></param>
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);
}
}
/// <summary>
/// 将AssemblySystem接口的object注册到程序集管理中心
/// </summary>
/// <param name="obj"></param>
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);
}
}
/// <summary>
/// 程序集管理中心卸载注册的Load、ReLoad、UnLoad的接口
/// </summary>
/// <param name="obj"></param>
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
}
/// <summary>
/// 获取所有已加载程序集中的所有类型。
/// </summary>
/// <returns>所有已加载程序集中的类型。</returns>
public static IEnumerable<Type> ForEach()
{
foreach (var (_, assemblyInfo) in AssemblyList)
{
foreach (var type in assemblyInfo.AssemblyTypeList)
{
yield return type;
}
}
}
/// <summary>
/// 获取指定程序集中的所有类型。
/// </summary>
/// <param name="assemblyIdentity">程序集唯一标识。</param>
/// <returns>指定程序集中的类型。</returns>
public static IEnumerable<Type> ForEach(long assemblyIdentity)
{
if (!AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo))
{
yield break;
}
foreach (var type in assemblyInfo.AssemblyTypeList)
{
yield return type;
}
}
/// <summary>
/// 获取所有已加载程序集中实现指定类型的所有类型。
/// </summary>
/// <param name="findType">要查找的基类或接口类型。</param>
/// <returns>所有已加载程序集中实现指定类型的类型。</returns>
public static IEnumerable<Type> 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;
}
}
}
/// <summary>
/// 获取指定程序集中实现指定类型的所有类型。
/// </summary>
/// <param name="assemblyIdentity">程序集唯一标识。</param>
/// <param name="findType">要查找的基类或接口类型。</param>
/// <returns>指定程序集中实现指定类型的类型。</returns>
public static IEnumerable<Type> 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;
}
}
/// <summary>
/// 获取指定程序集的实例。
/// </summary>
/// <param name="assemblyIdentity">程序集名称。</param>
/// <returns>指定程序集的实例,如果未加载则返回 null。</returns>
public static System.Reflection.Assembly GetAssembly(long assemblyIdentity)
{
return !AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo) ? null : assemblyInfo.Assembly;
}
/// <summary>
/// 获取当前框架注册的Assembly
/// </summary>
/// <returns></returns>
public static IEnumerable<System.Reflection.Assembly> ForEachAssembly
{
get
{
foreach (var (_, assemblyInfo) in AssemblyList)
{
yield return assemblyInfo.Assembly;
}
}
}
/// <summary>
/// 根据Assembly的强命名计算唯一标识。
/// </summary>
/// <param name="assembly"></param>
/// <returns></returns>
private static long AssemblyIdentity(System.Reflection.Assembly assembly)
{
return HashCodeHelper.ComputeHash64(assembly.GetName().Name);
}
/// <summary>
/// 释放资源,卸载所有加载的程序集。
/// </summary>
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();
}
}
}

View File

@@ -1,27 +0,0 @@
using System;
using Fantasy.Async;
namespace Fantasy.Assembly
{
/// <summary>
/// 实现这个接口、会再程序集首次加载、卸载、重载的时候调用
/// </summary>
public interface IAssembly : IDisposable
{
/// <summary>
/// 程序集加载时调用
/// </summary>
/// <param name="assemblyIdentity">程序集标识</param>
public FTask Load(long assemblyIdentity);
/// <summary>
/// 程序集重新加载的时候调用
/// </summary>
/// <param name="assemblyIdentity">程序集标识</param>
public FTask ReLoad(long assemblyIdentity);
/// <summary>
/// 卸载的时候调用
/// </summary>
/// <param name="assemblyIdentity">程序集标识</param>
public FTask OnUnLoad(long assemblyIdentity);
}
}

View File

@@ -1,25 +0,0 @@
using Fantasy.Async;
using Fantasy.InnerMessage;
using Fantasy.Network.Interface;
#if FANTASY_NET
namespace Fantasy.Network.Benchmark.Handler;
/// <summary>
/// BenchmarkRequestHandler
/// </summary>
public sealed class BenchmarkRequestHandler : MessageRPC<BenchmarkRequest, BenchmarkResponse>
{
/// <summary>
/// Run方法
/// </summary>
/// <param name="session"></param>
/// <param name="request"></param>
/// <param name="response"></param>
/// <param name="reply"></param>
protected override async FTask Run(Session session, BenchmarkRequest request, BenchmarkResponse response, Action reply)
{
await FTask.CompletedTask;
}
}
#endif

View File

@@ -1,20 +0,0 @@
// ReSharper disable CheckNamespace
// ReSharper disable InconsistentNaming
#if FANTASY_NET
namespace Fantasy.DataBase;
/// <summary>
/// 数据库类型
/// </summary>
public enum DataBaseType
{
/// <summary>
/// 默认
/// </summary>
None = 0,
/// <summary>
/// MongoDB
/// </summary>
MongoDB = 1
}
#endif

View File

@@ -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
{
/// <summary>
/// 数据库设置助手
/// </summary>
public static class DataBaseSetting
{
/// <summary>
/// 初始化自定义委托当设置了这个委托后就不会自动创建MongoClient需要自己在委托里创建MongoClient。
/// </summary>
public static Func<DataBaseCustomConfig, MongoClient>? MongoDBCustomInitialize;
}
/// <summary>
/// MongoDB自定义连接参数
/// </summary>
public sealed class DataBaseCustomConfig
{
/// <summary>
/// 当前Scene
/// </summary>
public Scene Scene;
/// <summary>
/// 连接字符串
/// </summary>
public string ConnectionString;
/// <summary>
/// 数据库名字
/// </summary>
public string DBName;
}
/// <summary>
/// 表示用于执行各种数据库操作的数据库接口。
/// </summary>
public interface IDataBase : IDisposable
{
/// <summary>
/// 获得当前数据的类型
/// </summary>
public DataBaseType GetDataBaseType { get;}
/// <summary>
/// 获得对应数据的操作实例
/// </summary>
/// <returns>如MongoDB就是IMongoDatabase</returns>
public object GetDataBaseInstance { get;}
/// <summary>
/// 初始化数据库连接。
/// </summary>
IDataBase Initialize(Scene scene, string connectionString, string dbName);
/// <summary>
/// 在指定的集合中检索类型 <typeparamref name="T"/> 的实体数量。
/// </summary>
FTask<long> Count<T>(string collection = null) where T : Entity;
/// <summary>
/// 在指定的集合中检索满足给定筛选条件的类型 <typeparamref name="T"/> 的实体数量。
/// </summary>
FTask<long> Count<T>(Expression<Func<T, bool>> filter, string collection = null) where T : Entity;
/// <summary>
/// 检查指定集合中是否存在类型 <typeparamref name="T"/> 的实体。
/// </summary>
FTask<bool> Exist<T>(string collection = null) where T : Entity;
/// <summary>
/// 检查指定集合中是否存在满足给定筛选条件的类型 <typeparamref name="T"/> 的实体。
/// </summary>
FTask<bool> Exist<T>(Expression<Func<T, bool>> filter, string collection = null) where T : Entity;
/// <summary>
/// 从指定集合中检索指定 ID 的类型 <typeparamref name="T"/> 的实体,不锁定。
/// </summary>
FTask<T> QueryNotLock<T>(long id, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 从指定集合中检索指定 ID 的类型 <typeparamref name="T"/> 的实体。
/// </summary>
FTask<T> Query<T>(long id, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 按页查询满足给定筛选条件的类型 <typeparamref name="T"/> 的实体数量和日期。
/// </summary>
FTask<(int count, List<T> dates)> QueryCountAndDatesByPage<T>(Expression<Func<T, bool>> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 按页查询满足给定筛选条件的类型 <typeparamref name="T"/> 的实体数量和日期。
/// </summary>
FTask<(int count, List<T> dates)> QueryCountAndDatesByPage<T>(Expression<Func<T, bool>> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 分页查询指定集合中满足给定筛选条件的类型 <typeparamref name="T"/> 的实体列表。
/// </summary>
FTask<List<T>> QueryByPage<T>(Expression<Func<T, bool>> filter, int pageIndex, int pageSize, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 分页查询指定集合中满足给定筛选条件的类型 <typeparamref name="T"/> 的实体列表,仅返回指定列的数据。
/// </summary>
FTask<List<T>> QueryByPage<T>(Expression<Func<T, bool>> filter, int pageIndex, int pageSize, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 从指定集合中按页查询满足给定筛选条件的类型 <typeparamref name="T"/> 的实体列表,按指定字段排序。
/// </summary>
FTask<List<T>> QueryByPageOrderBy<T>(Expression<Func<T, bool>> filter, int pageIndex, int pageSize, Expression<Func<T, object>> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 检索满足给定筛选条件的类型 <typeparamref name="T"/> 的第一个实体,从指定集合中。
/// </summary>
FTask<T?> First<T>(Expression<Func<T, bool>> filter, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 查询指定集合中满足给定 JSON 查询字符串的类型 <typeparamref name="T"/> 的第一个实体,仅返回指定列的数据。
/// </summary>
FTask<T> First<T>(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 从指定集合中按页查询满足给定筛选条件的类型 <typeparamref name="T"/> 的实体列表,按指定字段排序。
/// </summary>
FTask<List<T>> QueryOrderBy<T>(Expression<Func<T, bool>> filter, Expression<Func<T, object>> orderByExpression, bool isAsc = true, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 从指定集合中按页查询满足给定筛选条件的类型 <typeparamref name="T"/> 的实体列表。
/// </summary>
FTask<List<T>> Query<T>(Expression<Func<T, bool>> filter, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 查询指定集合中满足给定筛选条件的类型 <typeparamref name="T"/> 实体列表,仅返回指定字段的数据。
/// </summary>
FTask<List<T>> Query<T>(Expression<Func<T, bool>> filter, Expression<Func<T, object>>[] cols, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 查询指定 ID 的多个集合,将结果存储在给定的实体列表中。
/// </summary>
FTask Query(long id, List<string> collectionNames, List<Entity> result, bool isDeserialize = false);
/// <summary>
/// 根据给定的 JSON 查询字符串查询指定集合中的类型 <typeparamref name="T"/> 实体列表。
/// </summary>
FTask<List<T>> QueryJson<T>(string json, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 根据给定的 JSON 查询字符串查询指定集合中的类型 <typeparamref name="T"/> 实体列表,仅返回指定列的数据。
/// </summary>
FTask<List<T>> QueryJson<T>(string json, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 根据给定的 JSON 查询字符串查询指定集合中的类型 <typeparamref name="T"/> 实体列表,通过指定的任务 ID 进行标识。
/// </summary>
FTask<List<T>> QueryJson<T>(long taskId, string json, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 查询指定集合中满足给定筛选条件的类型 <typeparamref name="T"/> 实体列表,仅返回指定列的数据。
/// </summary>
FTask<List<T>> Query<T>(Expression<Func<T, bool>> filter, string[] cols, bool isDeserialize = false, string collection = null) where T : Entity;
/// <summary>
/// 保存类型 <typeparamref name="T"/> 实体到指定集合中,如果集合不存在将自动创建。
/// </summary>
FTask Save<T>(T entity, string collection = null) where T : Entity, new();
/// <summary>
/// 保存一组实体到数据库中,根据实体列表的 ID 进行区分和存储。
/// </summary>
FTask Save(long id, List<Entity> entities);
/// <summary>
/// 通过事务会话将类型 <typeparamref name="T"/> 实体保存到指定集合中,如果集合不存在将自动创建。
/// </summary>
FTask Save<T>(object transactionSession, T entity, string collection = null) where T : Entity;
/// <summary>
/// 向指定集合中插入一个类型 <typeparamref name="T"/> 实体,如果集合不存在将自动创建。
/// </summary>
FTask Insert<T>(T entity, string collection = null) where T : Entity, new();
/// <summary>
/// 批量插入一组类型 <typeparamref name="T"/> 实体到指定集合中,如果集合不存在将自动创建。
/// </summary>
FTask InsertBatch<T>(IEnumerable<T> list, string collection = null) where T : Entity, new();
/// <summary>
/// 通过事务会话,批量插入一组类型 <typeparamref name="T"/> 实体到指定集合中,如果集合不存在将自动创建。
/// </summary>
FTask InsertBatch<T>(object transactionSession, IEnumerable<T> list, string collection = null) where T : Entity, new();
/// <summary>
/// 通过事务会话,根据指定的 ID 从数据库中删除指定类型 <typeparamref name="T"/> 实体。
/// </summary>
FTask<long> Remove<T>(object transactionSession, long id, string collection = null) where T : Entity, new();
/// <summary>
/// 根据指定的 ID 从数据库中删除指定类型 <typeparamref name="T"/> 实体。
/// </summary>
FTask<long> Remove<T>(long id, string collection = null) where T : Entity, new();
/// <summary>
/// 通过事务会话,根据给定的筛选条件从数据库中删除指定类型 <typeparamref name="T"/> 实体。
/// </summary>
FTask<long> Remove<T>(long coroutineLockQueueKey, object transactionSession, Expression<Func<T, bool>> filter, string collection = null) where T : Entity, new();
/// <summary>
/// 根据给定的筛选条件从数据库中删除指定类型 <typeparamref name="T"/> 实体。
/// </summary>
FTask<long> Remove<T>(long coroutineLockQueueKey, Expression<Func<T, bool>> filter, string collection = null) where T : Entity, new();
/// <summary>
/// 根据给定的筛选条件计算指定集合中类型 <typeparamref name="T"/> 实体某个属性的总和。
/// </summary>
FTask<long> Sum<T>(Expression<Func<T, bool>> filter, Expression<Func<T, object>> sumExpression, string collection = null) where T : Entity;
/// <summary>
/// 在指定的集合中创建索引,以提高类型 <typeparamref name="T"/> 实体的查询性能。
/// </summary>
FTask CreateIndex<T>(string collection, params object[] keys) where T : Entity;
/// <summary>
/// 在默认集合中创建索引,以提高类型 <typeparamref name="T"/> 实体的查询性能。
/// </summary>
FTask CreateIndex<T>(params object[] keys) where T : Entity;
/// <summary>
/// 创建指定类型 <typeparamref name="T"/> 的数据库,用于存储实体。
/// </summary>
FTask CreateDB<T>() where T : Entity;
/// <summary>
/// 根据指定类型创建数据库,用于存储实体。
/// </summary>
FTask CreateDB(Type type);
}
}
#endif

View File

@@ -1,77 +0,0 @@
#pragma warning disable CS8603 // Possible null reference return.
#if FANTASY_NET
using Fantasy.Platform.Net;
namespace Fantasy.DataBase
{
/// <summary>
/// 表示一个游戏世界。
/// </summary>
public sealed class World : IDisposable
{
/// <summary>
/// 获取游戏世界的唯一标识。
/// </summary>
public byte Id { get; private init; }
/// <summary>
/// 获取游戏世界的数据库接口。
/// </summary>
public IDataBase DataBase { get; private init; }
/// <summary>
/// 获取游戏世界的配置信息。
/// </summary>
public WorldConfig Config => WorldConfigData.Instance.Get(Id);
/// <summary>
/// 使用指定的配置信息创建一个游戏世界实例。
/// </summary>
/// <param name="scene"></param>
/// <param name="worldConfigId"></param>
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");
}
}
}
/// <summary>
/// 创建一个指定唯一标识的游戏世界实例。
/// </summary>
/// <param name="scene"></param>
/// <param name="id">游戏世界的唯一标识。</param>
/// <returns>游戏世界实例。</returns>
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);
}
/// <summary>
/// 释放游戏世界资源。
/// </summary>
public void Dispose()
{
DataBase.Dispose();
}
}
}
#endif

View File

@@ -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、当读取完成后用过的环会放在缓存中不会销毁掉。
/// <summary>
/// 自增式缓存类,继承自 Stream 和 IDisposable 接口。
/// 环形缓存具有自动扩充的特性,但不会收缩,适用于操作不过大的 IO 流。
/// </summary>
public sealed class CircularBuffer : Stream, IDisposable
{
private byte[] _lastBuffer;
/// <summary>
/// 环形缓存块的默认大小
/// </summary>
public const int ChunkSize = 8192;
private readonly Queue<byte[]> _bufferCache = new Queue<byte[]>();
private readonly Queue<byte[]> _bufferQueue = new Queue<byte[]>();
/// <summary>
/// 获取或设置环形缓存的第一个索引位置
/// </summary>
public int FirstIndex { get; set; }
/// <summary>
/// 获取或设置环形缓存的最后一个索引位置
/// </summary>
public int LastIndex { get; set; }
/// <summary>
/// 获取环形缓存的总长度
/// </summary>
public override long Length
{
get
{
if (_bufferQueue.Count == 0)
{
return 0;
}
return (_bufferQueue.Count - 1) * ChunkSize + LastIndex - FirstIndex;
}
}
/// <summary>
/// 获取环形缓存的第一个块
/// </summary>
public byte[] First
{
get
{
if (_bufferQueue.Count == 0)
{
AddLast();
}
return _bufferQueue.Peek();
}
}
/// <summary>
/// 获取环形缓存的最后一个块
/// </summary>
public byte[] Last
{
get
{
if (_bufferQueue.Count == 0)
{
AddLast();
}
return _lastBuffer;
}
}
/// <summary>
/// 向环形缓存中添加一个新的块
/// </summary>
public void AddLast()
{
var buffer = _bufferCache.Count > 0 ? _bufferCache.Dequeue() : new byte[ChunkSize];
_bufferQueue.Enqueue(buffer);
_lastBuffer = buffer;
}
/// <summary>
/// 从环形缓存中移除第一个块
/// </summary>
public void RemoveFirst()
{
_bufferCache.Enqueue(_bufferQueue.Dequeue());
}
/// <summary>
/// 从流中读取指定数量的数据到缓存。
/// </summary>
/// <param name="stream">源数据流。</param>
/// <param name="count">要读取的字节数。</param>
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();
}
}
}
/// <summary>
/// 从缓存中读取指定数量的数据到内存。
/// </summary>
/// <param name="memory">目标内存。</param>
/// <param name="count">要读取的字节数。</param>
public void Read(Memory<byte> 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();
}
}
}
/// <summary>
/// 从自定义流中读取数据到指定的缓冲区。
/// </summary>
/// <param name="buffer">目标缓冲区,用于存储读取的数据。</param>
/// <param name="offset">目标缓冲区中的起始偏移量。</param>
/// <param name="count">要读取的字节数。</param>
/// <returns>实际读取的字节数。</returns>
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;
}
/// <summary>
/// 将数据从给定的字节数组写入流中。
/// </summary>
/// <param name="buffer">包含要写入的数据的字节数组。</param>
public void Write(byte[] buffer)
{
Write(buffer, 0, buffer.Length);
}
/// <summary>
/// 将数据从给定的流写入流中。
/// </summary>
/// <param name="stream">包含要写入的数据的流。</param>
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;
}
}
}
/// <summary>
/// 将数据从给定的字节数组写入流中。
/// </summary>
/// <param name="buffer">包含要写入的数据的字节数组。</param>
/// <param name="offset">开始写入的缓冲区中的索引。</param>
/// <param name="count">要写入的字节数。</param>
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;
}
}
}
/// <summary>
/// 获取一个值,指示流是否支持读取操作。
/// </summary>
public override bool CanRead { get; } = true;
/// <summary>
/// 获取一个值,指示流是否支持寻找操作。
/// </summary>
public override bool CanSeek { get; } = false;
/// <summary>
/// 获取一个值,指示流是否支持写入操作。
/// </summary>
public override bool CanWrite { get; } = true;
/// <summary>
/// 获取或设置流中的位置。
/// </summary>
public override long Position { get; set; }
/// <summary>
/// 刷新流(在此实现中引发未实现异常)。
/// </summary>
public override void Flush()
{
throw new NotImplementedException();
}
/// <summary>
/// 在流中寻找特定位置(在此实现中引发未实现异常)。
/// </summary>
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
/// <summary>
/// 设置流的长度(在此实现中引发未实现异常)。
/// </summary>
public override void SetLength(long value)
{
throw new NotImplementedException();
}
/// <summary>
/// 释放 CustomStream 使用的所有资源。
/// </summary>
public new void Dispose()
{
_bufferQueue.Clear();
_lastBuffer = null;
FirstIndex = 0;
LastIndex = 0;
base.Dispose();
}
}
}

View File

@@ -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
{
/// <summary>
/// 并发的一对多列表池,用于维护具有相同键的多个值的关联关系,实现了 <see cref="IDisposable"/> 接口。
/// </summary>
/// <typeparam name="TKey">关键字的类型,不能为空。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class ConcurrentOneToManyListPool<TKey, TValue> : ConcurrentOneToManyList<TKey, TValue>, IDisposable, IPool where TKey : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个 <see cref="ConcurrentOneToManyListPool{TKey, TValue}"/> 的实例。
/// </summary>
/// <returns>创建的实例。</returns>
public static ConcurrentOneToManyListPool<TKey, TValue> Create()
{
var a = MultiThreadPool.Rent<ConcurrentOneToManyListPool<TKey, TValue>>();
a._isDispose = false;
a._isPool = true;
return a;
}
/// <summary>
/// 释放实例占用的资源。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
// 清空实例的数据
Clear();
// 将实例返回到池中以便重用
MultiThreadPool.Return(this);
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 并发的一对多列表,用于维护具有相同键的多个值的关联关系。
/// </summary>
/// <typeparam name="TKey">关键字的类型,不能为空。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class ConcurrentOneToManyList<TKey, TValue> : ConcurrentDictionary<TKey, List<TValue>> where TKey : notnull
{
private readonly Queue<List<TValue>> _queue = new Queue<List<TValue>>();
private readonly int _recyclingLimit = 120;
/// <summary>
/// 初始化 <see cref="ConcurrentOneToManyList{TKey, TValue}"/> 类的新实例。
/// </summary>
public ConcurrentOneToManyList()
{
}
/// <summary>
/// 设置最大缓存数量
/// </summary>
/// <param name="recyclingLimit">
/// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC.
/// 2:设置成0不控制数量全部缓存
/// </param>
public ConcurrentOneToManyList(int recyclingLimit)
{
_recyclingLimit = recyclingLimit;
}
/// <summary>
/// 判断指定键的列表是否包含指定值。
/// </summary>
/// <param name="key">要搜索的键。</param>
/// <param name="value">要搜索的值。</param>
/// <returns>如果列表包含值,则为 true否则为 false。</returns>
public bool Contains(TKey key, TValue value)
{
TryGetValue(key, out var list);
return list != null && list.Contains(value);
}
/// <summary>
/// 向指定键的列表中添加一个值。
/// </summary>
/// <param name="key">要添加值的键。</param>
/// <param name="value">要添加的值。</param>
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);
}
/// <summary>
/// 获取指定键的列表中的第一个值。
/// </summary>
/// <param name="key">要获取第一个值的键。</param>
/// <returns>指定键的列表中的第一个值,如果不存在则为默认值。</returns>
public TValue First(TKey key)
{
return !TryGetValue(key, out var list) ? default : list.FirstOrDefault();
}
/// <summary>
/// 从指定键的列表中移除一个值。
/// </summary>
/// <param name="key">要移除值的键。</param>
/// <param name="value">要移除的值。</param>
public void RemoveValue(TKey key, TValue value)
{
if (!TryGetValue(key, out var list)) return;
list.Remove(value);
if (list.Count == 0) RemoveKey(key);
}
/// <summary>
/// 从字典中移除指定键以及其关联的列表。
/// </summary>
/// <param name="key">要移除的键。</param>
public void RemoveKey(TKey key)
{
if (!TryRemove(key, out var list)) return;
Recycle(list);
}
/// <summary>
/// 从队列中获取一个列表,如果队列为空则创建一个新的列表。
/// </summary>
/// <returns>获取的列表。</returns>
private List<TValue> Fetch()
{
return _queue.Count <= 0 ? new List<TValue>() : _queue.Dequeue();
}
/// <summary>
/// 将一个列表回收到队列中。
/// </summary>
/// <param name="list">要回收的列表。</param>
private void Recycle(List<TValue> list)
{
list.Clear();
if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return;
_queue.Enqueue(list);
}
/// <summary>
/// 清空当前类的数据,包括从基类继承的数据以及自定义的数据队列。
/// </summary>
protected new void Clear()
{
base.Clear();
_queue.Clear();
}
}
}
#endif

View File

@@ -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
{
/// <summary>
/// 表示一个并发的一对多队列池,用于维护具有相同键的多个值的关联关系,实现了 <see cref="IDisposable"/> 接口。
/// </summary>
/// <typeparam name="TKey">关键字的类型,不能为空。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class ConcurrentOneToManyQueuePool<TKey, TValue> : ConcurrentOneToManyQueue<TKey, TValue>, IDisposable, IPool where TKey : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建并返回一个 <see cref="ConcurrentOneToManyQueuePool{TKey, TValue}"/> 的实例。
/// </summary>
/// <returns>创建的实例。</returns>
public static ConcurrentOneToManyQueuePool<TKey, TValue> Create()
{
var a = MultiThreadPool.Rent<ConcurrentOneToManyQueuePool<TKey, TValue>>();
a._isDispose = false;
a._isPool = true;
return a;
}
/// <summary>
/// 释放当前实例所占用的资源,并将实例返回到对象池中,以便重用。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
// 将实例返回到对象池中,以便重用
MultiThreadPool.Return(this);
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 表示一个并发的一对多队列,用于维护具有相同键的多个值的关联关系。
/// </summary>
/// <typeparam name="TKey">关键字的类型,不能为空。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class ConcurrentOneToManyQueue<TKey, TValue> : ConcurrentDictionary<TKey, Queue<TValue>> where TKey : notnull
{
private readonly Queue<Queue<TValue>> _queue = new Queue<Queue<TValue>>();
private readonly int _recyclingLimit;
/// <summary>
/// 设置最大缓存数量
/// </summary>
/// <param name="recyclingLimit">
/// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC.
/// 2:设置成0不控制数量全部缓存
/// </param>
public ConcurrentOneToManyQueue(int recyclingLimit = 0)
{
_recyclingLimit = recyclingLimit;
}
/// <summary>
/// 判断指定键的队列是否包含指定值。
/// </summary>
/// <param name="key">要搜索的键。</param>
/// <param name="value">要搜索的值。</param>
/// <returns>如果队列包含值,则为 true否则为 false。</returns>
public bool Contains(TKey key, TValue value)
{
TryGetValue(key, out var list);
return list != null && list.Contains(value);
}
/// <summary>
/// 向指定键的队列中添加一个值。
/// </summary>
/// <param name="key">要添加值的键。</param>
/// <param name="value">要添加的值。</param>
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);
}
/// <summary>
/// 从指定键的队列中出队并返回一个值。
/// </summary>
/// <param name="key">要出队的键。</param>
/// <returns>出队的值,如果队列为空则为默认值。</returns>
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;
}
/// <summary>
/// 尝试从指定键的队列中出队一个值。
/// </summary>
/// <param name="key">要出队的键。</param>
/// <param name="value">出队的值,如果队列为空则为默认值。</param>
/// <returns>如果成功出队,则为 true否则为 false。</returns>
public bool TryDequeue(TKey key, out TValue value)
{
value = Dequeue(key);
return value != null;
}
/// <summary>
/// 从字典中移除指定键以及其关联的队列。
/// </summary>
/// <param name="key">要移除的键。</param>
public void RemoveKey(TKey key)
{
if (!TryGetValue(key, out var list)) return;
TryRemove(key, out _);
Recycle(list);
}
/// <summary>
/// 从队列中获取一个新的队列,如果队列为空则创建一个新的队列。
/// </summary>
/// <returns>获取的队列。</returns>
private Queue<TValue> Fetch()
{
return _queue.Count <= 0 ? new Queue<TValue>() : _queue.Dequeue();
}
/// <summary>
/// 将一个队列回收到队列池中。
/// </summary>
/// <param name="list">要回收的队列。</param>
private void Recycle(Queue<TValue> list)
{
list.Clear();
if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return;
_queue.Enqueue(list);
}
/// <summary>
/// 清空当前类的数据,包括从基类继承的键值对字典中的数据以及自定义的队列池。
/// </summary>
protected new void Clear()
{
base.Clear();
_queue.Clear();
}
}
}
#endif

View File

@@ -1,134 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
namespace Fantasy.DataStructure.Collection
{
/// <summary>
/// 可释放的哈希集合对象池。
/// </summary>
/// <typeparam name="T">哈希集合中元素的类型。</typeparam>
public sealed class HashSetPool<T> : HashSet<T>, IDisposable, IPool
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<HashSetPool<T>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 创建一个 <see cref="HashSetPool{T}"/> 哈希集合池的实例。
/// </summary>
/// <returns>创建的实例。</returns>
public static HashSetPool<T> Create()
{
#if FANTASY_WEBGL
var list = Pool<HashSetPool<T>>.Rent();
list._isDispose = false;
list._isPool = true;
return list;
#else
var list = MultiThreadPool.Rent<HashSetPool<T>>();
list._isDispose = false;
list._isPool = true;
return list;
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 基本哈希集合对象池,他自持有实际的哈希集合。
/// </summary>
/// <typeparam name="T">哈希集合中元素的类型。</typeparam>
public sealed class HashSetBasePool<T> : IDisposable, IPool
{
private bool _isPool;
/// <summary>
/// 存储实际的哈希集合
/// </summary>
public HashSet<T> Set = new HashSet<T>();
/// <summary>
/// 创建一个 <see cref="HashSetBasePool{T}"/> 基本哈希集合对象池的实例。
/// </summary>
/// <returns>创建的实例。</returns>
public static HashSetBasePool<T> Create()
{
#if FANTASY_WEBGL
var hashSetBasePool = Pool<HashSetBasePool<T>>.Rent();
hashSetBasePool._isPool = true;
return hashSetBasePool;
#else
var hashSetBasePool = MultiThreadPool.Rent<HashSetBasePool<T>>();
hashSetBasePool._isPool = true;
return hashSetBasePool;
#endif
}
/// <summary>
/// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。
/// </summary>
public void Dispose()
{
Set.Clear();
#if FANTASY_WEBGL
Pool<HashSetBasePool<T>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,101 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
namespace Fantasy.DataStructure.Collection
{
/// <summary>
/// 可释放的列表List对象池。
/// </summary>
/// <typeparam name="T">列表中元素的类型。</typeparam>
public sealed class ListPool<T> : List<T>, IDisposable, IPool
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<ListPool<T>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 使用指定的元素创建一个 <see cref="ListPool{T}"/> 列表List对象池的实例。
/// </summary>
/// <param name="args">要添加到列表的元素。</param>
/// <returns>创建的实例。</returns>
public static ListPool<T> Create(params T[] args)
{
#if FANTASY_WEBGL
var list = Pool<ListPool<T>>.Rent();
#else
var list = MultiThreadPool.Rent<ListPool<T>>();
#endif
list._isDispose = false;
list._isPool = true;
if (args != null)
{
list.AddRange(args);
}
return list;
}
/// <summary>
/// 使用指定的列表创建一个 <see cref="ListPool{T}"/> 列表List对象池的实例。
/// </summary>
/// <param name="args">要添加到列表的元素列表。</param>
/// <returns>创建的实例。</returns>
public static ListPool<T> Create(List<T> args)
{
#if FANTASY_WEBGL
var list = Pool<ListPool<T>>.Rent();
#else
var list = MultiThreadPool.Rent<ListPool<T>>();
#endif
list._isDispose = false;
list._isPool = true;
if (args != null)
{
list.AddRange(args);
}
return list;
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
}

View File

@@ -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
{
/// <summary>
/// 一对多哈希集合OneToManyHashSet对象池。
/// </summary>
/// <typeparam name="TKey">键的类型。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class OneToManyHashSetPool<TKey, TValue> : OneToManyHashSet<TKey, TValue>, IDisposable, IPool where TKey : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个 <see cref="OneToManyHashSetPool{TKey, TValue}"/> 一对多哈希集合OneToManyHashSet对象池的实例。
/// </summary>
/// <returns>创建的实例。</returns>
public static OneToManyHashSetPool<TKey, TValue> Create()
{
#if FANTASY_WEBGL
var a = Pool<OneToManyHashSetPool<TKey, TValue>>.Rent();
#else
var a = MultiThreadPool.Rent<OneToManyHashSetPool<TKey, TValue>>();
#endif
a._isDispose = false;
a._isPool = true;
return a;
}
/// <summary>
/// 释放实例所占用的资源,并将实例返回到对象池中,以便重用。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<OneToManyHashSetPool<TKey, TValue>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 一对多哈希集合OneToManyHashSet用于创建和管理键对应多个值的集合。
/// </summary>
/// <typeparam name="TKey">键的类型。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class OneToManyHashSet<TKey, TValue> : Dictionary<TKey, HashSet<TValue>> where TKey : notnull
{
/// 用于回收和重用的空闲值集合队列。
private readonly Queue<HashSet<TValue>> _queue = new Queue<HashSet<TValue>>();
/// 设置最大回收限制,用于控制值集合的最大数量。
private readonly int _recyclingLimit = 120;
/// 一个空的、不包含任何元素的哈希集合,用于在查找失败时返回。
private static HashSet<TValue> _empty = new HashSet<TValue>();
/// <summary>
/// 初始化 <see cref="OneToManyHashSet{TKey, TValue}"/> 类的新实例。
/// </summary>
public OneToManyHashSet() { }
/// <summary>
/// 设置最大缓存数量
/// </summary>
/// <param name="recyclingLimit">
/// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC.
/// 2:设置成0不控制数量全部缓存
/// </param>
public OneToManyHashSet(int recyclingLimit)
{
_recyclingLimit = recyclingLimit;
}
/// <summary>
/// 判断指定的键值对是否存在于集合中。
/// </summary>
/// <param name="key">键。</param>
/// <param name="value">值。</param>
/// <returns>如果存在则为 true否则为 false。</returns>
public bool Contains(TKey key, TValue value)
{
TryGetValue(key, out var list);
return list != null && list.Contains(value);
}
/// <summary>
/// 添加指定的键值对到集合中。
/// </summary>
/// <param name="key">键。</param>
/// <param name="value">值。</param>
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);
}
/// <summary>
/// 从集合中移除指定键对应的值。
/// </summary>
/// <param name="key">键。</param>
/// <param name="value">要移除的值。</param>
public void RemoveValue(TKey key, TValue value)
{
if (!TryGetValue(key, out var list)) return;
list.Remove(value);
if (list.Count == 0) RemoveKey(key);
}
/// <summary>
/// 从集合中移除指定键及其对应的值集合。
/// </summary>
/// <param name="key">键。</param>
public void RemoveKey(TKey key)
{
if (!TryGetValue(key, out var list)) return;
Remove(key);
Recycle(list);
}
/// <summary>
/// 获取指定键对应的值集合,如果不存在则返回一个空的哈希集合。
/// </summary>
/// <param name="key">键。</param>
/// <returns>对应的值集合或空的哈希集合。</returns>
public HashSet<TValue> GetValue(TKey key)
{
if (TryGetValue(key, out HashSet<TValue> value))
{
return value;
}
return _empty;
}
/// <summary>
/// 从队列中获取一个空闲的值集合,或者创建一个新的。
/// </summary>
/// <returns>值集合。</returns>
private HashSet<TValue> Fetch()
{
return _queue.Count <= 0 ? new HashSet<TValue>() : _queue.Dequeue();
}
/// <summary>
/// 回收值集合到队列中,以便重复利用。
/// </summary>
/// <param name="list">要回收的值集合。</param>
private void Recycle(HashSet<TValue> list)
{
list.Clear();
if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return;
_queue.Enqueue(list);
}
/// <summary>
/// 清空集合中的数据并和队列。
/// </summary>
protected new void Clear()
{
base.Clear();
_queue.Clear();
}
}
}

View File

@@ -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
{
/// <summary>
/// 可回收的、一对多关系的列表池。
/// </summary>
/// <typeparam name="TKey">键的类型。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class OneToManyListPool<TKey, TValue> : OneToManyList<TKey, TValue>, IDisposable, IPool where TKey : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个 <see cref="OneToManyListPool{TKey, TValue}"/> 一对多关系的列表池的实例。
/// </summary>
/// <returns>创建的实例。</returns>
public static OneToManyListPool<TKey, TValue> Create()
{
#if FANTASY_WEBGL || FANTASY_EXPORTER
var list = Pool<OneToManyListPool<TKey, TValue>>.Rent();
#else
var list = MultiThreadPool.Rent<OneToManyListPool<TKey, TValue>>();
#endif
list._isDispose = false;
list._isPool = true;
return list;
}
/// <summary>
/// 释放当前对象所占用的资源,并将对象回收到对象池中。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL || FANTASY_EXPORTER
Pool<OneToManyListPool<TKey, TValue>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 一对多关系的列表字典。
/// </summary>
/// <typeparam name="TKey">键的类型。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class OneToManyList<TKey, TValue> : Dictionary<TKey, List<TValue>> where TKey : notnull
{
private readonly int _recyclingLimit = 120;
private static readonly List<TValue> Empty = new List<TValue>();
private readonly Queue<List<TValue>> _queue = new Queue<List<TValue>>();
/// <summary>
/// 初始化一个新的 <see cref="OneToManyList{TKey, TValue}"/> 实例。
/// </summary>
public OneToManyList() { }
/// <summary>
/// 设置最大缓存数量
/// </summary>
/// <param name="recyclingLimit">
/// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC.
/// 2:设置成0不控制数量全部缓存
/// </param>
public OneToManyList(int recyclingLimit)
{
_recyclingLimit = recyclingLimit;
}
/// <summary>
/// 判断给定的键和值是否存在于列表中。
/// </summary>
/// <param name="key">要搜索的键。</param>
/// <param name="value">要搜索的值。</param>
/// <returns>如果存在则为 <see langword="true"/>,否则为 <see langword="false"/>。</returns>
public bool Contains(TKey key, TValue value)
{
TryGetValue(key, out var list);
return list != null && list.Contains(value);
}
/// <summary>
/// 向列表中添加指定键和值。
/// </summary>
/// <param name="key">要添加值的键。</param>
/// <param name="value">要添加的值。</param>
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);
}
/// <summary>
/// 获取指定键对应的列表中的第一个值。
/// </summary>
/// <param name="key">要获取值的键。</param>
/// <returns>键对应的列表中的第一个值。</returns>
public TValue First(TKey key)
{
return !TryGetValue(key, out var list) ? default : list.FirstOrDefault();
}
/// <summary>
/// 从列表中移除指定键和值。
/// </summary>
/// <param name="key">要移除值的键。</param>
/// <param name="value">要移除的值。</param>
/// <returns>如果成功移除则为 <see langword="true"/>,否则为 <see langword="false"/>。</returns>
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;
}
/// <summary>
/// 从列表中移除指定键及其关联的所有值。
/// </summary>
/// <param name="key">要移除的键。</param>
/// <returns>如果成功移除则为 <see langword="true"/>,否则为 <see langword="false"/>。</returns>
public bool RemoveByKey(TKey key)
{
if (!TryGetValue(key, out var list))
{
return false;
}
Remove(key);
Recycle(list);
return true;
}
/// <summary>
/// 获取指定键关联的所有值的列表。
/// </summary>
/// <param name="key">要获取值的键。</param>
/// <returns>键关联的所有值的列表。</returns>
public List<TValue> GetValues(TKey key)
{
if (TryGetValue(key, out List<TValue> list))
{
return list;
}
return Empty;
}
/// <summary>
/// 清除字典中的所有键值对,并回收相关的值集合。
/// </summary>
public new void Clear()
{
foreach (var keyValuePair in this) Recycle(keyValuePair.Value);
base.Clear();
}
/// <summary>
/// 从空闲值集合队列中获取一个值集合,如果队列为空则创建一个新的值集合。
/// </summary>
/// <returns>从队列中获取的值集合。</returns>
private List<TValue> Fetch()
{
return _queue.Count <= 0 ? new List<TValue>() : _queue.Dequeue();
}
/// <summary>
/// 回收一个不再使用的值集合到空闲值集合队列中。
/// </summary>
/// <param name="list">要回收的值集合。</param>
private void Recycle(List<TValue> list)
{
list.Clear();
if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return;
_queue.Enqueue(list);
}
}
}

View File

@@ -1,204 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
#pragma warning disable CS8603
namespace Fantasy.DataStructure.Collection
{
/// <summary>
/// 支持一对多关系的队列池,用于存储具有相同键的值的队列集合。
/// </summary>
/// <typeparam name="TKey">键的类型。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class OneToManyQueuePool<TKey, TValue> : OneToManyQueue<TKey, TValue>, IDisposable, IPool where TKey : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个 <see cref="OneToManyQueuePool{TKey, TValue}"/> 一对多关系的队列池的实例。
/// </summary>
/// <returns>创建的实例。</returns>
public static OneToManyQueuePool<TKey, TValue> Create()
{
#if FANTASY_WEBGL
var a = Pool<OneToManyQueuePool<TKey, TValue>>.Rent();
#else
var a = MultiThreadPool.Rent<OneToManyQueuePool<TKey, TValue>>();
#endif
a._isDispose = false;
a._isPool = true;
return a;
}
/// <summary>
/// 释放当前实例所占用的资源,并将实例回收到对象池中。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<OneToManyQueuePool<TKey, TValue>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 支持一对多关系的队列,用于存储具有相同键的值的队列集合。
/// </summary>
/// <typeparam name="TKey">键的类型。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class OneToManyQueue<TKey, TValue> : Dictionary<TKey, Queue<TValue>> where TKey : notnull
{
private readonly Queue<Queue<TValue>> _queue = new Queue<Queue<TValue>>();
private readonly int _recyclingLimit;
/// <summary>
/// 创建一个 <see cref="OneToManyQueue{TKey, TValue}"/> 一对多关系的队列的实例。设置最大缓存数量
/// </summary>
/// <param name="recyclingLimit">
/// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC.
/// 2:设置成0不控制数量全部缓存
/// </param>
public OneToManyQueue(int recyclingLimit = 0)
{
_recyclingLimit = recyclingLimit;
}
/// <summary>
/// 判断指定键的值队列是否包含指定的值。
/// </summary>
/// <param name="key">要查找的键。</param>
/// <param name="value">要查找的值。</param>
/// <returns>如果存在,则为 <c>true</c>;否则为 <c>false</c>。</returns>
public bool Contains(TKey key, TValue value)
{
TryGetValue(key, out var list);
return list != null && list.Contains(value);
}
/// <summary>
/// 将指定的值添加到指定键的值队列中。
/// </summary>
/// <param name="key">要添加值的键。</param>
/// <param name="value">要添加的值。</param>
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);
}
/// <summary>
/// 从指定键的值队列中出队一个值。
/// </summary>
/// <param name="key">要出队的键。</param>
/// <returns>出队的值。</returns>
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;
}
/// <summary>
/// 尝试从指定键的值队列中出队一个值。
/// </summary>
/// <param name="key">要出队的键。</param>
/// <param name="value">出队的值。</param>
/// <returns>如果成功出队,则为 <c>true</c>;否则为 <c>false</c>。</returns>
public bool TryDequeue(TKey key, out TValue value)
{
value = Dequeue(key);
return value != null;
}
/// <summary>
/// 从字典中移除指定键及其对应的值队列。
/// </summary>
/// <param name="key">要移除的键。</param>
public void RemoveKey(TKey key)
{
if (!TryGetValue(key, out var list)) return;
Remove(key);
Recycle(list);
}
/// <summary>
/// 从队列池中获取一个值队列。如果队列池为空,则创建一个新的值队列。
/// </summary>
/// <returns>获取的值队列。</returns>
private Queue<TValue> Fetch()
{
return _queue.Count <= 0 ? new Queue<TValue>() : _queue.Dequeue();
}
/// <summary>
/// 回收一个不再使用的值队列到队列池中,以便重用。
/// </summary>
/// <param name="list">要回收的值队列。</param>
private void Recycle(Queue<TValue> list)
{
list.Clear();
if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return;
_queue.Enqueue(list);
}
/// <summary>
/// 清空当前实例的数据,同时回收所有值队列。
/// </summary>
protected new void Clear()
{
base.Clear();
_queue.Clear();
}
}
}

View File

@@ -1,69 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
namespace Fantasy.DataStructure.Collection
{
/// <summary>
/// 可重用的列表,继承自 <see cref="List{T}"/> 类。该类支持通过对象池重用列表实例,以减少对象分配和释放的开销。
/// </summary>
/// <typeparam name="T">列表中元素的类型。</typeparam>
public sealed class ReuseList<T> : List<T>, IDisposable, IPool
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个 <see cref="ReuseList{T}"/> 可重用的列表的实例。
/// </summary>
/// <returns>创建的实例。</returns>
public static ReuseList<T> Create()
{
#if FANTASY_WEBGL
var list = Pool<ReuseList<T>>.Rent();
#else
var list = MultiThreadPool.Rent<ReuseList<T>>();
#endif
list._isDispose = false;
list._isPool = true;
return list;
}
/// <summary>
/// 释放该实例所占用的资源,并将实例返回到对象池中,以便重用。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<ReuseList<T>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
}

View File

@@ -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
{
/// <summary>
/// 基于排序字典和并发集合实现的一对多映射列表的对象池包装类,继承自 <see cref="SortedConcurrentOneToManyList{TKey, TValue}"/> 类,
/// 同时实现了 <see cref="IDisposable"/> 接口,以支持对象的重用和释放。
/// </summary>
/// <typeparam name="TKey">键的类型。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class SortedConcurrentOneToManyListPool<TKey, TValue> : SortedConcurrentOneToManyList<TKey, TValue>, IDisposable, IPool where TKey : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个新的 <see cref="SortedConcurrentOneToManyListPool{TKey, TValue}"/> 实例,使用默认的参数设置。
/// </summary>
/// <returns>新创建的 <see cref="SortedConcurrentOneToManyListPool{TKey, TValue}"/> 实例。</returns>
public static SortedConcurrentOneToManyListPool<TKey, TValue> Create()
{
var a = MultiThreadPool.Rent<SortedConcurrentOneToManyListPool<TKey, TValue>>();
a._isDispose = false;
a._isPool = true;
return a;
}
/// <summary>
/// 释放当前对象池实例,将其返回到对象池以供重用。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
MultiThreadPool.Return(this);
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 基于排序字典和并发集合实现的一多对映射列表类,继承自 <see cref="SortedDictionary{TKey, TValue}"/> 类,
/// 用于在多个值与一个键关联的情况下进行管理和存储。该类支持并发操作,适用于多线程环境。
/// </summary>
/// <typeparam name="TKey">键的类型。</typeparam>
/// <typeparam name="TValue">值的类型。</typeparam>
public class SortedConcurrentOneToManyList<TKey, TValue> : SortedDictionary<TKey, List<TValue>> where TKey : notnull
{
/// 用于同步操作的锁对象,它确保在多线程环境下对数据的安全访问。
private readonly object _lockObject = new object();
/// 用于存储缓存的队列。
private readonly Queue<List<TValue>> _queue = new Queue<List<TValue>>();
/// 控制缓存回收的限制。当缓存的数量超过此限制时,旧的缓存将会被回收。
private readonly int _recyclingLimit;
/// <summary>
/// 初始化一个新的 <see cref="SortedConcurrentOneToManyList{TKey, TValue}"/> 类的实例,使用默认的参数设置。
/// </summary>
public SortedConcurrentOneToManyList()
{
}
/// <summary>
/// 初始化一个新的 <see cref="SortedConcurrentOneToManyList{TKey, TValue}"/> 类的实例,指定最大缓存数量。
/// </summary>
/// <param name="recyclingLimit">
/// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC.
/// 2:设置成0不控制数量全部缓存
/// </param>
public SortedConcurrentOneToManyList(int recyclingLimit = 0)
{
_recyclingLimit = recyclingLimit;
}
/// <summary>
/// 检查指定的键和值是否存在于映射列表中。
/// </summary>
/// <param name="key">要检查的键。</param>
/// <param name="value">要检查的值。</param>
/// <returns>如果存在,则为 true否则为 false。</returns>
public bool Contains(TKey key, TValue value)
{
lock (_lockObject)
{
TryGetValue(key, out var list);
return list != null && list.Contains(value);
}
}
/// <summary>
/// 将指定的值添加到与指定键关联的列表中。
/// </summary>
/// <param name="key">要关联值的键。</param>
/// <param name="value">要添加到列表的值。</param>
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);
}
}
/// <summary>
/// 获取与指定键关联的列表中的第一个值。
/// 如果列表不存在或为空,则返回默认值。
/// </summary>
/// <param name="key">要获取第一个值的键。</param>
/// <returns>第一个值,或默认值。</returns>
public TValue First(TKey key)
{
lock (_lockObject)
{
return !TryGetValue(key, out var list) ? default : list.FirstOrDefault();
}
}
/// <summary>
/// 从与指定键关联的列表中移除指定的值。
/// 如果列表不存在或值不存在于列表中,则不执行任何操作。
/// </summary>
/// <param name="key">要移除值的键。</param>
/// <param name="value">要移除的值。</param>
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);
}
}
/// <summary>
/// 从映射列表中移除指定的键及其关联的列表。
/// 如果键不存在于映射列表中,则不执行任何操作。
/// </summary>
/// <param name="key">要移除的键。</param>
public void RemoveKey(TKey key)
{
lock (_lockObject)
{
if (!TryGetValue(key, out var list)) return;
Remove(key);
Recycle(list);
}
}
/// <summary>
/// 从缓存中获取一个可重用的列表。如果缓存中不存在列表,则创建一个新的列表并返回。
/// </summary>
/// <returns>可重用的列表。</returns>
private List<TValue> Fetch()
{
lock (_lockObject)
{
return _queue.Count <= 0 ? new List<TValue>() : _queue.Dequeue();
}
}
/// <summary>
/// 将不再使用的列表回收到缓存中,以便重复利用。如果缓存数量超过限制,则丢弃列表而不进行回收。
/// </summary>
/// <param name="list">要回收的列表。</param>
private void Recycle(List<TValue> list)
{
lock (_lockObject)
{
list.Clear();
if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return;
_queue.Enqueue(list);
}
}
/// <summary>
/// 清空映射列表以及队列。
/// </summary>
protected new void Clear()
{
base.Clear();
_queue.Clear();
}
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More