饭太稀
This commit is contained in:
@@ -0,0 +1 @@
|
||||
// 自定义导出配置文件,用于配置自定义导出自定义程序的路径
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{"WorksheetNames":[-8419147776733210060,-3495952183970875596,1720330851179383898,5812538452563588342],"Tables":{"-3495952183970875596":1747624043302,"-1088042625810372120":1731573652950,"1720330851179383898":1728449870789,"3730651590607244245":1731575713470,"5812538452563588342":1748394916174}}
|
||||
@@ -0,0 +1,3 @@
|
||||
{"List":[
|
||||
{"Id":1,"OuterIP":"127.0.0.1","OuterBindIP":"127.0.0.1","InnerBindIP":"127.0.0.1"}
|
||||
]}
|
||||
@@ -0,0 +1,3 @@
|
||||
{"List":[
|
||||
{"Id":1,"MachineId":1,"StartupGroup":0}
|
||||
]}
|
||||
@@ -0,0 +1,6 @@
|
||||
{"List":[
|
||||
{"Id":1001,"ProcessConfigId":1,"WorldConfigId":1,"SceneRuntimeMode":"MultiThread","SceneTypeString":"Addressable","NetworkProtocol":null,"OuterPort":0,"InnerPort":11001,"SceneType":2},
|
||||
{"Id":1002,"ProcessConfigId":1,"WorldConfigId":1,"SceneRuntimeMode":"MultiThread","SceneTypeString":"Gate","NetworkProtocol":"KCP","OuterPort":20000,"InnerPort":11002,"SceneType":3},
|
||||
{"Id":1003,"ProcessConfigId":1,"WorldConfigId":1,"SceneRuntimeMode":"MultiThread","SceneTypeString":"Map","NetworkProtocol":null,"OuterPort":0,"InnerPort":11003,"SceneType":4},
|
||||
{"Id":1004,"ProcessConfigId":1,"WorldConfigId":1,"SceneRuntimeMode":"MultiThread","SceneTypeString":"Chat","NetworkProtocol":null,"OuterPort":0,"InnerPort":11004,"SceneType":8}
|
||||
]}
|
||||
@@ -0,0 +1,3 @@
|
||||
{"List":[
|
||||
{"Id":1,"WorldName":"测试服","DbConnection":null,"DbName":"fantasy_main","DbType":"MongoDB"}
|
||||
]}
|
||||
@@ -0,0 +1,27 @@
|
||||
syntax = "proto3";
|
||||
package Sining.Message;
|
||||
message G2A_TestRequest // IRouteRequest,G2A_TestResponse
|
||||
{
|
||||
|
||||
}
|
||||
message G2A_TestResponse // IRouteResponse
|
||||
{
|
||||
|
||||
}
|
||||
message G2M_RequestAddressableId // IRouteRequest,M2G_ResponseAddressableId
|
||||
{
|
||||
|
||||
}
|
||||
message M2G_ResponseAddressableId // IRouteResponse
|
||||
{
|
||||
int64 AddressableId = 1; // Map服务器返回的AddressableId
|
||||
}
|
||||
/// 通知Chat服务器创建一个RouteId
|
||||
message G2Chat_CreateRouteRequest // IRouteRequest,Chat2G_CreateRouteResponse
|
||||
{
|
||||
int64 GateRouteId = 1;
|
||||
}
|
||||
message Chat2G_CreateRouteResponse // IRouteResponse
|
||||
{
|
||||
int64 ChatRouteId = 1;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,64 @@
|
||||
syntax = "proto3";
|
||||
package Fantasy.Network.Message;
|
||||
// 协议分为:
|
||||
// ProtoBuf:可以在Outer和Inner文件里使用。
|
||||
// MemoryPack:可以在Outer和Inner文件里使用。
|
||||
// Bson:仅支持在Inner文件里使用。
|
||||
// 使用方式:
|
||||
// 在message协议上方添加// Protocol+空格+协议名字
|
||||
// 例如:// Protocol ProtoBuf 或 // Protocol MemoryPack
|
||||
message C2G_TestMessage // IMessage
|
||||
{
|
||||
string Tag = 1;
|
||||
}
|
||||
message C2G_TestRequest // IRequest,G2C_TestResponse
|
||||
{
|
||||
string Tag = 1;
|
||||
}
|
||||
message G2C_TestResponse // IResponse
|
||||
{
|
||||
string Tag = 1;
|
||||
}
|
||||
message C2G_CreateAddressableRequest // IRequest,G2C_CreateAddressableResponse
|
||||
{
|
||||
|
||||
}
|
||||
message G2C_CreateAddressableResponse // IResponse
|
||||
{
|
||||
|
||||
}
|
||||
message C2M_TestMessage // IAddressableRouteMessage
|
||||
{
|
||||
string Tag = 1;
|
||||
}
|
||||
message C2M_TestRequest // IAddressableRouteRequest,M2C_TestResponse
|
||||
{
|
||||
string Tag = 1;
|
||||
}
|
||||
message M2C_TestResponse // IAddressableRouteResponse
|
||||
{
|
||||
string Tag = 1;
|
||||
}
|
||||
/// 通知Gate服务器创建一个Chat的Route连接
|
||||
message C2G_CreateChatRouteRequest // IRequest,G2C_CreateChatRouteResponse
|
||||
{
|
||||
|
||||
}
|
||||
message G2C_CreateChatRouteResponse // IResponse
|
||||
{
|
||||
|
||||
}
|
||||
/// 发送一个Route消息给Chat
|
||||
message C2Chat_TestMessage // ICustomRouteMessage,ChatRoute
|
||||
{
|
||||
string Tag = 1;
|
||||
}
|
||||
/// 发送一个RPCRoute消息给Chat
|
||||
message C2Chat_TestMessageRequest // ICustomRouteRequest,Chat2C_TestMessageResponse,ChatRoute
|
||||
{
|
||||
string Tag = 1;
|
||||
}
|
||||
message Chat2C_TestMessageResponse // ICustomRouteResponse
|
||||
{
|
||||
string Tag = 1;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// Route协议定义(需要定义1000以上、因为1000以内的框架预留)
|
||||
GateRoute = 1001 // Gate
|
||||
ChatRoute = 1002 // Chat
|
||||
@@ -0,0 +1,25 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- 物理复制 Exporter 文件到项目根目录,保留目录结构 -->
|
||||
<Target Name="CopyExporterFilesToProject" BeforeTargets="PrepareForBuild">
|
||||
<ItemGroup>
|
||||
<!-- 获取需要复制的文件 -->
|
||||
<ExporterFilesToCopy Include="$(MSBuildThisFileDirectory)..\tools\output\**\*" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- 生成目标路径,保持原有目录结构 -->
|
||||
<ExporterFilesWithDestination Include="@(ExporterFilesToCopy)">
|
||||
<DestinationPath>$(MSBuildProjectDirectory)\Tools\Exporter\ConfigTable\%(RecursiveDir)%(Filename)%(Extension)</DestinationPath>
|
||||
</ExporterFilesWithDestination>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- 日志输出 -->
|
||||
<Message Text="Source: %(ExporterFilesWithDestination.Identity), Destination: %(ExporterFilesWithDestination.DestinationPath)" />
|
||||
|
||||
<!-- 复制文件 -->
|
||||
<Copy
|
||||
SourceFiles="@(ExporterFilesWithDestination)"
|
||||
DestinationFiles="@(ExporterFilesWithDestination->'%(DestinationPath)')"
|
||||
SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageId>Fantasy-Net.Config</PackageId>
|
||||
<PackageVersion>2024.1.4</PackageVersion>
|
||||
<Title>Fantasy-Net.Config</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>
|
||||
<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.Config</AssemblyName>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<LangVersion>default</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Config/**/*" Pack="true" PackagePath="tools\output\" />
|
||||
<None Include="README.md" Pack="true" PackagePath="tools\output\" />
|
||||
<None Include="icon.png" Pack="true" PackagePath="\"/>
|
||||
<None Include="README.md" Pack="true" PackagePath="\"/>
|
||||
<None Include="Fantasy-Net.Config.targets" Pack="true" PackagePath="buildTransitive" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="**\.DS_Store" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
16
Fantasy/Fantasy.Packages/Fantasy.Config/README.md
Normal file
16
Fantasy/Fantasy.Packages/Fantasy.Config/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Fantasy-Net.Config
|
||||
在Config文件夹中,存放着Fantasy所需的各种配置文件。这些文件涵盖了多个方面。每个配置文件都有其特定的格式和功能,通过精心设计的这些配置文件,开发团队能够快速调整框架参数,以实现更好的游戏体验,从而提升Fantasy的整体质量。
|
||||
## Excel文件夹
|
||||
里面存放了Fantasy.Net所需的四个Excel配置文件。用户可以利用Fantasy-Net.Exporter工具,依据这四个Excel文件生成相应的JSON文件,以供框架使用。这一过程不仅简化了数据处理,还确保了不同组件之间的无缝对接,使得工作流程更加高效。请确保在导出之前,Excel文件的格式和内容符合要求,以避免产生错误。
|
||||
## Json文件夹
|
||||
在该目录中存放了Fantasy.Net所需的四个JSON配置文件。用户可以根据这四个文件的模板进行添加或修改配置,以满足具体需求。每个项目的功能说明在相应的Excel文件中有详细描述,方便用户理解和使用这些配置文件。我们建议用户仔细阅读Excel文件中的说明,以确保配置的正确性和有效性。
|
||||
## NetworkProtocol文件夹
|
||||
存放框架所需定义网络协议的模版和文件夹
|
||||
### Inner文件夹
|
||||
定义服务器之间的网络协议
|
||||
### Outer文件夹
|
||||
定义客户端和服务器之间的网络协议
|
||||
### RouteType.Config
|
||||
定义自定义Route协议的配置文件
|
||||
## 交流与讨论:
|
||||
__讨论QQ群 : Fantasy服务器开发交流群 569888673 __
|
||||
BIN
Fantasy/Fantasy.Packages/Fantasy.Config/icon.png
Normal file
BIN
Fantasy/Fantasy.Packages/Fantasy.Config/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 246 B |
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Fantasy.Platform.Net;
|
||||
using Fantasy.Serialize;
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
// ReSharper disable SuspiciousTypeConversion.Global
|
||||
|
||||
namespace Fantasy.ConfigTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置表帮助类
|
||||
/// </summary>
|
||||
public static class ConfigTableHelper
|
||||
{
|
||||
private static string _configTableBinaryDirectory;
|
||||
private static readonly object Lock = new object();
|
||||
// 配置表数据缓存字典
|
||||
private static readonly Dictionary<string, ASerialize> ConfigDic = new ();
|
||||
/// <summary>
|
||||
/// 初始化ConfigTableHelper
|
||||
/// </summary>
|
||||
/// <param name="configTableBinaryDirectory"></param>
|
||||
public static void Initialize(string configTableBinaryDirectory)
|
||||
{
|
||||
_configTableBinaryDirectory = configTableBinaryDirectory;
|
||||
}
|
||||
/// <summary>
|
||||
/// 加载配置表数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置表类型</typeparam>
|
||||
/// <returns>配置表数据</returns>
|
||||
public static T Load<T>() where T : ASerialize
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dataConfig = typeof(T).Name;
|
||||
|
||||
if (ConfigDic.TryGetValue(dataConfig, out var aProto))
|
||||
{
|
||||
return (T)aProto;
|
||||
}
|
||||
|
||||
var configFile = GetConfigPath(dataConfig);
|
||||
var bytes = File.ReadAllBytes(configFile);
|
||||
// Log.Debug($"dataConfig:{dataConfig} {bytes.Length}");
|
||||
var data = SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf).Deserialize<T>(bytes);
|
||||
ConfigDic[dataConfig] = data;
|
||||
return data;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"ConfigTableManage:{typeof(T).Name} 数据表加载之后反序列化时出错:{ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取配置表文件路径
|
||||
/// </summary>
|
||||
/// <param name="name">配置表名称</param>
|
||||
/// <returns>配置表文件路径</returns>
|
||||
private static string GetConfigPath(string name)
|
||||
{
|
||||
var configFile = Path.Combine(_configTableBinaryDirectory, $"{name}.bytes");
|
||||
|
||||
if (File.Exists(configFile))
|
||||
{
|
||||
return configFile;
|
||||
}
|
||||
|
||||
throw new FileNotFoundException($"{name}.byte not found: {configFile}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新加载配置表数据
|
||||
/// </summary>
|
||||
public static void ReLoadConfigTable()
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
foreach (var (_, aProto) in ConfigDic)
|
||||
{
|
||||
((IDisposable) aProto).Dispose();
|
||||
}
|
||||
|
||||
ConfigDic.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using ProtoBuf;
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
// ReSharper disable CheckNamespace
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
namespace Fantasy.ConfigTable
|
||||
{
|
||||
[ProtoContract]
|
||||
public partial class IntDictionaryConfig
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public Dictionary<int, int> Dic;
|
||||
public int this[int key] => GetValue(key);
|
||||
public bool TryGetValue(int key, out int value)
|
||||
{
|
||||
value = default;
|
||||
|
||||
if (!Dic.ContainsKey(key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = Dic[key];
|
||||
return true;
|
||||
}
|
||||
private int GetValue(int key)
|
||||
{
|
||||
return Dic.TryGetValue(key, out var value) ? value : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
using ProtoBuf;
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
// ReSharper disable CheckNamespace
|
||||
// ReSharper disable CollectionNeverUpdated.Global
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
namespace Fantasy.ConfigTable
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class StringDictionaryConfig
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public Dictionary<int, string> Dic;
|
||||
public string this[int key] => GetValue(key);
|
||||
public bool TryGetValue(int key, out string value)
|
||||
{
|
||||
value = default;
|
||||
|
||||
if (!Dic.ContainsKey(key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = Dic[key];
|
||||
return true;
|
||||
}
|
||||
private string GetValue(int key)
|
||||
{
|
||||
return Dic.TryGetValue(key, out var value) ? value : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageId>Fantasy-Net.ConfigTable</PackageId>
|
||||
<PackageVersion>2024.2.0</PackageVersion>
|
||||
<Title>Fantasy-Net.ConfigTable</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>
|
||||
<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.ConfigTable</AssemblyName>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<LangVersion>default</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fantasy-Net" Version="2024.2.22" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="icon.png" Pack="true" PackagePath="\"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Fantasy.ConfigTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示是一个配置文件
|
||||
/// </summary>
|
||||
public interface IConfigTable { }
|
||||
}
|
||||
BIN
Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/icon.png
Normal file
BIN
Fantasy/Fantasy.Packages/Fantasy.ConfigTable/Net/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 246 B |
74
Fantasy/Fantasy.Packages/Fantasy.ConfigTable/README.md
Normal file
74
Fantasy/Fantasy.Packages/Fantasy.ConfigTable/README.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Fantasy.ConfigTable
|
||||
|
||||
Fantasy配置表扩展包,配合Tools里面的配置导出工具使用,注意该包依赖Fantasy包。
|
||||
|
||||
- Unity : 需要先安装Fantasy.Unity
|
||||
- Net : 需要先安装Fantasy.Net
|
||||
## Unity
|
||||
|
||||
在Unity中使用Package Manager,点击左上角➕选择add package from disk,选择package.json安装。
|
||||
|
||||
Unity端采用assetbundle方式加载配置文件,需要把配置文件放到一个包中,例如config的ab包。
|
||||
|
||||
可以在导出工具中设置导出到前端二进制文件的路径,设置到这个config包中。
|
||||
|
||||
用代码使用一个IConfigTableAssetBundle接口
|
||||
|
||||
```csharp
|
||||
public sealed class AsserBundleManager : IConfigTableAssetBundle
|
||||
{
|
||||
public string Combine(string assetBundleDirectoryPath, string dataConfig)
|
||||
{
|
||||
// 该方法用于拼装ab包的路径,因为不同的ab包资源管理工具路径都不一样
|
||||
// 所以这里提供该方法自定义路径
|
||||
return Path.Combine(assetBundleDirectoryPath, $"{dataConfig}.bytes");
|
||||
}
|
||||
|
||||
public byte[] LoadConfigTable(string assetBundlePath)
|
||||
{
|
||||
// 这里是加载包里的二进制文件的逻辑。
|
||||
// 正常的情况下需要分编辑器和打包环境下。
|
||||
// 这里只做了编辑器下拿取ab包里的某个配置文件的逻辑。
|
||||
// 正常情况下要把非编辑器环境的逻辑也要写好。
|
||||
if (File.Exists(assetBundlePath))
|
||||
{
|
||||
return AssetDatabase.LoadAssetAtPath<TextAsset>(assetBundlePath).bytes;
|
||||
}
|
||||
UnityEngine.Debug.LogError($"assetBundlePath:{assetBundlePath} not exist");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
上述工作完成够,可以在项目入口点执行初始化代码
|
||||
|
||||
```csharp
|
||||
// 第一个参数是指定ab包的路径,但不包含配置名字,因为配置文件会在上面的AsserBundleManager里Combine方法拼接出的路径
|
||||
// 同样这里因为是编辑环境下,所以我输入的是一个路径。
|
||||
// 但如果打包后这个路径其实并不能使用,要把这个路径改成ab包发布都得正常路径。
|
||||
ConfigTableHelper.Initialize("Assets/Bundles/Config/", new AsserBundleManager());
|
||||
```
|
||||
|
||||
## Net
|
||||
|
||||
```csharp
|
||||
// 设置配置表的路径
|
||||
// 导出工具会把配置表的二进制数据导出到一个目录中。
|
||||
// 服务器启动的时候需要传入这个目录的路径。
|
||||
// 我这里使用了相对路径,大家可以根据自己的环境更改目录
|
||||
ConfigTableHelper.Initialize("../../../Config/Binary");
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
初始化完成后,就可以在项目中使用配置文件了
|
||||
|
||||
```csharp
|
||||
// 例如我配置了一个表名为UnitConfig,那在导出在代码中使用只需要再这个表名后面加上Data
|
||||
// 然后在使用下面的Instance就可以访问表里的数据了
|
||||
|
||||
// 获得表里的所有数据
|
||||
var instanceList = UnitConfigData.Instance.List;
|
||||
// 根据表的主键Id来获得数据,这里的1就是表对应的Id
|
||||
var unitConfig = UnitConfigData.Instance.Get(1);
|
||||
```
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Fantasy.ConfigTable",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:0b7224b83ba514121aa026f3857f820a"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4d36c5a80dc44c6e822eba8db9ed704
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfbf88374cb6b49f2947ab95a9bc08ba
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Fantasy.Serialize;
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
// ReSharper disable SuspiciousTypeConversion.Global
|
||||
|
||||
namespace Fantasy.ConfigTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置表帮助类
|
||||
/// </summary>
|
||||
public static class ConfigTableHelper
|
||||
{
|
||||
private static string _assetBundleDirectoryPath;
|
||||
private static IConfigTableAssetBundle _configTableAssetBundle;
|
||||
private static readonly object Lock = new object();
|
||||
// 配置表数据缓存字典
|
||||
private static readonly Dictionary<string, ASerialize> ConfigDic = new ();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化ConfigTableHelper
|
||||
/// </summary>
|
||||
/// <param name="assetBundleDirectoryPath"></param>
|
||||
/// <param name="configTableAssetBundle"></param>
|
||||
public static void Initialize(string assetBundleDirectoryPath, IConfigTableAssetBundle configTableAssetBundle)
|
||||
{
|
||||
_assetBundleDirectoryPath = assetBundleDirectoryPath;
|
||||
_configTableAssetBundle = configTableAssetBundle;
|
||||
}
|
||||
/// <summary>
|
||||
/// 加载配置表数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置表类型</typeparam>
|
||||
/// <returns>配置表数据</returns>
|
||||
public static T Load<T>() where T : ASerialize
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dataConfig = typeof(T).Name;
|
||||
|
||||
if (ConfigDic.TryGetValue(dataConfig, out var aProto))
|
||||
{
|
||||
return (T)aProto;
|
||||
}
|
||||
|
||||
var dataConfigPath = _configTableAssetBundle.Combine(_assetBundleDirectoryPath, dataConfig);
|
||||
var bytes = _configTableAssetBundle.LoadConfigTable(dataConfigPath);
|
||||
var data = SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf).Deserialize<T>(bytes);
|
||||
ConfigDic[dataConfig] = data;
|
||||
return data;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"ConfigTableManage:{typeof(T).Name} 数据表加载之后反序列化时出错:{ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新加载配置表数据
|
||||
/// </summary>
|
||||
public static void ReLoadConfigTable()
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
foreach (var (_, aProto) in ConfigDic)
|
||||
{
|
||||
((IDisposable) aProto).Dispose();
|
||||
}
|
||||
|
||||
ConfigDic.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e3ca7a021b1c445a9f58c1e4645fe17
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e10a07ad20ee4d7298ee808a3ea8b73
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using ProtoBuf;
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
// ReSharper disable CheckNamespace
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
namespace Fantasy.ConfigTable
|
||||
{
|
||||
[ProtoContract]
|
||||
public partial class IntDictionaryConfig
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public Dictionary<int, int> Dic;
|
||||
public int this[int key] => GetValue(key);
|
||||
public bool TryGetValue(int key, out int value)
|
||||
{
|
||||
value = default;
|
||||
|
||||
if (!Dic.ContainsKey(key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = Dic[key];
|
||||
return true;
|
||||
}
|
||||
private int GetValue(int key)
|
||||
{
|
||||
return Dic.TryGetValue(key, out var value) ? value : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 294753d61a7ac401f9f1b75e43d7536e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
using ProtoBuf;
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
// ReSharper disable CheckNamespace
|
||||
// ReSharper disable CollectionNeverUpdated.Global
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
namespace Fantasy.ConfigTable
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class StringDictionaryConfig
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public Dictionary<int, string> Dic;
|
||||
public string this[int key] => GetValue(key);
|
||||
public bool TryGetValue(int key, out string value)
|
||||
{
|
||||
value = default;
|
||||
|
||||
if (!Dic.ContainsKey(key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = Dic[key];
|
||||
return true;
|
||||
}
|
||||
private string GetValue(int key)
|
||||
{
|
||||
return Dic.TryGetValue(key, out var value) ? value : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 295679520921148c685abac87ba609fd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e229cd1e867af419193a32fefaf271df
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Fantasy.ConfigTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示是一个配置文件
|
||||
/// </summary>
|
||||
public interface IConfigTable { }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba91b698a7df846c185a3d9e384f71b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace Fantasy.ConfigTable
|
||||
{
|
||||
public interface IConfigTableAssetBundle
|
||||
{
|
||||
/// <summary>
|
||||
/// 不同的资源管理器有各自独特的包加载方式。
|
||||
/// 为了满足不同的需求,我们提供了这个接口,允许用户自定义拼装包路径。
|
||||
/// 通过这个接口,用户可以根据自己的特定格式和要求,灵活地加载包,从而提高资源管理的灵活性和效率。
|
||||
/// </summary>
|
||||
/// <param name="assetBundleDirectoryPath"></param>
|
||||
/// <param name="dataConfig"></param>
|
||||
/// <returns></returns>
|
||||
public string Combine(string assetBundleDirectoryPath, string dataConfig);
|
||||
public byte[] LoadConfigTable(string assetBundlePath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a819f57dfada43d9955a9b402772cf6d
|
||||
timeCreated: 1728549292
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "com.fantasy.configtable",
|
||||
"version": "2024.2.24",
|
||||
"displayName": "Fantasy.ConfigTable",
|
||||
"description": "Fantasy is a cross platform distributed server framework.",
|
||||
"category": "Network Framework",
|
||||
"documentationUrl": "https://www.code-fantasy.com/",
|
||||
"changelogUrl": "https://www.code-fantasy.com/",
|
||||
"licensesUrl": "https://www.code-fantasy.com/",
|
||||
"keywords": [
|
||||
"Fantasy",
|
||||
"Framework",
|
||||
"hotfix",
|
||||
"Server",
|
||||
"Network"
|
||||
],
|
||||
"author": {
|
||||
"name": "Fantasy",
|
||||
"email": "362946@qq.com",
|
||||
"url": "https://www.code-fantasy.com/"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db12b302eec284d61984b0798590173a
|
||||
PackageManifestImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,212 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using MemoryPack;
|
||||
|
||||
namespace Fantasy.Serialize
|
||||
{
|
||||
/// <summary>
|
||||
/// MemoryPack帮助类
|
||||
/// </summary>
|
||||
public sealed class MemoryPackHelper : ISerialize
|
||||
{
|
||||
/// <summary>
|
||||
/// 序列化器的名字
|
||||
/// </summary>
|
||||
public string SerializeName { get; } = "MemoryPack";
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public T Deserialize<T>(byte[] bytes)
|
||||
{
|
||||
var @object = MemoryPackSerializer.Deserialize<T>(bytes);
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.AfterDeserialization();
|
||||
}
|
||||
|
||||
return @object;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public T Deserialize<T>(MemoryStreamBuffer buffer)
|
||||
{
|
||||
var @object = MemoryPackSerializer.Deserialize<T>(buffer.GetSpan());
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.AfterDeserialization();
|
||||
}
|
||||
|
||||
return @object;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="bytes"></param>
|
||||
/// <returns></returns>
|
||||
public object Deserialize(Type type, byte[] bytes)
|
||||
{
|
||||
var @object = MemoryPackSerializer.Deserialize(type,bytes);
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.AfterDeserialization();
|
||||
}
|
||||
|
||||
return @object;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="buffer"></param>
|
||||
/// <returns></returns>
|
||||
public object Deserialize(Type type, MemoryStreamBuffer buffer)
|
||||
{
|
||||
var @object = MemoryPackSerializer.Deserialize(type, buffer.GetSpan());
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.AfterDeserialization();
|
||||
}
|
||||
|
||||
return @object;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public T Deserialize<T>(byte[] bytes, int index, int count)
|
||||
{
|
||||
var @object = MemoryPackSerializer.Deserialize<T>(new ReadOnlySpan<byte>(bytes, index, count));
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.AfterDeserialization();
|
||||
}
|
||||
|
||||
return @object;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
public object Deserialize(Type type, byte[] bytes, int index, int count)
|
||||
{
|
||||
var @object = MemoryPackSerializer.Deserialize(type, new ReadOnlySpan<byte>(bytes, index, count));
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.AfterDeserialization();
|
||||
}
|
||||
|
||||
return @object;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 序列化
|
||||
/// </summary>
|
||||
/// <param name="object"></param>
|
||||
/// <param name="buffer"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public void Serialize<T>(T @object, IBufferWriter<byte> buffer)
|
||||
{
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.BeginInit();
|
||||
}
|
||||
|
||||
MemoryPackSerializer.Serialize<T, IBufferWriter<byte>>(buffer, @object);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 序列化
|
||||
/// </summary>
|
||||
/// <param name="object"></param>
|
||||
/// <param name="buffer"></param>
|
||||
public void Serialize(object @object, IBufferWriter<byte> buffer)
|
||||
{
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.BeginInit();
|
||||
}
|
||||
|
||||
MemoryPackSerializer.Serialize(@object.GetType(), buffer, @object);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 序列化
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="object"></param>
|
||||
/// <param name="buffer"></param>
|
||||
public void Serialize(Type type, object @object, IBufferWriter<byte> buffer)
|
||||
{
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.BeginInit();
|
||||
}
|
||||
|
||||
MemoryPackSerializer.Serialize(type, buffer, @object);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 序列化
|
||||
/// </summary>
|
||||
/// <param name="object"></param>
|
||||
/// <returns></returns>
|
||||
public byte[] Serialize(object @object)
|
||||
{
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.BeginInit();
|
||||
}
|
||||
|
||||
return MemoryPackSerializer.Serialize(@object.GetType(), @object);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 序列化
|
||||
/// </summary>
|
||||
/// <param name="object"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public byte[] Serialize<T>(T @object)
|
||||
{
|
||||
if (@object is ASerialize aSerialize)
|
||||
{
|
||||
aSerialize.BeginInit();
|
||||
}
|
||||
|
||||
return MemoryPackSerializer.Serialize<T>(@object);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 克隆
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public T Clone<T>(T t)
|
||||
{
|
||||
return Deserialize<T>(Serialize(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Fantasy/Fantasy.Packages/Fantasy.MemoryPack/README.md
Normal file
25
Fantasy/Fantasy.Packages/Fantasy.MemoryPack/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Fantasy.MemoryPack 扩展包
|
||||
## Unity
|
||||
Unity使用,只需要再Unity文件夹里,导入Fantays.MemoryPack.unitypackage到Unity里即可。
|
||||
## Net
|
||||
* 在你的项目里用Nuget或dotnet add package MemoryPack安装MemoryPack的库。
|
||||
* 再Net文件夹里把MemoryPack文件夹拷贝的项目中。
|
||||
## Tools
|
||||
编辑改导表工具ExporterSettings.json文件,在文件Serializes里增加MemoryPack协议的说明.
|
||||
```json
|
||||
"Serializes": {
|
||||
"Value": [
|
||||
{
|
||||
"KeyIndex": 0,
|
||||
"NameSpace" : "MemoryPack",
|
||||
"SerializeName": "MemoryPack",
|
||||
"Attribute": "\t[MemoryPackable]",
|
||||
"Ignore": "\t\t[MemoryPackIgnore]",
|
||||
"Member": "MemoryPackOrder"
|
||||
}
|
||||
],
|
||||
"Comment": "自定义序列化器"
|
||||
}
|
||||
```
|
||||
## 使用注意
|
||||
无论是Unity或Net下,导入所在的项目,必须要把当前程序集装载到框架中才可以。
|
||||
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- 物理复制 NLog 配置文件到项目根目录 -->
|
||||
<Target Name="CopyNLogFilesToProject" BeforeTargets="PrepareForBuild">
|
||||
<ItemGroup>
|
||||
<!-- 定义源文件路径,指向 NuGet 包中的文件 -->
|
||||
<FilesToCopy Include="$(MSBuildThisFileDirectory)..\build\NLog.config" />
|
||||
<FilesToCopy Include="$(MSBuildThisFileDirectory)..\build\NLog.xsd" />
|
||||
</ItemGroup>
|
||||
<!-- 仅当目标文件不存在时才执行复制操作 -->
|
||||
<Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(MSBuildProjectDirectory)" Condition="!Exists('$(MSBuildProjectDirectory)\NLog.config')" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(MSBuildProjectDirectory)" Condition="!Exists('$(MSBuildProjectDirectory)\NLog.xsd')" SkipUnchangedFiles="true" />
|
||||
<ItemGroup>
|
||||
<!-- 使用 Include 确保文件在解决方案中显示 -->
|
||||
<None Include="$(MSBuildProjectDirectory)\NLog.config">
|
||||
<!-- 确保复制到输出目录,并设置复制模式 -->
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildProjectDirectory)\NLog.xsd">
|
||||
<!-- 确保复制到输出目录,并设置复制模式 -->
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
38
Fantasy/Fantasy.Packages/Fantasy.NLog/Fantasy.NLog.csproj
Normal file
38
Fantasy/Fantasy.Packages/Fantasy.NLog/Fantasy.NLog.csproj
Normal file
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageId>Fantasy-Net.NLog</PackageId>
|
||||
<PackageVersion>2024.1.20</PackageVersion>
|
||||
<Title>Fantasy-Net.NLog</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>
|
||||
<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.NLog</AssemblyName>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<LangVersion>default</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fantasy-Net" Version="2024.2.22" />
|
||||
<PackageReference Include="NLog" Version="5.3.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="NLog.config" Pack="true" PackagePath="build\NLog.config" />
|
||||
<None Include="NLog.xsd" Pack="true" PackagePath="build\NLog.xsd" />
|
||||
<None Include="Fantasy-Net.NLog.targets" Pack="true" PackagePath="buildTransitive" />
|
||||
<None Include="icon.png" Pack="true" PackagePath="\"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
91
Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.config
Normal file
91
Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.config
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd">
|
||||
<targets async="true">
|
||||
<target name="ServerDebug" xsi:type="File"
|
||||
encoding="UTF-8"
|
||||
createDirs="true"
|
||||
autoFlush="false"
|
||||
keepFileOpen="true"
|
||||
concurrentWrites="true"
|
||||
openFileCacheTimeout="30"
|
||||
openFileFlushTimeout="60"
|
||||
fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Debug.log"
|
||||
layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
|
||||
</targets>
|
||||
<targets async="true">
|
||||
<target name="ServerInfo" xsi:type="File"
|
||||
encoding="UTF-8"
|
||||
createDirs="true"
|
||||
autoFlush="false"
|
||||
keepFileOpen="true"
|
||||
concurrentWrites="true"
|
||||
openFileCacheTimeout="30"
|
||||
openFileFlushTimeout="60"
|
||||
fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Info.log"
|
||||
layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
|
||||
</targets>
|
||||
<targets async="true">
|
||||
<target name="ServerWarn" xsi:type="File"
|
||||
encoding="UTF-8"
|
||||
createDirs="true"
|
||||
autoFlush="false"
|
||||
keepFileOpen="true"
|
||||
concurrentWrites="true"
|
||||
openFileCacheTimeout="30"
|
||||
openFileFlushTimeout="60"
|
||||
fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Warn.log"
|
||||
layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
|
||||
</targets>
|
||||
<targets async="true">
|
||||
<target name="ServerError" xsi:type="File"
|
||||
encoding="UTF-8"
|
||||
createDirs="true"
|
||||
autoFlush="false"
|
||||
keepFileOpen="true"
|
||||
concurrentWrites="true"
|
||||
openFileCacheTimeout="30"
|
||||
openFileFlushTimeout="60"
|
||||
fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Error.log"
|
||||
layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
|
||||
</targets>
|
||||
<targets async="true">
|
||||
<target name="ServerTrace" xsi:type="File"
|
||||
encoding="UTF-8"
|
||||
createDirs="true"
|
||||
autoFlush="false"
|
||||
keepFileOpen="true"
|
||||
concurrentWrites="true"
|
||||
openFileCacheTimeout="30"
|
||||
openFileFlushTimeout="60"
|
||||
fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Trace.log"
|
||||
layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
|
||||
</targets>
|
||||
<targets async="true">
|
||||
<target name="ConsoleColor" xsi:type="ColoredConsole"
|
||||
useDefaultRowHighlightingRules="false"
|
||||
layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}">
|
||||
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGreen" />
|
||||
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
|
||||
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
|
||||
<highlight-row condition="level == LogLevel.Error" foregroundColor="DarkRed" />
|
||||
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" />
|
||||
</target>
|
||||
</targets>
|
||||
<rules>
|
||||
<!-- 控制台 调试或编辑器启动的时候会调用-->
|
||||
<logger ruleName="ConsoleTrace" name="Server" level="Trace" writeTo="ConsoleColor" />
|
||||
<logger ruleName="ConsoleDebug" name="Server" level="Debug" writeTo="ConsoleColor" />
|
||||
<logger ruleName="ConsoleInfo" name="Server" level="Info" writeTo="ConsoleColor" />
|
||||
<logger ruleName="ConsoleWarn" name="Server" level="Warn" writeTo="ConsoleColor" />
|
||||
<logger ruleName="ConsoleError" name="Server" level="Error" writeTo="ConsoleColor" />
|
||||
<!-- 服务端日志输出文件 发布到服务器后会调用-->
|
||||
<logger ruleName="ServerDebug" name="Server" level="Debug" writeTo="ServerDebug" />
|
||||
<logger ruleName="ServerTrace" name="Server" level="Trace" writeTo="ServerTrace" />
|
||||
<logger ruleName="ServerInfo" name="Server" level="Info" writeTo="ServerInfo" />
|
||||
<logger ruleName="ServerWarn" name="Server" level="Warn" writeTo="ServerWarn" />
|
||||
<logger ruleName="ServerError" name="Server" level="Error" writeTo="ServerError" />
|
||||
</rules>
|
||||
</nlog>
|
||||
167
Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.cs
Normal file
167
Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using Fantasy.Platform.Net;
|
||||
using NLog;
|
||||
|
||||
namespace Fantasy
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用 NLog 实现的日志记录器。
|
||||
/// </summary>
|
||||
public class NLog : ILog
|
||||
{
|
||||
private readonly Logger _logger; // NLog 日志记录器实例
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 NLog 实例。
|
||||
/// </summary>
|
||||
/// <param name="name">日志记录器的名称。</param>
|
||||
public NLog(string name)
|
||||
{
|
||||
// 获取指定名称的 NLog 日志记录器
|
||||
_logger = LogManager.GetLogger(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化方法
|
||||
/// </summary>
|
||||
/// <param name="processMode"></param>
|
||||
public void Initialize(ProcessMode processMode)
|
||||
{
|
||||
// 非Benchmark模式、根据不同的运行模式来选择日志的方式
|
||||
switch (processMode)
|
||||
{
|
||||
case ProcessMode.Develop:
|
||||
{
|
||||
LogManager.Configuration.RemoveRuleByName("ServerDebug");
|
||||
LogManager.Configuration.RemoveRuleByName("ServerTrace");
|
||||
LogManager.Configuration.RemoveRuleByName("ServerInfo");
|
||||
LogManager.Configuration.RemoveRuleByName("ServerWarn");
|
||||
LogManager.Configuration.RemoveRuleByName("ServerError");
|
||||
break;
|
||||
}
|
||||
case ProcessMode.Release:
|
||||
{
|
||||
LogManager.Configuration.RemoveRuleByName("ConsoleTrace");
|
||||
LogManager.Configuration.RemoveRuleByName("ConsoleDebug");
|
||||
LogManager.Configuration.RemoveRuleByName("ConsoleInfo");
|
||||
LogManager.Configuration.RemoveRuleByName("ConsoleWarn");
|
||||
LogManager.Configuration.RemoveRuleByName("ConsoleError");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录跟踪级别的日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息。</param>
|
||||
public void Trace(string message)
|
||||
{
|
||||
_logger.Trace(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录警告级别的日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息。</param>
|
||||
public void Warning(string message)
|
||||
{
|
||||
_logger.Warn(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录信息级别的日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息。</param>
|
||||
public void Info(string message)
|
||||
{
|
||||
_logger.Info(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录调试级别的日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息。</param>
|
||||
public void Debug(string message)
|
||||
{
|
||||
_logger.Debug(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录错误级别的日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息。</param>
|
||||
public void Error(string message)
|
||||
{
|
||||
_logger.Error(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录严重错误级别的日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息。</param>
|
||||
public void Fatal(string message)
|
||||
{
|
||||
_logger.Fatal(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录跟踪级别的格式化日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息模板。</param>
|
||||
/// <param name="args">格式化参数。</param>
|
||||
public void Trace(string message, params object[] args)
|
||||
{
|
||||
_logger.Trace(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录警告级别的格式化日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息模板。</param>
|
||||
/// <param name="args">格式化参数。</param>
|
||||
public void Warning(string message, params object[] args)
|
||||
{
|
||||
_logger.Warn(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录信息级别的格式化日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息模板。</param>
|
||||
/// <param name="args">格式化参数。</param>
|
||||
public void Info(string message, params object[] args)
|
||||
{
|
||||
_logger.Info(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录调试级别的格式化日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息模板。</param>
|
||||
/// <param name="args">格式化参数。</param>
|
||||
public void Debug(string message, params object[] args)
|
||||
{
|
||||
_logger.Debug(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录错误级别的格式化日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息模板。</param>
|
||||
/// <param name="args">格式化参数。</param>
|
||||
public void Error(string message, params object[] args)
|
||||
{
|
||||
_logger.Error(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录严重错误级别的格式化日志消息。
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息模板。</param>
|
||||
/// <param name="args">格式化参数。</param>
|
||||
public void Fatal(string message, params object[] args)
|
||||
{
|
||||
_logger.Fatal(message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
3483
Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.xsd
Normal file
3483
Fantasy/Fantasy.Packages/Fantasy.NLog/NLog.xsd
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Fantasy/Fantasy.Packages/Fantasy.NLog/icon.png
Normal file
BIN
Fantasy/Fantasy.Packages/Fantasy.NLog/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 246 B |
Reference in New Issue
Block a user