ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

ET 框架构建指南:从 dotnet build 到 Proto 导出、服务器启动与发布的完整工作流

2026/9/16 12:05:13 拓冰建站 浏览量
ET 框架构建指南:从 dotnet build 到 Proto 导出、服务器启动与发布的完整工作流 ET 框架构建指南从 dotnet build 到 Proto 导出、服务器启动与发布的完整工作流【免费下载链接】ETUnity3D Client And C# Server Framework项目地址: https://gitcode.com/GitHub_Trending/et/ET导读本文是 ETUnity3D Client And C# Server Framework开源仓库中et-build技能文档及其参考手册 et-build-commands.md 的完整解读与源码级扩充。你将掌握 ET 项目中四类高频构建操作的标准入口——编译与分析器验证dotnet build ET.sln、Proto 消息导出ET.Proto2CS.dll、服务器启动ET.App.dll --Console1与版本发布Publish.ps1并理解每条命令背后的实现原理、前置条件与常见排错路径。读完即可按统一规范独立完成 ET 项目的构建、验证与发布闭环。et-build 技能定位与使用边界et-build是 ET 仓库 harness 包中面向构建与导出场景的 Agent 技能入口其定义位于 SKILL.md并在技能索引 index.md 中被归类为构建与导出分组。它只负责四件事编译项目唯一命令dotnet build ET.sln导出 Proto 文件.proto→ C#启动服务器发布版本与之相对技能文档明确划定了不应加载本技能的场景只是改代码、写测试还没到编译或导出环节 → 用et-code/et-async等开发技能只是导出 Luban 配置 → 用et-luban技能只是查询架构规范或包依赖 → 用et-code技能这种职责划分与索引文档中的组合场景一致et-build通常处于开发链路的末端如et-tdd→et-test-write→et-code→et-build→et-test-run只在需要真正编译、运行或发布时才介入。四条默认动作原则在动手执行任何命令之前et-build技能要求遵守四条全局原则它们是整个构建工作流的行为基线编译和分析器验证统一使用dotnet build ET.sln不单独编译某个包也不用 IDE 私有方案。这样保证全仓库的编译语义一致且所有 Roslyn 分析器见下文编译与分析器验证在每次构建中都被真实执行。服务器必须在 Unity 项目根目录启动不在Bin/目录内启动——因为 ET.App 启动时需要以项目根目录为工作目录来定位Packages/、Config/、Logs/等相对路径。运行服务器前先清理旧Logs/避免新日志与旧日志混在一起导致排查困难。Model / Hotfix 程序集不能用 IDE 编译必须走项目规定的 Unity / ET 编译入口即dotnet build ET.sln。这背后是 ET 的代码模式CodeMode设计运行时程序集按 Model / Hotfix / Loader 分层组织只有经统一构建入口生成才能保证源生成器与分析器的输出一致。对应的高频命令与默认动作一一映射参考手册 et-build-commands.md 中把它们整理成了四组优先入口下一节逐一展开。唯一编译入口dotnet build ET.sln命令与适用前提dotnet build ET.sln这是 ET 项目唯一被认可的编译与分析器验证命令。技能文档反复强调不单独编译包或 IDE 私有方案原因在于 ET.sln 聚合了全部cn.etetet.*包的程序集项目如 loader 包的DotNet~/ET.Loader.csproj只有从解决方案级别构建包间依赖、源生成器注入与分析器检查才能在一个完整的编译图中生效。从源码看loader 包的工程文件 ET.Loader.csproj 声明了net10.0目标框架与ET.Loader程序集名并通过AppendTargetFrameworkToOutputPathfalse将产物直接输出到Bin/目录——这正是后续Bin/ET.App.dll、Bin/ET.Proto2CS.dll等命令能够直接以相对路径调用的基础。编译时被触发的分析器构建并非简单的语法编译。harness 包的DotNet~/SourceGenerator/目录中存放着多款 Roslyn 分析器它们在dotnet build ET.sln时随编译运行用于在 CI/Agent 场景下即时校验架构约束例如AwaitEntityAnalyzer.cs检查async/await/ETTask用法是否符合 ET 异步规范DiableNewAnalyzer.cs禁止用new直接创建本应由对象池/工厂管理的对象并受AnalyzerGlobalSetting.EnableAnalyzer开关控制DisableSingletonInstanceAccessAnalyzer.cs阻止绕过框架直接访问单例实例分析范围限定在AnalyzeAssembly.AllModelHotfix对应的 Model / Hotfix 程序集NamespaceAnalyzer.cs、NetMessageAnalyzer.cs、MessageObjectReferenceAnalyzer.cs、TestCaseNamingAnalyzer.cs 等分别约束命名空间、网络消息、MessageObject 引用与测试命名。这也是分析器结果异常时先确认是否单独编译了某个包这一排查项的根源一旦绕过 ET.sln 单独编译分析器集合不完整报错或漏报都会失真。Proto 导出ET.Proto2CS.dll命令dotnet ./Bin/ET.Proto2CS.dll该命令把各包Proto/目录下的.proto消息定义批量转换为 C# 代码。技能文档给出的关键约束有三条全部能在源码中找到对应实现入口 Program.cs核心逻辑 Proto2CS.cs生成文件落在 proto 包中代码写死输出目录为Packages/cn.etetet.proto/CodeMode/Model/下的Client、Server、ClientServer三个子目录对应 Proto2CS.cs 中的clientMessagePath/serverMessagePath/clientServerMessagePath并在导出前先清理这些目录里的旧.cs文件CleanGeneratedFiles。Proto 文件名带的编号必须唯一通常是 100 的倍数导出器要求.proto文件名遵循名字_类型_起始Opcode.proto的约定——例如 Login_C_10000.proto 表示 Login 包、Client 侧_C_、起始 Opcode 10000Login_S_20000.proto 对应 Server 侧_S_。代码通过fileName.Split(_)拆出protoName、csClient/Server/ClientServer与startOpcode三个段每条message声明会让 opcode 自增msgOpcode.Add(..., Opcode startOpcode)因此编号必须全局唯一且通常取 100 的倍数为后续增量预留空间。生成结果会被写入Opcode枚举与[Message(Opcode.xxx)]特性。导出后必要时用git diff --stat确认生成范围因为导出会先清空目标目录再全量重写用 git diff 可以快速核对本次改动是否超出预期例如误改了某个 proto 导致大面积重生成。导出流程的源码视角Program.cs 展示了完整链路读取项目根目录下的MainPackage.txt若不存在或为空则跳过导出并打印提示把其中列出的包名集合传给Proto2CS.Export(packages)Proto2CS.cs 扫描Packages/下所有cn.etetet.*包过滤出目标包收集其Proto/*.proto文件对每个 proto 文件逐行解析注释///会转成 XML 文档注释message声明会生成带[MemoryPackable]、[Message(Opcode.X)]、[ResponseType(...)]特性的partial class继承MessageObject并自动补出Create工厂方法与Dispose回收逻辑除非标注// no dispose最后打印Generated N proto files.。可以看到导出不仅是文本翻译还涉及 Opcode 分配、对象池接入、MemoryPack 序列化标记等 ET 运行时约定因此用 IDE 手工改生成代码是严格禁止的——一切以重新执行导出为准。服务器启动ET.App.dll命令Remove-Item ./Logs -Recurse -Force -ErrorAction SilentlyContinue dotnet ./Bin/ET.App.dll --Console1两行命令配套使用先清理旧日志再以控制台模式启动服务器。技能文档给出的启动前提包括需要管理员权限ET.App 启动时涉及端口绑定监听 RPC / 网关等端口等敏感操作必须在 Unity 项目根目录执行不在Bin/下执行这与参考手册当前工作目录应位于 Unity 项目根目录的原则一致因为运行时会按相对路径加载Packages/、Config/、Logs/等资源启动前清理旧Logs/避免新旧日志混淆方便确认启动是否真正成功。--Console1以控制台模式运行日志直接输出到终端同时框架也会落盘到Logs/目录这也是找不到日志时确认Logs/是否生成最新文件这一排查项的由来。发布Publish.ps1命令pwsh -ExecutionPolicy Bypass -File ./Scripts/Publish.ps1发布入口统一为 Publish.ps1。技能文档要求发布前先完成必要编译、配置导出与测试验证即发布是构建链路的最后一步而不是替代编译的手段。注意技能文档与参考手册都强调所有命令必须使用pwshPowerShell 7不要使用 Windows 自带的powershell.exe这一约定同时写在技能索引 index.md 中-ExecutionPolicy Bypass用于规避脚本执行策略限制。发布脚本做了什么以 Publish.ps1 为例发布流程本质上是编译 目录组装dotnet publish ET.sln -r linux-x64 --framework net10.0 --no-self-contained --no-dependencies -c Debug针对 linux-x64 运行时发布解决方案产物输出到Bin/linux-x64/publish/清空并重建Publish/Bin/把发布产物整体搬入拷贝运行期资源到发布目录的约定位置loader 包的NLog.config日志配置→Publish/Packages/cn.etetet.loader/CodeMode/Loader/Server/Bson资源 →Publish/Packages/cn.etetet.wow/Bundles/Bson/服务端 Luban 配置 →Publish/Packages/cn.etetet.config/Bundles/Luban/Config/Server/发布用 StartConfig →Publish/Packages/cn.etetet.startconfig/Bundles/Luban/Release/可见发布产物是一个自包含的目录树Publish/Bin/存放服务器程序集Publish/Packages/下按包路径摆放配置文件。这也解释了为什么服务器要求在项目根目录启动——运行时对Packages/下配置路径的引用是相对项目根目录的。常见问题排查速查表参考手册 et-build-commands.md 给出了五个高频问题的标准排查路径现象排查方向编译报错确认使用的是dotnet build ET.sln而不是局部方案或 IDE 编译分析器结果异常确认没有单独编译某个包、没用 IDE 私有编译分析器只在 ET.sln 完整构建时全量生效NuGet 还原失败检查网络与代理设置服务器启动失败依次检查管理员权限、运行目录是否为 Unity 项目根目录、端口是否被占用找不到日志确认Logs/目录是否生成了最新文件启动前清理旧日志会清空该目录与其他技能的协作边界et-build在 harness 技能体系中不是孤立入口索引 index.md 定义了清晰的协作关系Luban 配置导出走et-luban技能文档 et-luban/SKILL.md不要在et-build中处理测试执行与排查走et-test-run并以 cn.etetet.test/AGENTS.md 为路由依据改代码、写测试等尚未到编译环节的任务不加载本技能典型完整链路为开发et-code/et-async→ 测试et-tdd→ 构建et-build→ 提交et-gitet-build承担其中编译 / Proto / 运行 / 发布的纯构建职责。这种按场景加载、按需补读的设计让 Agent 在编译、导出、启动、发布等任务上始终走统一入口避免出现局部编译、错误目录启动、手工拼长命令等偏离项目规范的执行方式。小结et-build把 ET 项目的四条关键构建动作收敛为四个标准入口dotnet build ET.sln编译 分析器验证、dotnet ./Bin/ET.Proto2CS.dllProto 导出、dotnet ./Bin/ET.App.dll --Console1服务器启动、pwsh -ExecutionPolicy Bypass -File ./Scripts/Publish.ps1发布。它们共同依赖两条底层约束统一从 Unity 项目根目录以 ET.sln 为唯一构建图执行、生成的程序集与代码全部遵循项目的目录与 Opcode 约定。理解这些约束就能在遇到编译、分析器、启动或日志问题时快速定位到技能文档给出的标准排查路径。【免费下载链接】ETUnity3D Client And C# Server Framework项目地址: https://gitcode.com/GitHub_Trending/et/ET创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考