mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
Compare commits
57 Commits
TEngine3.1
...
TEngine3.1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4c8c37ffd8 | ||
![]() |
5f694c2bed | ||
![]() |
7ff74bb747 | ||
![]() |
a5de63397a | ||
![]() |
13cc62f3f1 | ||
![]() |
95dfac5294 | ||
![]() |
14e95107c9 | ||
![]() |
caf5b2b54e | ||
![]() |
285483034e | ||
![]() |
1cdd8b63b4 | ||
![]() |
4c748df7ac | ||
![]() |
e1229b5a4b | ||
![]() |
b937fb1a37 | ||
![]() |
87ab99b363 | ||
![]() |
e3a47393f4 | ||
![]() |
75725314ad | ||
![]() |
d3ed2b21b9 | ||
![]() |
ec34dfbb16 | ||
![]() |
bd76e3a651 | ||
![]() |
278c8f23be | ||
![]() |
42568db2ab | ||
![]() |
b033c59b00 | ||
![]() |
04a43a3f11 | ||
![]() |
54214cdd0b | ||
![]() |
fa870b6228 | ||
![]() |
8a49d3437b | ||
![]() |
f19b889deb | ||
![]() |
d55f6e29d9 | ||
![]() |
8e4af31f26 | ||
![]() |
58a4b3e043 | ||
![]() |
576bf3bb48 | ||
![]() |
d282b81546 | ||
![]() |
d6dcd8851c | ||
![]() |
bbea9c4cee | ||
![]() |
b1ccb1fd53 | ||
![]() |
0f2ad3c71d | ||
![]() |
0e6851e691 | ||
![]() |
75b9956261 | ||
![]() |
401c397fc8 | ||
![]() |
94b314e91f | ||
![]() |
a6573d9336 | ||
![]() |
abf5357f49 | ||
![]() |
aab353cca3 | ||
![]() |
e13071c4db | ||
![]() |
e071c20214 | ||
![]() |
bf73ce333b | ||
![]() |
d7a60002d4 | ||
![]() |
61f657322d | ||
![]() |
33223dc02e | ||
![]() |
0661c59877 | ||
![]() |
7c74e10857 | ||
![]() |
db935bfb5f | ||
![]() |
dc6b7bb21e | ||
![]() |
d32f3cb768 | ||
![]() |
a32ab30444 | ||
![]() |
aa0d40c758 | ||
![]() |
5239b89326 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -129,4 +129,5 @@ DotNet/ThirdParty/obj/
|
||||
Bin/
|
||||
|
||||
#Server_Config
|
||||
DotNet/Config/GameConfig
|
||||
DotNet/Config/GameConfig
|
||||
DotNet/Config/ProtoBuf/OpCode.Cache
|
||||
|
@@ -1,5 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b9128b665b538746a11489aee369030
|
||||
guid: 6a824de3af698c34bb4343dbb911498b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef51ed54e72f97a4ab530b932680e08b
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@@ -70,6 +70,10 @@ public static class Define
|
||||
/// </summary>
|
||||
public static string ClientCustomExportDirectory;
|
||||
/// <summary>
|
||||
/// SceneConfig.xlsx的位置
|
||||
/// </summary>
|
||||
public static string SceneConfigPath;
|
||||
/// <summary>
|
||||
/// 自定义导出代码存放的程序集
|
||||
/// </summary>
|
||||
public static string CustomExportAssembly;
|
||||
|
@@ -1,12 +1,34 @@
|
||||
#if TENGINE_NET
|
||||
namespace TEngine.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 导出类型枚举,用于标识不同类型的导出操作。
|
||||
/// </summary>
|
||||
public enum ExportType
|
||||
{
|
||||
None = 0,
|
||||
ProtoBuf = 1, // 导出ProtoBuf
|
||||
AllExcelIncrement = 2, // 所有-增量导出Excel
|
||||
AllExcel = 3, // 所有-全量导出Excel
|
||||
Max, // 这个一定放最后
|
||||
/// <summary>
|
||||
/// 无导出类型。
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// 导出ProtoBuf类型。
|
||||
/// </summary>
|
||||
ProtoBuf = 1,
|
||||
/// <summary>
|
||||
/// 导出网络协议并重新生成OpCode。
|
||||
/// </summary>
|
||||
ProtoBufAndOpCodeCache = 2,
|
||||
/// <summary>
|
||||
/// 所有数据的增量导出Excel类型。
|
||||
/// </summary>
|
||||
AllExcelIncrement = 3,
|
||||
/// <summary>
|
||||
/// 所有数据的全量导出Excel类型。
|
||||
/// </summary>
|
||||
AllExcel = 4,
|
||||
/// <summary>
|
||||
/// 导出类型枚举的最大值,一定要放在最后。
|
||||
/// </summary>
|
||||
Max,
|
||||
}
|
||||
#endif
|
||||
|
@@ -3,16 +3,21 @@ using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using System.Text;
|
||||
using TEngine.Core;
|
||||
using TEngine.Helper;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
#pragma warning disable CS8601
|
||||
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace TEngine.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 数据导出器,用于执行导出操作。
|
||||
/// </summary>
|
||||
public sealed class Exporter
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始执行数据导出操作。
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
Console.OutputEncoding = Encoding.UTF8;
|
||||
@@ -25,8 +30,9 @@ public sealed class Exporter
|
||||
|
||||
LogInfo("请输入你想要做的操作:");
|
||||
LogInfo("1:导出网络协议(ProtoBuf)");
|
||||
LogInfo("2:增量导出服务器启动Excel(包含常量枚举)");
|
||||
LogInfo("3:全量导出服务器启动Excel(包含常量枚举)");
|
||||
LogInfo("2:导出网络协议并重新生成OpCode(ProtoBuf)");
|
||||
LogInfo("3:增量导出Excel(包含常量枚举)");
|
||||
LogInfo("4:全量导出Excel(包含常量枚举)");
|
||||
|
||||
var keyChar = Console.ReadKey().KeyChar;
|
||||
|
||||
@@ -39,13 +45,17 @@ public sealed class Exporter
|
||||
|
||||
LogInfo("");
|
||||
exportType = (ExportType) key;
|
||||
// LoadConfig();
|
||||
|
||||
|
||||
switch (exportType)
|
||||
{
|
||||
case ExportType.ProtoBuf:
|
||||
{
|
||||
_ = new ProtoBufExporter();
|
||||
_ = new ProtoBufExporter(false);
|
||||
break;
|
||||
}
|
||||
case ExportType.ProtoBufAndOpCodeCache:
|
||||
{
|
||||
_ = new ProtoBufExporter(true);
|
||||
break;
|
||||
}
|
||||
case ExportType.AllExcel:
|
||||
@@ -61,58 +71,19 @@ public sealed class Exporter
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
#if old
|
||||
// private void LoadConfig()
|
||||
// {
|
||||
// const string settingsName = "TEngineSettings.json";
|
||||
// var currentDirectory = Directory.GetCurrentDirectory();
|
||||
//
|
||||
// if (!File.Exists(Path.Combine(currentDirectory, settingsName)))
|
||||
// {
|
||||
// throw new FileNotFoundException($"not found {settingsName} in OutputDirectory");
|
||||
// }
|
||||
//
|
||||
// var configurationRoot = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
|
||||
// .AddJsonFile(settingsName)
|
||||
// .Build();
|
||||
// // ProtoBuf文件所在的位置文件夹位置
|
||||
// ProtoBufDefine.ProtoBufDirectory = configurationRoot["Export:ProtoBufDirectory:Value"];
|
||||
// // ProtoBuf生成到服务端的文件夹位置
|
||||
// ProtoBufDefine.ServerDirectory = configurationRoot["Export:ProtoBufServerDirectory:Value"];
|
||||
// // ProtoBuf生成到客户端的文件夹位置
|
||||
// ProtoBufDefine.ClientDirectory = configurationRoot["Export:ProtoBufClientDirectory:Value"];
|
||||
// // ProtoBuf生成代码模板的位置
|
||||
// ProtoBufDefine.ProtoBufTemplatePath = configurationRoot["Export:ProtoBufTemplatePath:Value"];
|
||||
// // Excel配置文件根目录
|
||||
// ExcelDefine.ProgramPath = configurationRoot["Export:ExcelProgramPath:Value"];
|
||||
// // Excel版本文件的位置
|
||||
// ExcelDefine.ExcelVersionFile = configurationRoot["Export:ExcelVersionFile:Value"];
|
||||
// // Excel生成服务器代码的文件夹位置
|
||||
// ExcelDefine.ServerFileDirectory = configurationRoot["Export:ExcelServerFileDirectory:Value"];
|
||||
// // Excel生成客户端代码文件夹位置
|
||||
// ExcelDefine.ClientFileDirectory = configurationRoot["Export:ExcelClientFileDirectory:Value"];
|
||||
// // Excel生成服务器二进制数据文件夹位置
|
||||
// ExcelDefine.ServerBinaryDirectory = configurationRoot["Export:ExcelServerBinaryDirectory:Value"];
|
||||
// // Excel生成客户端二进制数据文件夹位置
|
||||
// ExcelDefine.ClientBinaryDirectory = configurationRoot["Export:ExcelClientBinaryDirectory:Value"];
|
||||
// // Excel生成服务器Json数据文件夹位置
|
||||
// ExcelDefine.ServerJsonDirectory = configurationRoot["Export:ExcelServerJsonDirectory:Value"];
|
||||
// // Excel生成客户端Json数据文件夹位置
|
||||
// ExcelDefine.ClientJsonDirectory = configurationRoot["Export:ExcelClientJsonDirectory:Value"];
|
||||
// // Excel生成代码模板的位置
|
||||
// ExcelDefine.ExcelTemplatePath = configurationRoot["Export:ExcelTemplatePath:Value"];
|
||||
// // 服务器自定义导出代码文件夹位置
|
||||
// ExcelDefine.ServerCustomExportDirectory = configurationRoot["Export:ServerCustomExportDirectory:Value"];
|
||||
// // 客户端自定义导出代码文件夹位置
|
||||
// ExcelDefine.ClientCustomExportDirectory = configurationRoot["Export:ClientCustomExportDirectory:Value"];
|
||||
// }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// 输出信息到控制台。
|
||||
/// </summary>
|
||||
/// <param name="msg">要输出的信息。</param>
|
||||
public static void LogInfo(string msg)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输出错误信息到控制台。
|
||||
/// </summary>
|
||||
/// <param name="msg">要输出的错误信息。</param>
|
||||
public static void LogError(string msg)
|
||||
{
|
||||
ConsoleColor color = Console.ForegroundColor;
|
||||
@@ -121,6 +92,10 @@ public sealed class Exporter
|
||||
Console.ForegroundColor = color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输出异常信息到控制台。
|
||||
/// </summary>
|
||||
/// <param name="e">要输出的异常。</param>
|
||||
public static void LogError(Exception e)
|
||||
{
|
||||
ConsoleColor color = Console.ForegroundColor;
|
||||
|
@@ -0,0 +1,60 @@
|
||||
#if TENGINE_NET
|
||||
using TEngine.Helper;
|
||||
|
||||
namespace TEngine.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 网络协议操作码缓存。
|
||||
/// </summary>
|
||||
public class OpCodeCache
|
||||
{
|
||||
private readonly List<uint> _opCodes = new List<uint>();
|
||||
private readonly SortedDictionary<string, uint> _opcodeCache;
|
||||
private readonly SortedDictionary<string, uint> _saveOpCodeCache = new();
|
||||
private readonly string _opcodeCachePath = $"{Define.ProtoBufDirectory}OpCode.Cache";
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,用于初始化网络协议操作码缓存。
|
||||
/// </summary>
|
||||
public OpCodeCache(bool regenerate)
|
||||
{
|
||||
if (File.Exists(_opcodeCachePath) && !regenerate)
|
||||
{
|
||||
var readAllText = File.ReadAllText(_opcodeCachePath);
|
||||
_opcodeCache = readAllText.Deserialize<SortedDictionary<string, uint>>();
|
||||
_opCodes.AddRange(_opcodeCache.Values);
|
||||
}
|
||||
else
|
||||
{
|
||||
_opcodeCache = new SortedDictionary<string, uint>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存网络协议操作码。
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
File.WriteAllText(_opcodeCachePath, _saveOpCodeCache.ToJson());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据className获得OpCode、如果是新增的会产生一个新的OpCode。
|
||||
/// </summary>
|
||||
/// <param name="className">协议名。</param>
|
||||
/// <param name="opcode">操作码。</param>
|
||||
/// <returns></returns>
|
||||
public uint GetOpcodeCache(string className, ref uint opcode)
|
||||
{
|
||||
if (!_opcodeCache.TryGetValue(className, out var opCode))
|
||||
{
|
||||
while (_opCodes.Contains(++opcode)) { }
|
||||
opCode = opcode;
|
||||
_opCodes.Add(opCode);
|
||||
}
|
||||
|
||||
_saveOpCodeCache.Add(className, opCode);
|
||||
return opCode;
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0f0d02da06c4ca981417bfe43162809
|
||||
timeCreated: 1693928511
|
@@ -1,27 +1,52 @@
|
||||
#if TENGINE_NET
|
||||
using System.Text;
|
||||
using TEngine.Core.Network;
|
||||
#pragma warning disable CS8604
|
||||
#pragma warning disable CS8602
|
||||
#pragma warning disable CS8600
|
||||
#pragma warning disable CS8618
|
||||
using TEngine.Helper;
|
||||
|
||||
namespace TEngine.Core;
|
||||
|
||||
/// <summary>
|
||||
/// ProtoBuf操作码类型枚举
|
||||
/// </summary>
|
||||
public enum ProtoBufOpCodeType
|
||||
{
|
||||
/// <summary>
|
||||
/// 无
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// 外部操作码类型
|
||||
/// </summary>
|
||||
Outer = 1,
|
||||
/// <summary>
|
||||
/// 内部操作码类型
|
||||
/// </summary>
|
||||
Inner = 2,
|
||||
/// <summary>
|
||||
/// 使用BSON的内部操作码类型
|
||||
/// </summary>
|
||||
InnerBson = 3,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 操作码信息类
|
||||
/// </summary>
|
||||
public sealed class OpcodeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 操作码
|
||||
/// </summary>
|
||||
public uint Code;
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ProtoBuf导出器类
|
||||
/// </summary>
|
||||
public sealed class ProtoBufExporter
|
||||
{
|
||||
private uint _aMessage;
|
||||
@@ -32,10 +57,13 @@ public sealed class ProtoBufExporter
|
||||
private uint _aRouteResponse;
|
||||
private string _serverTemplate;
|
||||
private string _clientTemplate;
|
||||
|
||||
private readonly OpCodeCache _opCodeCache;
|
||||
private readonly List<OpcodeInfo> _opcodes = new();
|
||||
|
||||
public ProtoBufExporter()
|
||||
/// <summary>
|
||||
/// 构造函数,用于初始化导出器
|
||||
/// </summary>
|
||||
public ProtoBufExporter(bool regenerateOpCodeCache)
|
||||
{
|
||||
Console.OutputEncoding = Encoding.UTF8;
|
||||
|
||||
@@ -48,6 +76,23 @@ public sealed class ProtoBufExporter
|
||||
{
|
||||
Directory.CreateDirectory(Define.ProtoBufClientDirectory);
|
||||
}
|
||||
|
||||
if (!Directory.Exists($"{Define.ProtoBufDirectory}Outer"))
|
||||
{
|
||||
Directory.CreateDirectory($"{Define.ProtoBufDirectory}Outer");
|
||||
}
|
||||
|
||||
if (!Directory.Exists($"{Define.ProtoBufDirectory}Inner"))
|
||||
{
|
||||
Directory.CreateDirectory($"{Define.ProtoBufDirectory}Inner");
|
||||
}
|
||||
|
||||
if (!Directory.Exists($"{Define.ProtoBufDirectory}InnerBosn"))
|
||||
{
|
||||
Directory.CreateDirectory($"{Define.ProtoBufDirectory}InnerBosn");
|
||||
}
|
||||
|
||||
_opCodeCache = new OpCodeCache(regenerateOpCodeCache);
|
||||
|
||||
var tasks = new Task[2];
|
||||
tasks[0] = Task.Run(RouteType);
|
||||
@@ -59,21 +104,17 @@ public sealed class ProtoBufExporter
|
||||
await Start(ProtoBufOpCodeType.InnerBson);
|
||||
});
|
||||
Task.WaitAll(tasks);
|
||||
_opCodeCache.Save();
|
||||
}
|
||||
|
||||
private async Task Start(ProtoBufOpCodeType opCodeType)
|
||||
{
|
||||
var protoFile = "";
|
||||
List<string> files = new List<string>();
|
||||
var opCodeName = "";
|
||||
var parameter = "";
|
||||
var className = "";
|
||||
var isMsgHead = false;
|
||||
OpcodeInfo opcodeInfo = null;
|
||||
string responseTypeStr = null;
|
||||
string customRouteType = null;
|
||||
_opcodes.Clear();
|
||||
var file = new StringBuilder();
|
||||
var saveDirectory = new Dictionary<string,string>();
|
||||
var saveDirectory = new Dictionary<string, string>();
|
||||
|
||||
switch (opCodeType)
|
||||
{
|
||||
@@ -86,9 +127,11 @@ public sealed class ProtoBufExporter
|
||||
_aRouteRequest = Opcode.OuterRouteRequest;
|
||||
_aRouteResponse = Opcode.OuterRouteResponse;
|
||||
opCodeName = "OuterOpcode";
|
||||
protoFile = $"{Define.ProtoBufDirectory}OuterMessage.proto";
|
||||
saveDirectory.Add(Define.ProtoBufServerDirectory, _serverTemplate);
|
||||
saveDirectory.Add(Define.ProtoBufClientDirectory, _clientTemplate);
|
||||
var protoBufFiles = FileHelper.GetDirectoryFile(
|
||||
$"{Define.ProtoBufDirectory}Outer", "*.proto", SearchOption.AllDirectories);
|
||||
files.AddRange(protoBufFiles);
|
||||
break;
|
||||
}
|
||||
case ProtoBufOpCodeType.Inner:
|
||||
@@ -101,8 +144,9 @@ public sealed class ProtoBufExporter
|
||||
_aRouteRequest = Opcode.InnerRouteRequest + 1000;
|
||||
_aRouteResponse = Opcode.InnerRouteResponse + 1000;
|
||||
opCodeName = "InnerOpcode";
|
||||
protoFile = $"{Define.ProtoBufDirectory}InnerMessage.proto";
|
||||
saveDirectory.Add(Define.ProtoBufServerDirectory, _serverTemplate);
|
||||
var protoBufFiles = FileHelper.GetDirectoryFile($"{Define.ProtoBufDirectory}Inner", "*.proto", SearchOption.AllDirectories);
|
||||
files.AddRange(protoBufFiles);
|
||||
break;
|
||||
}
|
||||
case ProtoBufOpCodeType.InnerBson:
|
||||
@@ -115,204 +159,230 @@ public sealed class ProtoBufExporter
|
||||
_aRouteRequest = Opcode.InnerBsonRouteRequest + 1000;
|
||||
_aRouteResponse = Opcode.InnerBsonRouteResponse + 1000;
|
||||
opCodeName = "InnerBsonOpcode";
|
||||
protoFile = $"{Define.ProtoBufDirectory}InnerBsonMessage.proto";
|
||||
saveDirectory.Add(Define.ProtoBufServerDirectory, _serverTemplate);
|
||||
var protoBufFiles = FileHelper.GetDirectoryFile($"{Define.ProtoBufDirectory}InnerBosn", "*.proto", SearchOption.AllDirectories);
|
||||
files.AddRange(protoBufFiles);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var protoFileText = await File.ReadAllTextAsync(protoFile);
|
||||
|
||||
foreach (var line in protoFileText.Split('\n'))
|
||||
#region GenerateProtoFiles
|
||||
foreach (var filePath in files)
|
||||
{
|
||||
var currentLine = line.Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(currentLine))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var parameter = "";
|
||||
var className = "";
|
||||
var isMsgHead = false;
|
||||
string responseTypeStr = null;
|
||||
string customRouteType = null;
|
||||
|
||||
if (currentLine.StartsWith("///"))
|
||||
var protoFileText = await File.ReadAllTextAsync(filePath);
|
||||
|
||||
foreach (var line in protoFileText.Split('\n'))
|
||||
{
|
||||
file.AppendFormat(" /// <summary>\r\n" + " /// {0}\r\n" + " /// </summary>\r\n", currentLine.TrimStart(new[] {'/', '/', '/'}));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentLine.StartsWith("message"))
|
||||
{
|
||||
isMsgHead = true;
|
||||
opcodeInfo = new OpcodeInfo();
|
||||
file.AppendLine("\t[ProtoContract]");
|
||||
className = currentLine.Split(Define.SplitChars, StringSplitOptions.RemoveEmptyEntries)[1];
|
||||
var splits = currentLine.Split(new[] {"//"}, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (splits.Length > 1)
|
||||
{
|
||||
var parameterArray = currentLine.Split(new[] {"//"}, StringSplitOptions.RemoveEmptyEntries)[1].Trim().Split(',');
|
||||
parameter = parameterArray[0].Trim();
|
||||
|
||||
switch (parameterArray.Length)
|
||||
{
|
||||
case 2:
|
||||
responseTypeStr = parameterArray[1].Trim();
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
customRouteType = parameterArray[1].Trim();
|
||||
|
||||
if (parameterArray.Length == 3)
|
||||
{
|
||||
responseTypeStr = parameterArray[2].Trim();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parameter = "";
|
||||
}
|
||||
bool hadOpCode = true;
|
||||
|
||||
file.Append(string.IsNullOrWhiteSpace(parameter)
|
||||
? $"\tpublic partial class {className} : AProto"
|
||||
: $"\tpublic partial class {className} : AProto, {parameter}");
|
||||
opcodeInfo.Name = className;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isMsgHead)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var currentLine = line.Trim();
|
||||
|
||||
switch (currentLine)
|
||||
{
|
||||
case "{":
|
||||
if (string.IsNullOrWhiteSpace(currentLine))
|
||||
{
|
||||
file.AppendLine("\n\t{");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(parameter) || parameter == "IMessage")
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentLine.StartsWith("///"))
|
||||
{
|
||||
file.AppendFormat(" /// <summary>\r\n" + " /// {0}\r\n" + " /// </summary>\r\n", currentLine.TrimStart(new[] { '/', '/', '/' }));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentLine.StartsWith("message"))
|
||||
{
|
||||
isMsgHead = true;
|
||||
opcodeInfo = new OpcodeInfo();
|
||||
file.AppendLine("\t[ProtoContract]");
|
||||
className = currentLine.Split(Define.SplitChars, StringSplitOptions.RemoveEmptyEntries)[1];
|
||||
var splits = currentLine.Split(new[] { "//" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (splits.Length > 1)
|
||||
{
|
||||
opcodeInfo.Code += ++_aMessage;
|
||||
file.AppendLine($"\t\tpublic uint OpCode() {{ return {opCodeName}.{className}; }}");
|
||||
var parameterArray = currentLine.Split(new[] { "//" }, StringSplitOptions.RemoveEmptyEntries)[1].Trim().Split(',');
|
||||
parameter = parameterArray[0].Trim();
|
||||
|
||||
switch (parameterArray.Length)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
if (parameter == "ICustomRouteMessage")
|
||||
{
|
||||
customRouteType = parameterArray[1].Trim();
|
||||
break;
|
||||
}
|
||||
|
||||
responseTypeStr = parameterArray[1].Trim();
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
responseTypeStr = parameterArray[1].Trim();
|
||||
customRouteType = parameterArray[2].Trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (responseTypeStr != null)
|
||||
parameter = "";
|
||||
}
|
||||
|
||||
file.Append(string.IsNullOrWhiteSpace(parameter)
|
||||
? $"\tpublic partial class {className} : AProto"
|
||||
: $"\tpublic partial class {className} : AProto, {parameter}");
|
||||
opcodeInfo.Name = className;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isMsgHead)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (currentLine)
|
||||
{
|
||||
case "{":
|
||||
{
|
||||
file.AppendLine("\n\t{");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(parameter))
|
||||
{
|
||||
file.AppendLine("\t\t[ProtoIgnore]");
|
||||
file.AppendLine($"\t\tpublic {responseTypeStr} ResponseType {{ get; set; }}");
|
||||
responseTypeStr = null;
|
||||
hadOpCode = false;
|
||||
}
|
||||
else if(parameter == "IMessage")
|
||||
{
|
||||
opcodeInfo.Code = _opCodeCache.GetOpcodeCache(className, ref _aMessage);
|
||||
file.AppendLine($"\t\tpublic uint OpCode() {{ return {opCodeName}.{className}; }}");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parameter.Contains("RouteRequest"))
|
||||
if (responseTypeStr != null)
|
||||
{
|
||||
Exporter.LogError($"{opcodeInfo.Name} 没指定ResponseType");
|
||||
file.AppendLine("\t\t[ProtoIgnore]");
|
||||
file.AppendLine($"\t\tpublic {responseTypeStr} ResponseType {{ get; set; }}");
|
||||
responseTypeStr = null;
|
||||
}
|
||||
}
|
||||
|
||||
file.AppendLine($"\t\tpublic uint OpCode() {{ return {opCodeName}.{className}; }}");
|
||||
|
||||
if (customRouteType != null)
|
||||
{
|
||||
file.AppendLine($"\t\tpublic long RouteTypeOpCode() {{ return (long)RouteType.{customRouteType}; }}");
|
||||
customRouteType = null;
|
||||
}
|
||||
else if (parameter is "IAddressableRouteRequest" or "IAddressableRouteMessage")
|
||||
{
|
||||
file.AppendLine($"\t\tpublic long RouteTypeOpCode() {{ return CoreRouteType.Addressable; }}");
|
||||
}
|
||||
else if (parameter.EndsWith("BsonRouteMessage") || parameter.EndsWith("BsonRouteRequest"))
|
||||
{
|
||||
file.AppendLine($"\t\tpublic long RouteTypeOpCode() {{ return CoreRouteType.BsonRoute; }}");
|
||||
}
|
||||
else if (parameter is "IRouteMessage" or "IRouteRequest")
|
||||
{
|
||||
file.AppendLine($"\t\tpublic long RouteTypeOpCode() {{ return CoreRouteType.Route; }}");
|
||||
}
|
||||
|
||||
switch (parameter)
|
||||
{
|
||||
case "IRequest":
|
||||
case "IBsonRequest":
|
||||
else
|
||||
{
|
||||
opcodeInfo.Code += ++_aRequest;
|
||||
break;
|
||||
}
|
||||
case "IResponse":
|
||||
case "IBsonResponse":
|
||||
{
|
||||
opcodeInfo.Code += ++_aResponse;
|
||||
file.AppendLine("\t\t[ProtoMember(91, IsRequired = true)]");
|
||||
file.AppendLine("\t\tpublic uint ErrorCode { get; set; }");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (parameter.EndsWith("RouteMessage") || parameter == "IRouteMessage")
|
||||
if (parameter.Contains("RouteRequest"))
|
||||
{
|
||||
opcodeInfo.Code += ++_aRouteMessage;
|
||||
Exporter.LogError($"{opcodeInfo.Name} 没指定ResponseType");
|
||||
}
|
||||
else if (parameter.EndsWith("RouteRequest") || parameter == "IRouteRequest")
|
||||
}
|
||||
|
||||
file.AppendLine($"\t\tpublic uint OpCode() {{ return {opCodeName}.{className}; }}");
|
||||
|
||||
if (customRouteType != null)
|
||||
{
|
||||
file.AppendLine($"\t\tpublic long RouteTypeOpCode() {{ return (long)RouteType.{customRouteType}; }}");
|
||||
customRouteType = null;
|
||||
}
|
||||
else if (parameter is "IAddressableRouteRequest" or "IAddressableRouteMessage")
|
||||
{
|
||||
file.AppendLine($"\t\tpublic long RouteTypeOpCode() {{ return CoreRouteType.Addressable; }}");
|
||||
}
|
||||
else if (parameter.EndsWith("BsonRouteMessage") || parameter.EndsWith("BsonRouteRequest"))
|
||||
{
|
||||
file.AppendLine($"\t\tpublic long RouteTypeOpCode() {{ return CoreRouteType.BsonRoute; }}");
|
||||
}
|
||||
else if (parameter is "IRouteMessage" or "IRouteRequest")
|
||||
{
|
||||
file.AppendLine($"\t\tpublic long RouteTypeOpCode() {{ return CoreRouteType.Route; }}");
|
||||
}
|
||||
|
||||
switch (parameter)
|
||||
{
|
||||
case "IRequest":
|
||||
case "IBsonRequest":
|
||||
{
|
||||
opcodeInfo.Code += ++_aRouteRequest;
|
||||
opcodeInfo.Code = _opCodeCache.GetOpcodeCache(className, ref _aRequest);
|
||||
break;
|
||||
}
|
||||
else if (parameter.EndsWith("RouteResponse") || parameter == "IRouteResponse")
|
||||
case "IResponse":
|
||||
case "IBsonResponse":
|
||||
{
|
||||
opcodeInfo.Code += ++_aRouteResponse;
|
||||
opcodeInfo.Code = _opCodeCache.GetOpcodeCache(className, ref _aResponse);
|
||||
file.AppendLine("\t\t[ProtoMember(91, IsRequired = true)]");
|
||||
file.AppendLine("\t\tpublic uint ErrorCode { get; set; }");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (parameter.EndsWith("RouteMessage") || parameter == "IRouteMessage")
|
||||
{
|
||||
opcodeInfo.Code = _opCodeCache.GetOpcodeCache(className, ref _aRouteMessage);
|
||||
}
|
||||
else if (parameter.EndsWith("RouteRequest") || parameter == "IRouteRequest")
|
||||
{
|
||||
opcodeInfo.Code = _opCodeCache.GetOpcodeCache(className, ref _aRouteRequest);
|
||||
}
|
||||
else if (parameter.EndsWith("RouteResponse") || parameter == "IRouteResponse")
|
||||
{
|
||||
opcodeInfo.Code = _opCodeCache.GetOpcodeCache(className, ref _aRouteResponse);
|
||||
file.AppendLine("\t\t[ProtoMember(91, IsRequired = true)]");
|
||||
file.AppendLine("\t\tpublic uint ErrorCode { get; set; }");
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_opcodes.Add(opcodeInfo);
|
||||
continue;
|
||||
}
|
||||
case "}":
|
||||
{
|
||||
isMsgHead = false;
|
||||
file.AppendLine("\t}");
|
||||
continue;
|
||||
}
|
||||
case "":
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentLine.StartsWith("//"))
|
||||
{
|
||||
file.AppendFormat("\t\t///<summary>\r\n" + "\t\t/// {0}\r\n" + "\t\t///</summary>\r\n", currentLine.TrimStart('/', '/'));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentLine.StartsWith("repeated"))
|
||||
{
|
||||
Repeated(file, currentLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
Members(file, currentLine);
|
||||
}
|
||||
}
|
||||
|
||||
var csName = $"{Path.GetFileNameWithoutExtension(protoFile)}.cs";
|
||||
|
||||
foreach (var (directory, template) in saveDirectory)
|
||||
{
|
||||
var csFile = Path.Combine(directory, csName);
|
||||
var content = template.Replace("(Content)", file.ToString());
|
||||
await File.WriteAllTextAsync(csFile, content);
|
||||
}
|
||||
|
||||
file.Clear();
|
||||
if (hadOpCode)
|
||||
{
|
||||
_opcodes.Add(opcodeInfo);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case "}":
|
||||
{
|
||||
isMsgHead = false;
|
||||
file.AppendLine("\t}");
|
||||
continue;
|
||||
}
|
||||
case "":
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentLine.StartsWith("//"))
|
||||
{
|
||||
file.AppendFormat("\t\t///<summary>\r\n" + "\t\t/// {0}\r\n" + "\t\t///</summary>\r\n", currentLine.TrimStart('/', '/'));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentLine.StartsWith("repeated"))
|
||||
{
|
||||
Repeated(file, currentLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
Members(file, currentLine);
|
||||
}
|
||||
}
|
||||
|
||||
var csName = $"{Path.GetFileNameWithoutExtension(filePath)}.cs";
|
||||
|
||||
foreach (var (directory, template) in saveDirectory)
|
||||
{
|
||||
var csFile = Path.Combine(directory, csName);
|
||||
var content = template.Replace("(Content)", file.ToString());
|
||||
await File.WriteAllTextAsync(csFile, content);
|
||||
}
|
||||
|
||||
file.Clear();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GenerateOpCode
|
||||
file.Clear();
|
||||
file.AppendLine("namespace TEngine");
|
||||
file.AppendLine("{");
|
||||
file.AppendLine($"\tpublic static partial class {opCodeName}");
|
||||
@@ -333,6 +403,7 @@ public sealed class ProtoBufExporter
|
||||
var csFile = Path.Combine(directory, $"{opCodeName}.cs");
|
||||
await File.WriteAllTextAsync(csFile, file.ToString());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
private async Task RouteType()
|
||||
@@ -450,7 +521,10 @@ public sealed class ProtoBufExporter
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加载模板
|
||||
/// </summary>
|
||||
private void LoadTemplate()
|
||||
{
|
||||
string[] lines = File.ReadAllLines(Define.ProtoBufTemplatePath, Encoding.UTF8);
|
||||
|
@@ -1,26 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace TEngine.Core
|
||||
namespace TEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件操作助手类,提供了各种文件操作方法。
|
||||
/// </summary>
|
||||
public static class FileHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取文件全路径。
|
||||
/// 获取相对路径的完整路径。
|
||||
/// </summary>
|
||||
/// <param name="relativePath"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="relativePath">相对路径。</param>
|
||||
/// <returns>完整路径。</returns>
|
||||
public static string GetFullPath(string relativePath)
|
||||
{
|
||||
return Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), relativePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝文件到目标路径、如果目标目录不存在会自动创建目录
|
||||
/// 将文件复制到目标路径,如果目标目录不存在会自动创建目录。
|
||||
/// </summary>
|
||||
/// <param name="sourceFile"></param>
|
||||
/// <param name="destinationFile"></param>
|
||||
/// <param name="overwrite"></param>
|
||||
/// <param name="sourceFile">源文件路径。</param>
|
||||
/// <param name="destinationFile">目标文件路径。</param>
|
||||
/// <param name="overwrite">是否覆盖已存在的目标文件。</param>
|
||||
public static void Copy(string sourceFile, string destinationFile, bool overwrite)
|
||||
{
|
||||
var directoriesByFilePath = GetDirectoriesByFilePath(destinationFile);
|
||||
@@ -39,10 +42,10 @@ namespace TEngine.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件路径内的所有文件夹路径
|
||||
/// 获取文件路径内的所有文件夹路径。
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="filePath">文件路径。</param>
|
||||
/// <returns>文件夹路径列表。</returns>
|
||||
public static List<string> GetDirectoriesByFilePath(string filePath)
|
||||
{
|
||||
var dir = "";
|
||||
@@ -59,11 +62,11 @@ namespace TEngine.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 把文件夹里所有内容拷贝的目标位置
|
||||
/// 将文件夹内的所有内容复制到目标位置。
|
||||
/// </summary>
|
||||
/// <param name="sourceDirectory"></param>
|
||||
/// <param name="destinationDirectory"></param>
|
||||
/// <param name="overwrite"></param>
|
||||
/// <param name="sourceDirectory">源文件夹路径。</param>
|
||||
/// <param name="destinationDirectory">目标文件夹路径。</param>
|
||||
/// <param name="overwrite">是否覆盖已存在的文件。</param>
|
||||
public static void CopyDirectory(string sourceDirectory, string destinationDirectory, bool overwrite)
|
||||
{
|
||||
// 创建目标文件夹
|
||||
@@ -99,11 +102,23 @@ namespace TEngine.Core
|
||||
CopyDirectory(directory, destinationPath, overwrite);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 清除文件夹里的所有文件
|
||||
/// 获取目录下的所有文件
|
||||
/// </summary>
|
||||
/// <param name="folderPath"></param>
|
||||
/// <param name="folderPath">文件夹路径。</param>
|
||||
/// <param name="searchPattern">需要查找的文件通配符</param>
|
||||
/// <param name="searchOption">查找的类型</param>
|
||||
/// <returns></returns>
|
||||
public static string[] GetDirectoryFile(string folderPath, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
return Directory.GetFiles(folderPath, searchPattern, searchOption);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空文件夹内的所有文件。
|
||||
/// </summary>
|
||||
/// <param name="folderPath">文件夹路径。</param>
|
||||
public static void ClearDirectoryFile(string folderPath)
|
||||
{
|
||||
if (!Directory.Exists(folderPath))
|
||||
|
191
Assets/GameScripts/DotNet/Core/Helper/StringHelper.cs
Normal file
191
Assets/GameScripts/DotNet/Core/Helper/StringHelper.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
public static class StringHelper
|
||||
{
|
||||
public static IEnumerable<byte> ToBytes(this string str)
|
||||
{
|
||||
byte[] byteArray = Encoding.Default.GetBytes(str);
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(this string str)
|
||||
{
|
||||
byte[] byteArray = Encoding.Default.GetBytes(str);
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
public static byte[] ToUtf8(this string str)
|
||||
{
|
||||
byte[] byteArray = Encoding.UTF8.GetBytes(str);
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
public static byte[] HexToBytes(this string hexString)
|
||||
{
|
||||
if (hexString.Length % 2 != 0)
|
||||
{
|
||||
throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}",
|
||||
hexString));
|
||||
}
|
||||
|
||||
var hexAsBytes = new byte[hexString.Length / 2];
|
||||
for (int index = 0; index < hexAsBytes.Length; index++)
|
||||
{
|
||||
string byteValue = "";
|
||||
byteValue += hexString[index * 2];
|
||||
byteValue += hexString[index * 2 + 1];
|
||||
hexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
return hexAsBytes;
|
||||
}
|
||||
|
||||
public static string Fmt(this string text, params object[] args)
|
||||
{
|
||||
return string.Format(text, args);
|
||||
}
|
||||
|
||||
public static string ListToString<T>(this List<T> list)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (T t in list)
|
||||
{
|
||||
sb.Append(t);
|
||||
sb.Append(",");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string ArrayToString<T>(this T[] args)
|
||||
{
|
||||
if (args == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
string argStr = " [";
|
||||
for (int arrIndex = 0; arrIndex < args.Length; arrIndex++)
|
||||
{
|
||||
argStr += args[arrIndex];
|
||||
if (arrIndex != args.Length - 1)
|
||||
{
|
||||
argStr += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
argStr += "]";
|
||||
return argStr;
|
||||
}
|
||||
|
||||
public static string ArrayToString<T>(this T[] args, int index, int count)
|
||||
{
|
||||
if (args == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
string argStr = " [";
|
||||
for (int arrIndex = index; arrIndex < count + index; arrIndex++)
|
||||
{
|
||||
argStr += args[arrIndex];
|
||||
if (arrIndex != args.Length - 1)
|
||||
{
|
||||
argStr += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
argStr += "]";
|
||||
return argStr;
|
||||
}
|
||||
|
||||
public static string PrintProto(this AProto proto, int stackIndex = 0, string propertyInfoName = "", bool isList = false, int listIndex = 0)
|
||||
{
|
||||
if (proto == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder _stringBuilder = new StringBuilder();
|
||||
_stringBuilder.Clear();
|
||||
|
||||
Type type = proto.GetType();
|
||||
_stringBuilder.Append($"\n");
|
||||
for (int i = 0; i < stackIndex; i++)
|
||||
{
|
||||
_stringBuilder.Append("\t");
|
||||
}
|
||||
|
||||
propertyInfoName = isList ? $"[{propertyInfoName}][{listIndex}]" : $"[{propertyInfoName}]";
|
||||
_stringBuilder.Append(stackIndex == 0? $"[{type.Name}]" : propertyInfoName);
|
||||
|
||||
var bindingFlags = BindingFlags.Public | BindingFlags.Instance;
|
||||
var propertyInfos = type.GetProperties(bindingFlags);
|
||||
for (var i = 0; i < propertyInfos.Length; ++i)
|
||||
{
|
||||
var propertyInfo = propertyInfos[i];
|
||||
|
||||
if (propertyInfo.PropertyType.BaseType == typeof (AProto))
|
||||
{
|
||||
_stringBuilder.Append(PrintProto((AProto)propertyInfo.GetValue(proto), stackIndex + 1, propertyInfo.Name));
|
||||
}
|
||||
else if (propertyInfo.PropertyType.IsList() && propertyInfo.PropertyType.IsGenericType)
|
||||
{
|
||||
object value = propertyInfo.GetValue(proto, null);
|
||||
if (value != null)
|
||||
{
|
||||
Type objType = value.GetType();
|
||||
int count = Convert.ToInt32(objType.GetProperty("Count").GetValue(value, null));
|
||||
for (int j = 0; j < count; j++)
|
||||
{
|
||||
object item = objType.GetProperty("Item").GetValue(value, new object[] { j });
|
||||
_stringBuilder.Append(PrintProto((AProto)item, stackIndex + 1, propertyInfo.Name, isList: true, listIndex: j));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_stringBuilder.Append($"\n");
|
||||
for (int j = 0; j < stackIndex + 1; j++)
|
||||
{
|
||||
_stringBuilder.Append("\t");
|
||||
}
|
||||
|
||||
_stringBuilder.Append($"[{propertyInfo.Name}]");
|
||||
_stringBuilder.Append(": ");
|
||||
_stringBuilder.Append(propertyInfo.GetValue(proto));
|
||||
}
|
||||
}
|
||||
|
||||
return _stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断类型是否为可操作的列表类型
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsList(this Type type)
|
||||
{
|
||||
if (typeof (System.Collections.IList).IsAssignableFrom(type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var it in type.GetInterfaces())
|
||||
{
|
||||
if (it.IsGenericType && typeof (IList<>) == it.GetGenericTypeDefinition())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b7dfd2b954f77047a61bf4c505f8cc1
|
||||
guid: c253fa0108e29234f9198e6b720bdbf7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -4,6 +4,7 @@ namespace TEngine.Core.Network
|
||||
{
|
||||
None = 0,
|
||||
KCP = 1,
|
||||
TCP = 2
|
||||
TCP = 2,
|
||||
WebSocket = 3,
|
||||
}
|
||||
}
|
@@ -2,7 +2,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
#if !UNITY_WEBGL
|
||||
using System.Net.Sockets;
|
||||
#endif
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
@@ -49,6 +51,7 @@ namespace TEngine.Core
|
||||
return $"{self.Address}:{self.Port}";
|
||||
}
|
||||
|
||||
#if !UNITY_WEBGL
|
||||
public static void SetSioUdpConnReset(Socket socket)
|
||||
{
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
@@ -70,5 +73,6 @@ namespace TEngine.Core
|
||||
|
||||
socket.IOControl(SIO_UDP_CONNRESET, new[] {Convert.ToByte(false)}, null);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -1,3 +1,4 @@
|
||||
#if !UNITY_WEBGL
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace TEngine.Core.Network
|
||||
@@ -48,4 +49,5 @@ namespace TEngine.Core.Network
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -13,7 +13,8 @@ namespace TEngine.Core.Network
|
||||
public void Initialize(NetworkProtocolType networkProtocolType, NetworkTarget networkTarget)
|
||||
{
|
||||
switch (networkProtocolType)
|
||||
{
|
||||
{
|
||||
#if !UNITY_WEBGL
|
||||
case NetworkProtocolType.KCP:
|
||||
{
|
||||
Network = new KCPClientNetwork(Scene, networkTarget);
|
||||
@@ -24,6 +25,7 @@ namespace TEngine.Core.Network
|
||||
Network = new TCPClientNetwork(Scene, networkTarget);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
throw new NotSupportedException($"Unsupported NetworkProtocolType:{networkProtocolType}");
|
||||
|
@@ -13,6 +13,7 @@ namespace TEngine.Core.Network
|
||||
{
|
||||
switch (networkProtocolType)
|
||||
{
|
||||
#if !UNITY_WEBGL
|
||||
case NetworkProtocolType.KCP:
|
||||
{
|
||||
Network = new KCPServerNetwork(Scene, networkTarget, address);
|
||||
@@ -25,6 +26,7 @@ namespace TEngine.Core.Network
|
||||
// Log.Info($"NetworkProtocol:TCP IPEndPoint:{address}");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
throw new NotSupportedException($"Unsupported NetworkProtocolType:{networkProtocolType}");
|
||||
|
@@ -9,6 +9,7 @@ namespace TEngine.Core.Network
|
||||
{
|
||||
try
|
||||
{
|
||||
DisposePackInfo = false;
|
||||
switch (packInfo.ProtocolCode)
|
||||
{
|
||||
case > Opcode.InnerRouteResponse:
|
||||
|
@@ -1,3 +1,4 @@
|
||||
#if !UNITY_WEBGL
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
@@ -55,7 +56,6 @@ namespace TEngine.Core.Network
|
||||
ThreadSynchronizationContext.Main.Post(OnConnectDisconnect);
|
||||
}
|
||||
|
||||
_socket.Disconnect(false);
|
||||
_socket.Close();
|
||||
}
|
||||
|
||||
@@ -565,4 +565,5 @@ namespace TEngine.Core.Network
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -1,3 +1,4 @@
|
||||
#if !UNITY_WEBGL
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -459,4 +460,5 @@ namespace TEngine.Core.Network
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -1,3 +1,4 @@
|
||||
#if !UNITY_WEBGL
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
@@ -232,4 +233,5 @@ namespace TEngine.Core.Network
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -1,3 +1,4 @@
|
||||
#if !UNITY_WEBGL
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -538,4 +539,5 @@ namespace TEngine.Core.Network
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -1,3 +1,4 @@
|
||||
#if !UNITY_WEBGL
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -235,4 +236,5 @@ namespace TEngine.Core.Network
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -1,3 +1,4 @@
|
||||
#if !UNITY_WEBGL
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
@@ -346,4 +347,5 @@ namespace TEngine.Core.Network
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -3,7 +3,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
#if UNITY_WEBGL
|
||||
using Cysharp.Threading.Tasks;
|
||||
#else
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using TEngine.DataStructure;
|
||||
#pragma warning disable CS8601
|
||||
#pragma warning disable CS8604
|
||||
@@ -25,10 +29,10 @@ namespace TEngine.Core
|
||||
private static void Load(int assemblyName)
|
||||
{
|
||||
var count = 0;
|
||||
var task = new List<Task>();
|
||||
|
||||
#if !UNITY_WEBGL
|
||||
var task = new List<Task>();
|
||||
#endif
|
||||
UnLoad(assemblyName);
|
||||
|
||||
foreach (var singletonType in AssemblyManager.ForEach(assemblyName, typeof(ISingleton)))
|
||||
{
|
||||
var instance = (ISingleton) Activator.CreateInstance(singletonType);
|
||||
@@ -38,7 +42,11 @@ namespace TEngine.Core
|
||||
|
||||
if (initializeMethodInfo != null)
|
||||
{
|
||||
#if !UNITY_WEBGL
|
||||
task.Add((Task) initializeMethodInfo.Invoke(instance, null));
|
||||
#else
|
||||
initializeMethodInfo.Invoke(instance, null);
|
||||
#endif
|
||||
}
|
||||
|
||||
registerMethodInfo?.Invoke(instance, new object[] {instance});
|
||||
@@ -58,7 +66,9 @@ namespace TEngine.Core
|
||||
Singletons.Enqueue(assemblyName, instance);
|
||||
}
|
||||
|
||||
#if !UNITY_WEBGL
|
||||
Task.WaitAll(task.ToArray());
|
||||
#endif
|
||||
Log.Info($"assembly:{assemblyName} load Singleton count:{count}");
|
||||
}
|
||||
|
||||
|
@@ -69,6 +69,8 @@ public static class TEngineSettingsHelper
|
||||
Define.ServerCustomExportDirectory = FileHelper.GetFullPath(root["Export:ServerCustomExportDirectory:Value"]);
|
||||
// 客户端自定义导出代码
|
||||
Define.ClientCustomExportDirectory = FileHelper.GetFullPath(root["Export:ClientCustomExportDirectory:Value"]);
|
||||
// SceneConfig.xlsx的位置
|
||||
Define.SceneConfigPath = FileHelper.GetFullPath(root["Export:SceneConfigPath:Value"]);
|
||||
// 自定义导出代码存放的程序集
|
||||
Define.CustomExportAssembly = FileHelper.GetFullPath(root["Export:CustomExportAssembly:Value"]);
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
#if !UNITY_WEBGL
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
@@ -10,19 +11,18 @@ using System.Linq;
|
||||
{
|
||||
aucThread = new Thread(ReceiveMsg);
|
||||
aucThread.Start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//进程调用主线程方法
|
||||
MainPack pack = (MainPack)MainPack.Descriptor.Parser.ParseFrom(buffer, 0, len);
|
||||
Loom.QueueOnMainThread((param) =>
|
||||
{
|
||||
UdpHandleResponse(pack);
|
||||
}, null);
|
||||
|
||||
|
||||
*******************************************************************************/
|
||||
namespace GameBase
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Loom多线程通信。
|
||||
/// <remarks></remarks>
|
||||
@@ -187,4 +187,5 @@ namespace GameBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab10a5a730054c5aaa942164c750abfb
|
||||
timeCreated: 1689576189
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94212c40840344b5bd6ba4fc82097d47
|
||||
timeCreated: 1689576337
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78e93a657ea64d5d97000e8b6cc83ffc
|
||||
timeCreated: 1689576342
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3212280593954784b888cf6e9fa088a8
|
||||
timeCreated: 1689584199
|
@@ -1,11 +0,0 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// Actor属性数据管理。
|
||||
/// </summary>
|
||||
public class ActorData : EntityLogicComponent
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a344b822c96449a29d78fb64b02c762d
|
||||
timeCreated: 1689584206
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc314cd9682f4c1d8a870e2b4c6a5c88
|
||||
timeCreated: 1689584122
|
@@ -1,86 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 实体类的Buff管理。
|
||||
/// </summary>
|
||||
public class BuffComponent:EntityLogicComponent
|
||||
{
|
||||
private readonly Dictionary<int, BufferItem> _allBuff = new Dictionary<int, BufferItem>();
|
||||
private readonly List<BufferItem> _listBuff = new List<BufferItem>();
|
||||
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
foreach (var bufferItem in _listBuff)
|
||||
{
|
||||
BufferItem.Release(bufferItem);
|
||||
}
|
||||
_listBuff.Clear();
|
||||
_allBuff.Clear();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加Buff。
|
||||
/// </summary>
|
||||
/// <param name="buffId">BuffId。</param>
|
||||
/// <param name="caster">施法者。</param>
|
||||
/// <param name="addStackNum">增加层数。</param>
|
||||
/// <param name="skillId">技能Id。</param>
|
||||
/// <returns></returns>
|
||||
public bool AddBuff(int buffId, EntityLogic caster, int addStackNum = 1, uint skillId = 0)
|
||||
{
|
||||
BufferItem bufferItem = BufferItem.Alloc(buffId);
|
||||
if (bufferItem == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
RefreshBuffAttr();
|
||||
UpdateBuffState();
|
||||
_allBuff.Add(buffId, bufferItem);
|
||||
_listBuff.Add(bufferItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除Buff。
|
||||
/// </summary>
|
||||
/// <param name="buffID">BuffID。</param>
|
||||
/// <param name="caster">移除施放来源。</param>
|
||||
public void RmvBuff(int buffID, EntityLogic caster)
|
||||
{
|
||||
if (_allBuff.TryGetValue(buffID, out BufferItem buffItem))
|
||||
{
|
||||
RemoveBuffFromList(buffItem);
|
||||
RefreshBuffAttr();
|
||||
UpdateBuffState();
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveBuffFromList(BufferItem buffItem)
|
||||
{
|
||||
Log.Info("remove buff: {0}", buffItem.BuffID);
|
||||
BufferItem.Release(buffItem);
|
||||
_allBuff.Remove(buffItem.BuffID);
|
||||
_listBuff.Remove(buffItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新Buff带来的属性。
|
||||
/// </summary>
|
||||
private void RefreshBuffAttr()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新Buff改变的状态。
|
||||
/// </summary>
|
||||
private void UpdateBuffState()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29088ba5001247628aefb072c6d82705
|
||||
timeCreated: 1689582372
|
@@ -1,62 +0,0 @@
|
||||
using GameConfig.Battle;
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// Buff实例。
|
||||
/// </summary>
|
||||
public class BufferItem:IMemory
|
||||
{
|
||||
/// <summary>
|
||||
/// BuffId。
|
||||
/// </summary>
|
||||
public int BuffID => BuffConfig?.BuffID ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// BUff配置表。
|
||||
/// </summary>
|
||||
public BuffConfig BuffConfig { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 清理内存。
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
BuffConfig = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成Buff实例。
|
||||
/// </summary>
|
||||
/// <param name="buffId">buffId。</param>
|
||||
/// <returns>Buff实例。</returns>
|
||||
public static BufferItem Alloc(int buffId)
|
||||
{
|
||||
Log.Debug($"Alloc buffItem buffId:{buffId}");
|
||||
BuffConfig buffConfig = ConfigLoader.Instance.Tables.TbBuff.Get(buffId);
|
||||
if (buffConfig == null)
|
||||
{
|
||||
Log.Warning($"Alloc buffItem Failed ! buffId:{buffId}");
|
||||
return null;
|
||||
}
|
||||
|
||||
BufferItem ret = MemoryPool.Acquire<BufferItem>();
|
||||
ret.BuffConfig = buffConfig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放Buff实例。
|
||||
/// </summary>
|
||||
/// <param name="bufferItem"></param>
|
||||
public static void Release(BufferItem bufferItem)
|
||||
{
|
||||
if (bufferItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MemoryPool.Release(bufferItem);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8915b9545484419eb2642a69d4056daf
|
||||
timeCreated: 1689584322
|
@@ -1,39 +0,0 @@
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 实体创建预数据。
|
||||
/// </summary>
|
||||
public class EntityCreateData:IMemory
|
||||
{
|
||||
public ActorEntityType actorEntityType;
|
||||
|
||||
public bool HasBornPos = false;
|
||||
|
||||
public Vector3 BornPos;
|
||||
|
||||
public Vector3 BornForward;
|
||||
|
||||
/// <summary>
|
||||
/// 设置出生点。
|
||||
/// </summary>
|
||||
/// <param name="bornPos"></param>
|
||||
/// <param name="forward"></param>
|
||||
public void SetBornPos(Vector3 bornPos, Vector3 forward)
|
||||
{
|
||||
HasBornPos = true;
|
||||
BornPos = bornPos;
|
||||
BornForward = forward;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
actorEntityType = ActorEntityType.None;
|
||||
HasBornPos = false;
|
||||
BornPos = Vector3.zero;
|
||||
BornForward = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ba847c6eb944645a4b693f1a432d933
|
||||
timeCreated: 1689583498
|
@@ -1,65 +0,0 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 逻辑层实体。
|
||||
/// </summary>
|
||||
public abstract class EntityLogic : Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 逻辑层实体类型。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract ActorEntityType GetActorEntityType();
|
||||
|
||||
/// <summary>
|
||||
/// 是否是战斗起始的Actor。
|
||||
/// <remarks>,比如双方参与战斗的玩家,或者技能编辑器里的Caster。</remarks>
|
||||
/// </summary>
|
||||
public bool IsStartActor;
|
||||
|
||||
public EntityCreateData CreateData { private set; get; }
|
||||
|
||||
public virtual string GetActorName()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
#region 缓存常用组件
|
||||
public ActorData ActorData { protected set; get; }
|
||||
|
||||
public BuffComponent BuffComponent { protected set; get; }
|
||||
public SkillCasterComponent SkillCaster { protected set; get; }
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
|
||||
internal bool LogicCreate(EntityCreateData entityCreateData)
|
||||
{
|
||||
CreateData = entityCreateData;
|
||||
OnLogicCreate();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void OnLogicCreate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal void LogicDestroy()
|
||||
{
|
||||
OnLogicDestroy();
|
||||
if (CreateData != null)
|
||||
{
|
||||
MemoryPool.Release(CreateData);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnLogicDestroy()
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7b01c5b166445d680dc411dfbe5c781
|
||||
timeCreated: 1689576203
|
@@ -1,12 +0,0 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 逻辑层组件实体。
|
||||
/// </summary>
|
||||
public abstract class EntityLogicComponent: Entity
|
||||
{
|
||||
public EntityLogic Owner => (EntityLogic)Parent;
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92574294d8144f218f323f63f72a8374
|
||||
timeCreated: 1689585864
|
@@ -1,143 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 实体类型。
|
||||
/// </summary>
|
||||
public enum ActorEntityType
|
||||
{
|
||||
None,
|
||||
Player,
|
||||
Monster,
|
||||
Pet,
|
||||
Npc,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逻辑层实体管理器。
|
||||
/// </summary>
|
||||
public class EntityLogicMgr
|
||||
{
|
||||
private static readonly Dictionary<long, EntityLogic> EntityLogicPool = new Dictionary<long, EntityLogic>();
|
||||
private static readonly List<EntityLogic> ListEntityLogics = new List<EntityLogic>();
|
||||
|
||||
public static event Action<EntityLogic> OnEntityCreate;
|
||||
public static event Action<EntityLogic> OnEntityDestroy;
|
||||
|
||||
public static List<EntityLogic> GetAllActor(ref List<EntityLogic> temp)
|
||||
{
|
||||
if (temp == null)
|
||||
{
|
||||
temp = new List<EntityLogic>();
|
||||
}
|
||||
temp.AddRange(ListEntityLogics);
|
||||
return temp;
|
||||
}
|
||||
|
||||
public static List<EntityLogic> GetTypeActor(ref List<EntityLogic> temp,ActorEntityType type)
|
||||
{
|
||||
if (temp == null)
|
||||
{
|
||||
temp = new List<EntityLogic>();
|
||||
}
|
||||
|
||||
foreach (var actor in ListEntityLogics)
|
||||
{
|
||||
if (actor.GetActorEntityType() == type)
|
||||
{
|
||||
temp.Add(actor);
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
public static EntityLogic CreateEntityLogic(EntityCreateData entityCreateData, bool isStartActor = false)
|
||||
{
|
||||
if (entityCreateData == null)
|
||||
{
|
||||
Log.Error("create actor failed, create data is null");
|
||||
return null;
|
||||
}
|
||||
var actor = CreateActorEntityObject(entityCreateData.actorEntityType);
|
||||
if (actor == null)
|
||||
{
|
||||
Log.Error("create actor failed, create data is {0}", entityCreateData);
|
||||
return null;
|
||||
}
|
||||
|
||||
actor.IsStartActor = isStartActor;
|
||||
if (!actor.LogicCreate(entityCreateData))
|
||||
{
|
||||
DestroyActor(actor);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (OnEntityCreate != null)
|
||||
{
|
||||
OnEntityCreate(actor);
|
||||
}
|
||||
|
||||
Log.Debug("entityLogic created: {0}", actor.GetActorName());
|
||||
return actor;
|
||||
}
|
||||
|
||||
private static EntityLogic CreateActorEntityObject(ActorEntityType actorType)
|
||||
{
|
||||
EntityLogic entityLogic = null;
|
||||
|
||||
switch (actorType)
|
||||
{
|
||||
case ActorEntityType.Player:
|
||||
{
|
||||
entityLogic = Entity.Create<PlayerEntity>(GameApp.Instance.Scene);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Log.Error("unknown actor type:{0}", actorType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (entityLogic != null)
|
||||
{
|
||||
EntityLogicPool.Add(entityLogic.RuntimeId, entityLogic);
|
||||
ListEntityLogics.Add(entityLogic);
|
||||
}
|
||||
return entityLogic;
|
||||
}
|
||||
|
||||
|
||||
public static bool DestroyActor(long runtimeId)
|
||||
{
|
||||
EntityLogicPool.TryGetValue(runtimeId, out EntityLogic entityLogic);
|
||||
if (entityLogic != null)
|
||||
{
|
||||
return DestroyActor(entityLogic);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool DestroyActor(EntityLogic entityLogic)
|
||||
{
|
||||
Log.Debug("on destroy entityLogic {0}", entityLogic.RuntimeId);
|
||||
|
||||
|
||||
var runtimeId = entityLogic.RuntimeId;
|
||||
Log.Assert(EntityLogicPool.ContainsKey(runtimeId));
|
||||
|
||||
if (OnEntityDestroy != null)
|
||||
{
|
||||
OnEntityDestroy(entityLogic);
|
||||
}
|
||||
|
||||
entityLogic.LogicDestroy();
|
||||
EntityLogicPool.Remove(runtimeId);
|
||||
ListEntityLogics.Remove(entityLogic);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 513b12007c8f408698d12aee22fc44db
|
||||
timeCreated: 1689579220
|
@@ -1,18 +0,0 @@
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
public class PlayerEntity : EntityLogic
|
||||
{
|
||||
public override ActorEntityType GetActorEntityType()
|
||||
{
|
||||
return ActorEntityType.Player;
|
||||
}
|
||||
|
||||
protected override void OnLogicCreate()
|
||||
{
|
||||
base.OnLogicCreate();
|
||||
ActorData = AddComponent<ActorData>();
|
||||
BuffComponent = AddComponent<BuffComponent>();
|
||||
SkillCaster = AddComponent<SkillCasterComponent>();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9939517fe9f04f0d9c0c544fbdd43564
|
||||
timeCreated: 1689576650
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d126355d2da45c8899a7a4fff5d376c
|
||||
timeCreated: 1689584135
|
@@ -1,35 +0,0 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 技能释放组件。
|
||||
/// </summary>
|
||||
public class SkillCasterComponent:EntityLogicComponent
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 播放技能。
|
||||
/// </summary>
|
||||
/// <param name="skillId">技能Id。</param>
|
||||
/// <param name="target">目标。</param>
|
||||
/// <param name="checkCd">是否检测CD。</param>
|
||||
/// <param name="forceCaster">是否强制释放。</param>
|
||||
/// <returns>是否播放成功。</returns>
|
||||
internal void PlaySkill(int skillId, EntityLogic target = null, bool forceCaster = false, bool checkCd = true)
|
||||
{
|
||||
Log.Assert(skillId > 0, $"ActorName: {Owner.GetActorName()}");
|
||||
Log.Debug("Start Play SKill[{0}]", skillId);
|
||||
|
||||
var skillBaseConfig = ConfigLoader.Instance.Tables.TbSkill.Get(skillId);
|
||||
|
||||
if (skillBaseConfig == null)
|
||||
{
|
||||
Log.Error("GetSkillBaseConfig Failed, invalid skillID: {0}", skillId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b445989d175457db064ef74adeb4181
|
||||
timeCreated: 1689582410
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c20684aa6954a80abe88ef8ee599800
|
||||
timeCreated: 1689585664
|
@@ -1,14 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 技能表现数据。
|
||||
/// <remarks>表现数据再由SkillElementData组成。</remarks>
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SkillDisplayData
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ffa4d74525b4c55ac6013a4372c6d42
|
||||
timeCreated: 1689586727
|
@@ -1,232 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using GameConfig.Battle;
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
public enum SkillPlayStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始状态。
|
||||
/// </summary>
|
||||
PlayInit,
|
||||
|
||||
/// <summary>
|
||||
/// 技能施法前摇。
|
||||
/// <remarks>播放动作阶段。</remarks>
|
||||
/// </summary>
|
||||
PlayingAim,
|
||||
|
||||
/// <summary>
|
||||
/// 播放技能阶段,该阶段同时只能有一个技能播放。
|
||||
/// </summary>
|
||||
PlayingFront,
|
||||
|
||||
/// <summary>
|
||||
/// 后台播放阶段,前台播放完后,可能还有一些元素要继续生效,这个时候转为后台播放阶段。
|
||||
/// 同时玩家可以释放新的技能。
|
||||
/// </summary>
|
||||
PlayingBack,
|
||||
|
||||
/// <summary>
|
||||
/// 播放完毕,等待播放.
|
||||
/// </summary>
|
||||
PlayingToFree
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 技能播放的数据。
|
||||
/// </summary>
|
||||
public class SkillPlayData:IMemory
|
||||
{
|
||||
/// <summary>
|
||||
/// 技能内存Id,代表该玩家当前的唯一技能Id。
|
||||
/// </summary>
|
||||
public uint skillGid = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 技能的配置Id。
|
||||
/// </summary>
|
||||
public uint skillId;
|
||||
|
||||
/// <summary>
|
||||
/// 技能的配置。
|
||||
/// </summary>
|
||||
public SkillBaseConfig skillBaseConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 技能表现ID.
|
||||
/// </summary>
|
||||
public int skillDisplayId;
|
||||
|
||||
/// <summary>
|
||||
/// 技能表现数据。
|
||||
/// </summary>
|
||||
public SkillDisplayData skillDisplayData;
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经创建过visual表现层。
|
||||
/// </summary>
|
||||
public bool HasVisualPlayData = false;
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间。
|
||||
/// </summary>
|
||||
public float startTime;
|
||||
|
||||
/// <summary>
|
||||
/// 开始技能进入后台的时间。
|
||||
/// </summary>
|
||||
public float startBackTime;
|
||||
|
||||
private SkillPlayStatus _status = SkillPlayStatus.PlayInit;
|
||||
|
||||
/// <summary>
|
||||
/// 播放状态
|
||||
/// </summary>
|
||||
public SkillPlayStatus Status
|
||||
{
|
||||
set
|
||||
{
|
||||
if (_status != value)
|
||||
{
|
||||
_status = value;
|
||||
if (_status == SkillPlayStatus.PlayingBack)
|
||||
{
|
||||
startBackTime = GameTime.time;
|
||||
}
|
||||
}
|
||||
}
|
||||
get => _status;
|
||||
}
|
||||
|
||||
public bool IsFrontStatus => _status == SkillPlayStatus.PlayingAim || _status == SkillPlayStatus.PlayingFront;
|
||||
|
||||
public bool IsRunningStatus => _status == SkillPlayStatus.PlayingFront || _status == SkillPlayStatus.PlayingBack;
|
||||
|
||||
private EntityLogic _casterActor = null;
|
||||
private SkillCasterComponent _skillCaster = null;
|
||||
|
||||
/// <summary>
|
||||
/// 获取技能施法者。
|
||||
/// </summary>
|
||||
public EntityLogic CasterActor
|
||||
{
|
||||
get => _casterActor;
|
||||
|
||||
set
|
||||
{
|
||||
_casterActor = value;
|
||||
_skillCaster = _casterActor.SkillCaster;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取施法者的运行时ID。
|
||||
/// </summary>
|
||||
public long CasterId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_casterActor != null)
|
||||
{
|
||||
return _casterActor.RuntimeId;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 目标对象。
|
||||
/// </summary>
|
||||
public EntityLogic targetActor;
|
||||
|
||||
/// <summary>
|
||||
/// 获取技能播放模块。
|
||||
/// </summary>
|
||||
internal SkillCasterComponent SkillCaster => _skillCaster;
|
||||
|
||||
/// <summary>
|
||||
/// 处理动画元素。
|
||||
/// </summary>
|
||||
internal SkillAnimationHandle animHandle;
|
||||
|
||||
/// <summary>
|
||||
/// 技能元素处理列表。
|
||||
/// </summary>
|
||||
internal List<SkillElementHandle> handleList = new List<SkillElementHandle>();
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
skillId = 0;
|
||||
skillGid = 0;
|
||||
skillDisplayId = 0;
|
||||
skillDisplayData = null;
|
||||
skillBaseConfig = null;
|
||||
|
||||
Status = SkillPlayStatus.PlayInit;
|
||||
startTime = 0;
|
||||
startBackTime = 0;
|
||||
|
||||
CasterActor = null;
|
||||
targetActor = null;
|
||||
DestroyAllElement();
|
||||
}
|
||||
|
||||
private void DestroyAllElement()
|
||||
{
|
||||
//销毁所有的ElementHandle
|
||||
foreach (var elemHandle in handleList)
|
||||
{
|
||||
elemHandle?.Destroy();
|
||||
}
|
||||
handleList.Clear();
|
||||
animHandle = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加技能元素处理。
|
||||
/// </summary>
|
||||
/// <param name="handle">技能元素处理。</param>
|
||||
/// <returns>是否增加成功。</returns>
|
||||
internal bool AddElementHandle(SkillElementHandle handle)
|
||||
{
|
||||
string errField = null;
|
||||
string checkResult = handle.CheckElementConfig(ref errField);
|
||||
if (!string.IsNullOrEmpty(checkResult))
|
||||
{
|
||||
Log.Warning("skill Element config[{0}] error: {1}, RandomSkillLibraryId[{2}]", handle.GetType().ToString(), checkResult, skillId);
|
||||
return false;
|
||||
}
|
||||
handleList.Add(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建表现层技能对象。
|
||||
/// </summary>
|
||||
internal void CreateVisualObject()
|
||||
{
|
||||
if (HasVisualPlayData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
HasVisualPlayData = true;
|
||||
//发送给visual事件
|
||||
//TODO
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁表现层技能对象。
|
||||
/// </summary>
|
||||
internal void DestroyVisualObject()
|
||||
{
|
||||
if (HasVisualPlayData && _casterActor != null)
|
||||
{
|
||||
HasVisualPlayData = false;
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05013b249849443eb8c5cb10491233ed
|
||||
timeCreated: 1689586140
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29cd06d7bab9405481fc35365616dac3
|
||||
timeCreated: 1689587459
|
@@ -1,7 +0,0 @@
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
public abstract class SkillElementData
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d6aefa939104f9d89a18ab78e385d05
|
||||
timeCreated: 1689587502
|
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
[Serializable]
|
||||
public enum SkillTriggerEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 无触发。
|
||||
/// </summary>
|
||||
NoneEvent,
|
||||
|
||||
/// <summary>
|
||||
/// 时间点触发。
|
||||
/// </summary>
|
||||
TimeEvent,
|
||||
|
||||
/// <summary>
|
||||
/// 施法结束触发。
|
||||
/// </summary>
|
||||
AnimStopEvent,
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0413bfaea7674c68bde372498c15cc2d
|
||||
timeCreated: 1689588039
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 503ad5f03b8b4f8aab31436f9c5f44eb
|
||||
timeCreated: 1689587434
|
@@ -1,7 +0,0 @@
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
public class SkillAnimationHandle:SkillElementHandle
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f93a8f3fc1e34bb8a03bdb3c0ba56e27
|
||||
timeCreated: 1689587524
|
@@ -1,152 +0,0 @@
|
||||
using GameConfig.Battle;
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 每个元素的状态。
|
||||
/// </summary>
|
||||
public enum SkillElementStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 元素状态初始化。
|
||||
/// </summary>
|
||||
ELEM_STATUS_INIT,
|
||||
|
||||
/// <summary>
|
||||
/// 元素状态运行中。
|
||||
/// </summary>
|
||||
ELEM_STATUS_RUN,
|
||||
|
||||
/// <summary>
|
||||
/// 元素状态停止。
|
||||
/// </summary>
|
||||
ELEM_STATUS_STOP
|
||||
}
|
||||
|
||||
public abstract class SkillElementHandle
|
||||
{
|
||||
private static uint m_nextHandleGID = 1;
|
||||
|
||||
public uint m_handleGID;
|
||||
public EntityLogic CasterActor;
|
||||
protected uint m_skillId;
|
||||
protected SkillAttrDamageData[] m_damageAttr;
|
||||
|
||||
protected SkillPlayData m_playData;
|
||||
public SkillElementStatus Status = SkillElementStatus.ELEM_STATUS_INIT;
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
if (Status == SkillElementStatus.ELEM_STATUS_RUN)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
OnDestroy();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化接口
|
||||
/// </summary>
|
||||
public void Init(SkillPlayData playData, SkillAttrDamageData[] damageAttr)
|
||||
{
|
||||
m_handleGID = m_nextHandleGID++;
|
||||
CasterActor = playData.CasterActor;
|
||||
m_skillId = playData.skillId;
|
||||
m_playData = playData;
|
||||
m_damageAttr = damageAttr;
|
||||
|
||||
Status = SkillElementStatus.ELEM_STATUS_INIT;
|
||||
OnInit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发Element开始。
|
||||
/// </summary>
|
||||
/// <param name="playData">技能播放数据。</param>
|
||||
/// <param name="eventType">技能触发类型。</param>
|
||||
public void Start(SkillPlayData playData, SkillTriggerEvent eventType)
|
||||
{
|
||||
if (Status != SkillElementStatus.ELEM_STATUS_INIT)
|
||||
{
|
||||
Log.Error("invalid status skillId[{0}] element Type[{1}]", m_skillId, GetType().Name);
|
||||
return;
|
||||
}
|
||||
|
||||
Status = SkillElementStatus.ELEM_STATUS_RUN;
|
||||
|
||||
//如果是重复触发的机制,则不需要开始就触发。
|
||||
OnStart(playData, eventType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发Element结束。
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (Status == SkillElementStatus.ELEM_STATUS_STOP)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Status != SkillElementStatus.ELEM_STATUS_RUN)
|
||||
{
|
||||
Status = SkillElementStatus.ELEM_STATUS_STOP;
|
||||
return;
|
||||
}
|
||||
|
||||
Status = SkillElementStatus.ELEM_STATUS_STOP;
|
||||
OnStop();
|
||||
}
|
||||
|
||||
#region override function
|
||||
|
||||
/// <summary>
|
||||
/// 检查配置是否正常
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual string CheckElementConfig(ref string errField)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一些数,在加入到技能列表的时候触发
|
||||
/// </summary>
|
||||
protected virtual void OnInit()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发销毁。
|
||||
/// </summary>
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发开始
|
||||
/// </summary>
|
||||
/// <param name="playData">触发开始的消息类型</param>
|
||||
/// <param name="eventType">触发开始的消息类型</param>
|
||||
protected virtual void OnStart(SkillPlayData playData, SkillTriggerEvent eventType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发结束。
|
||||
/// </summary>
|
||||
protected virtual void OnStop()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 调试绘制。
|
||||
/// </summary>
|
||||
public virtual void OnDrawGizmos()
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 689c542f2f41447395080f93982a872f
|
||||
timeCreated: 1689587448
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fad718b498934a5d8c63aa6d1e115485
|
||||
timeCreated: 1689576347
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 489220b19d954b69be5e170287e92210
|
||||
timeCreated: 1689584174
|
@@ -1,18 +0,0 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 外观显示组件。
|
||||
/// </summary>
|
||||
public class DisplayComponent:EntityLogicComponent
|
||||
{
|
||||
public DisplayInfo displayInfo;
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
MemoryPool.Release(displayInfo);
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1b7fbc52816477c9fc7de9eabe17667
|
||||
timeCreated: 1689582273
|
@@ -1,12 +0,0 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
public class DisplayInfo:IMemory
|
||||
{
|
||||
public void Clear()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ee020b854aa4c62b684df994d73ad7a
|
||||
timeCreated: 1689585424
|
@@ -1,14 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic.BattleDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 表现层实体。
|
||||
/// </summary>
|
||||
public abstract class EntityVisual:MonoBehaviour
|
||||
{
|
||||
public EntityLogic Entity { protected set; get;}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 892288dabf264b20b49b03ae91ccf5f8
|
||||
timeCreated: 1689576255
|
@@ -7,8 +7,6 @@ public partial class GameApp:Singleton<GameApp>
|
||||
{
|
||||
private static List<Assembly> _hotfixAssembly;
|
||||
|
||||
public Scene Scene { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 热更域App主入口。
|
||||
/// </summary>
|
||||
@@ -26,6 +24,7 @@ public partial class GameApp:Singleton<GameApp>
|
||||
Utility.Unity.AddDestroyListener(Instance.OnDestroy);
|
||||
Utility.Unity.AddOnDrawGizmosListener(Instance.OnDrawGizmos);
|
||||
Utility.Unity.AddOnApplicationPauseListener(Instance.OnApplicationPause);
|
||||
GameModule.Procedure.RestartProcedure(new GameLogic.OnEnterGameAppProcedure());
|
||||
Instance.StartGameLogic();
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,11 @@ public partial class GameApp
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entity框架根节点。
|
||||
/// </summary>
|
||||
public Scene Scene { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册所有逻辑系统
|
||||
/// </summary>
|
||||
@@ -38,6 +43,7 @@ public partial class GameApp
|
||||
//带生命周期的单例系统。
|
||||
AddLogicSys(BehaviourSingleSystem.Instance);
|
||||
AddLogicSys(DataCenterSys.Instance);
|
||||
AddLogicSys(ConfigSystem.Instance);
|
||||
GMBehaviourSystem.Instance.Active();
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,13 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class OnEnterGameAppProcedure : ProcedureBase
|
||||
{
|
||||
protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
|
||||
{
|
||||
base.OnEnter(procedureOwner);
|
||||
Log.Debug("OnEnter GameApp Procedure");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 415b43b274b541a0a2312417644452b0
|
||||
timeCreated: 1692956662
|
@@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f3bcefaf67e76141a6d8edeb8354fea
|
||||
TextScriptImporter:
|
||||
guid: 0fcee77031f85f84dbc6735c875d64b8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
|
||||
public enum SnapStatus
|
||||
{
|
||||
NoTargetSet = 0,
|
||||
TargetHasSet = 1,
|
||||
SnapMoving = 2,
|
||||
SnapMoveFinish = 3
|
||||
}
|
||||
|
||||
|
||||
public enum ItemCornerEnum
|
||||
{
|
||||
LeftBottom = 0,
|
||||
LeftTop,
|
||||
RightTop,
|
||||
RightBottom,
|
||||
}
|
||||
|
||||
|
||||
public enum ListItemArrangeType
|
||||
{
|
||||
TopToBottom = 0,
|
||||
BottomToTop,
|
||||
LeftToRight,
|
||||
RightToLeft,
|
||||
}
|
||||
|
||||
public enum GridItemArrangeType
|
||||
{
|
||||
TopLeftToBottomRight = 0,
|
||||
BottomLeftToTopRight,
|
||||
TopRightToBottomLeft,
|
||||
BottomRightToTopLeft,
|
||||
}
|
||||
public enum GridFixedType
|
||||
{
|
||||
ColumnCountFixed = 0,
|
||||
RowCountFixed,
|
||||
}
|
||||
|
||||
public struct RowColumnPair
|
||||
{
|
||||
public RowColumnPair(int row1, int column1)
|
||||
{
|
||||
mRow = row1;
|
||||
mColumn = column1;
|
||||
}
|
||||
|
||||
public bool Equals(RowColumnPair other)
|
||||
{
|
||||
return this.mRow == other.mRow && this.mColumn == other.mColumn;
|
||||
}
|
||||
|
||||
public static bool operator ==(RowColumnPair a, RowColumnPair b)
|
||||
{
|
||||
return (a.mRow == b.mRow)&&(a.mColumn == b.mColumn);
|
||||
}
|
||||
public static bool operator !=(RowColumnPair a, RowColumnPair b)
|
||||
{
|
||||
return (a.mRow != b.mRow) || (a.mColumn != b.mColumn); ;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (obj is RowColumnPair) && Equals((RowColumnPair)obj);
|
||||
}
|
||||
|
||||
|
||||
public int mRow;
|
||||
public int mColumn;
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19e4e487f35877f4b9bb864eb43484d6
|
||||
timeCreated: 1534508353
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 090163c612f34ac4fb80004ac5f057b4
|
||||
TextScriptImporter:
|
||||
guid: d7f738dc5a266e94d9e9870fc76009c2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
@@ -0,0 +1,173 @@
|
||||
namespace GameLogic
|
||||
{
|
||||
//if GridFixedType is GridFixedType.ColumnCountFixed, then the GridItemGroup is one row of the gridview
|
||||
//if GridFixedType is GridFixedType.RowCountFixed, then the GridItemGroup is one column of the gridview
|
||||
public class GridItemGroup
|
||||
{
|
||||
private int _count = 0;
|
||||
private int _groupIndex = -1;//the row index or the column index of this group
|
||||
private LoopGridViewItem _first = null;
|
||||
private LoopGridViewItem _last = null;
|
||||
public int Count => _count;
|
||||
|
||||
public LoopGridViewItem First => _first;
|
||||
|
||||
public LoopGridViewItem Last => _last;
|
||||
|
||||
public int GroupIndex
|
||||
{
|
||||
get => _groupIndex;
|
||||
set => _groupIndex = value;
|
||||
}
|
||||
|
||||
|
||||
public LoopGridViewItem GetItemByColumn(int column)
|
||||
{
|
||||
LoopGridViewItem cur = _first;
|
||||
while(cur != null)
|
||||
{
|
||||
if(cur.Column == column)
|
||||
{
|
||||
return cur;
|
||||
}
|
||||
cur = cur.NextItem;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public LoopGridViewItem GetItemByRow(int row)
|
||||
{
|
||||
LoopGridViewItem cur = _first;
|
||||
while (cur != null)
|
||||
{
|
||||
if (cur.Row == row)
|
||||
{
|
||||
return cur;
|
||||
}
|
||||
cur = cur.NextItem;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void ReplaceItem(LoopGridViewItem curItem,LoopGridViewItem newItem)
|
||||
{
|
||||
newItem.PrevItem = curItem.PrevItem;
|
||||
newItem.NextItem = curItem.NextItem;
|
||||
if(newItem.PrevItem != null)
|
||||
{
|
||||
newItem.PrevItem.NextItem = newItem;
|
||||
}
|
||||
if(newItem.NextItem != null)
|
||||
{
|
||||
newItem.NextItem.PrevItem = newItem;
|
||||
}
|
||||
if(_first == curItem)
|
||||
{
|
||||
_first = newItem;
|
||||
}
|
||||
if(_last == curItem)
|
||||
{
|
||||
_last = newItem;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddFirst(LoopGridViewItem newItem)
|
||||
{
|
||||
newItem.PrevItem = null;
|
||||
newItem.NextItem = null;
|
||||
if (_first == null)
|
||||
{
|
||||
_first = newItem;
|
||||
_last = newItem;
|
||||
_first.PrevItem = null;
|
||||
_first.NextItem = null;
|
||||
_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_first.PrevItem = newItem;
|
||||
newItem.PrevItem = null;
|
||||
newItem.NextItem = _first;
|
||||
_first = newItem;
|
||||
_count++;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddLast(LoopGridViewItem newItem)
|
||||
{
|
||||
newItem.PrevItem = null;
|
||||
newItem.NextItem = null;
|
||||
if (_first == null)
|
||||
{
|
||||
_first = newItem;
|
||||
_last = newItem;
|
||||
_first.PrevItem = null;
|
||||
_first.NextItem = null;
|
||||
_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_last.NextItem = newItem;
|
||||
newItem.PrevItem = _last;
|
||||
newItem.NextItem = null;
|
||||
_last = newItem;
|
||||
_count++;
|
||||
}
|
||||
}
|
||||
|
||||
public LoopGridViewItem RemoveFirst()
|
||||
{
|
||||
LoopGridViewItem ret = _first;
|
||||
if (_first == null)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if(_first == _last)
|
||||
{
|
||||
_first = null;
|
||||
_last = null;
|
||||
--_count;
|
||||
return ret;
|
||||
}
|
||||
_first = _first.NextItem;
|
||||
_first.PrevItem = null;
|
||||
--_count;
|
||||
return ret;
|
||||
}
|
||||
public LoopGridViewItem RemoveLast()
|
||||
{
|
||||
LoopGridViewItem ret = _last;
|
||||
if (_first == null)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (_first == _last)
|
||||
{
|
||||
_first = null;
|
||||
_last = null;
|
||||
--_count;
|
||||
return ret;
|
||||
}
|
||||
_last = _last.PrevItem;
|
||||
_last.NextItem = null;
|
||||
--_count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
LoopGridViewItem current = _first;
|
||||
while (current != null)
|
||||
{
|
||||
current.PrevItem = null;
|
||||
current.NextItem = null;
|
||||
current = current.NextItem;
|
||||
}
|
||||
_first = null;
|
||||
_last = null;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7e7eb25fe1319d4b8773ddfab7a240e
|
||||
timeCreated: 1554538573
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class GridItemPool
|
||||
{
|
||||
private GameObject _prefabObj;
|
||||
private string _prefabName;
|
||||
private int _initCreateCount = 1;
|
||||
private readonly List<LoopGridViewItem> _tmpPooledItemList = new List<LoopGridViewItem>();
|
||||
private readonly List<LoopGridViewItem> _pooledItemList = new List<LoopGridViewItem>();
|
||||
private static int _curItemIdCount = 0;
|
||||
private RectTransform _itemParent = null;
|
||||
public GridItemPool()
|
||||
{
|
||||
|
||||
}
|
||||
public void Init(GameObject prefabObj, int createCount, RectTransform parent)
|
||||
{
|
||||
_prefabObj = prefabObj;
|
||||
_prefabName = _prefabObj.name;
|
||||
_initCreateCount = createCount;
|
||||
_itemParent = parent;
|
||||
_prefabObj.SetActive(false);
|
||||
for (int i = 0; i < _initCreateCount; ++i)
|
||||
{
|
||||
LoopGridViewItem tViewItem = CreateItem();
|
||||
RecycleItemReal(tViewItem);
|
||||
}
|
||||
}
|
||||
public LoopGridViewItem GetItem()
|
||||
{
|
||||
_curItemIdCount++;
|
||||
LoopGridViewItem tItem = null;
|
||||
if (_tmpPooledItemList.Count > 0)
|
||||
{
|
||||
int count = _tmpPooledItemList.Count;
|
||||
tItem = _tmpPooledItemList[count - 1];
|
||||
_tmpPooledItemList.RemoveAt(count - 1);
|
||||
tItem.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = _pooledItemList.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
tItem = CreateItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
tItem = _pooledItemList[count - 1];
|
||||
_pooledItemList.RemoveAt(count - 1);
|
||||
tItem.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
tItem.ItemId = _curItemIdCount;
|
||||
return tItem;
|
||||
|
||||
}
|
||||
|
||||
public void DestroyAllItem()
|
||||
{
|
||||
ClearTmpRecycledItem();
|
||||
int count = _pooledItemList.Count;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
GameObject.DestroyImmediate(_pooledItemList[i].gameObject);
|
||||
}
|
||||
_pooledItemList.Clear();
|
||||
}
|
||||
public LoopGridViewItem CreateItem()
|
||||
{
|
||||
|
||||
GameObject go = GameObject.Instantiate<GameObject>(_prefabObj, Vector3.zero, Quaternion.identity, _itemParent);
|
||||
go.SetActive(true);
|
||||
RectTransform rf = go.GetComponent<RectTransform>();
|
||||
rf.localScale = Vector3.one;
|
||||
rf.anchoredPosition3D = Vector3.zero;
|
||||
rf.localEulerAngles = Vector3.zero;
|
||||
LoopGridViewItem tViewItem = go.GetComponent<LoopGridViewItem>();
|
||||
tViewItem.ItemPrefabName = _prefabName;
|
||||
tViewItem.GoId = go.GetHashCode();
|
||||
return tViewItem;
|
||||
}
|
||||
void RecycleItemReal(LoopGridViewItem item)
|
||||
{
|
||||
item.gameObject.SetActive(false);
|
||||
_pooledItemList.Add(item);
|
||||
}
|
||||
public void RecycleItem(LoopGridViewItem item)
|
||||
{
|
||||
item.PrevItem = null;
|
||||
item.NextItem = null;
|
||||
_tmpPooledItemList.Add(item);
|
||||
}
|
||||
public void ClearTmpRecycledItem()
|
||||
{
|
||||
int count = _tmpPooledItemList.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
RecycleItemReal(_tmpPooledItemList[i]);
|
||||
}
|
||||
_tmpPooledItemList.Clear();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1eb92a17e8cee642a2245950dfaabea
|
||||
timeCreated: 1554538573
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17e9881a7bce8124a8f855b96a8ca11a
|
||||
timeCreated: 1554538573
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,184 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
|
||||
public class LoopGridViewItem : MonoBehaviour
|
||||
{
|
||||
// indicates the item’s index in the list the mItemIndex can only be from 0 to itemTotalCount -1.
|
||||
int mItemIndex = -1;
|
||||
// the row index, the item is in. starting from 0.
|
||||
int mRow = -1;
|
||||
// the column index, the item is in. starting from 0.
|
||||
int mColumn = -1;
|
||||
//indicates the item’s id.
|
||||
//This property is set when the item is created or fetched from pool,
|
||||
//and will no longer change until the item is recycled back to pool.
|
||||
int mItemId = -1;
|
||||
|
||||
private int _goId = 0;
|
||||
|
||||
public int GoId
|
||||
{
|
||||
set => _goId = value;
|
||||
get => _goId;
|
||||
}
|
||||
|
||||
LoopGridView mParentGridView = null;
|
||||
bool mIsInitHandlerCalled = false;
|
||||
string mItemPrefabName;
|
||||
RectTransform mCachedRectTransform;
|
||||
int mItemCreatedCheckFrameCount = 0;
|
||||
|
||||
object mUserObjectData = null;
|
||||
int mUserIntData1 = 0;
|
||||
int mUserIntData2 = 0;
|
||||
string mUserStringData1 = null;
|
||||
string mUserStringData2 = null;
|
||||
|
||||
LoopGridViewItem mPrevItem;
|
||||
LoopGridViewItem mNextItem;
|
||||
|
||||
public object UserObjectData
|
||||
{
|
||||
get { return mUserObjectData; }
|
||||
set { mUserObjectData = value; }
|
||||
}
|
||||
public int UserIntData1
|
||||
{
|
||||
get { return mUserIntData1; }
|
||||
set { mUserIntData1 = value; }
|
||||
}
|
||||
public int UserIntData2
|
||||
{
|
||||
get { return mUserIntData2; }
|
||||
set { mUserIntData2 = value; }
|
||||
}
|
||||
public string UserStringData1
|
||||
{
|
||||
get { return mUserStringData1; }
|
||||
set { mUserStringData1 = value; }
|
||||
}
|
||||
public string UserStringData2
|
||||
{
|
||||
get { return mUserStringData2; }
|
||||
set { mUserStringData2 = value; }
|
||||
}
|
||||
|
||||
public int ItemCreatedCheckFrameCount
|
||||
{
|
||||
get { return mItemCreatedCheckFrameCount; }
|
||||
set { mItemCreatedCheckFrameCount = value; }
|
||||
}
|
||||
|
||||
|
||||
public RectTransform CachedRectTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mCachedRectTransform == null)
|
||||
{
|
||||
mCachedRectTransform = gameObject.GetComponent<RectTransform>();
|
||||
}
|
||||
return mCachedRectTransform;
|
||||
}
|
||||
}
|
||||
|
||||
public string ItemPrefabName
|
||||
{
|
||||
get
|
||||
{
|
||||
return mItemPrefabName;
|
||||
}
|
||||
set
|
||||
{
|
||||
mItemPrefabName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Row
|
||||
{
|
||||
get
|
||||
{
|
||||
return mRow;
|
||||
}
|
||||
set
|
||||
{
|
||||
mRow = value;
|
||||
}
|
||||
}
|
||||
public int Column
|
||||
{
|
||||
get
|
||||
{
|
||||
return mColumn;
|
||||
}
|
||||
set
|
||||
{
|
||||
mColumn = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int ItemIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return mItemIndex;
|
||||
}
|
||||
set
|
||||
{
|
||||
mItemIndex = value;
|
||||
}
|
||||
}
|
||||
public int ItemId
|
||||
{
|
||||
get
|
||||
{
|
||||
return mItemId;
|
||||
}
|
||||
set
|
||||
{
|
||||
mItemId = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool IsInitHandlerCalled
|
||||
{
|
||||
get
|
||||
{
|
||||
return mIsInitHandlerCalled;
|
||||
}
|
||||
set
|
||||
{
|
||||
mIsInitHandlerCalled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public LoopGridView ParentGridView
|
||||
{
|
||||
get
|
||||
{
|
||||
return mParentGridView;
|
||||
}
|
||||
set
|
||||
{
|
||||
mParentGridView = value;
|
||||
}
|
||||
}
|
||||
|
||||
public LoopGridViewItem PrevItem
|
||||
{
|
||||
get { return mPrevItem; }
|
||||
set { mPrevItem = value; }
|
||||
}
|
||||
public LoopGridViewItem NextItem
|
||||
{
|
||||
get { return mNextItem; }
|
||||
set { mNextItem = value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec0432517adfcb84bb6163d7a44ab8c1
|
||||
timeCreated: 1554538573
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25113973d38eb5a48b064863830539a4
|
||||
TextScriptImporter:
|
||||
guid: e9bbd48a4abc45c46a92b92d0df3ae07
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
@@ -8,23 +8,6 @@ using Object = UnityEngine.Object;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public enum ItemCornerEnum
|
||||
{
|
||||
LeftBottom = 0,
|
||||
LeftTop,
|
||||
RightTop,
|
||||
RightBottom,
|
||||
}
|
||||
|
||||
|
||||
public enum ListItemArrangeType
|
||||
{
|
||||
TopToBottom,
|
||||
BottomToTop,
|
||||
LeftToRight,
|
||||
RightToLeft,
|
||||
}
|
||||
|
||||
public class ItemPool
|
||||
{
|
||||
private GameObject _prefabObj;
|
||||
@@ -171,13 +154,6 @@ namespace GameLogic
|
||||
public delegate LoopListViewItem
|
||||
OnGetItemByIndex(LoopListView listView, int index); // System.Func<LoopListView, int, LoopListViewItem>
|
||||
|
||||
public enum SnapStatus
|
||||
{
|
||||
NoTargetSet = 0,
|
||||
TargetHasSet = 1,
|
||||
SnapMoving = 2,
|
||||
SnapMoveFinish = 3
|
||||
}
|
||||
|
||||
public class LoopListView : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
|
||||
{
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user