Initial commit: Client Doc docs Server Tools

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ud18010
2026-07-10 10:24:29 +08:00
co-authored by Cursor
commit 7e35d8da31
3374 changed files with 680813 additions and 0 deletions
@@ -0,0 +1,59 @@
using System;
using System.IO;
using Xunit;
using XWorld.Server.Host;
namespace XWorld.Server.Host.Tests
{
// 字节加载去锁:模块加载期间磁盘 DLL 可被覆盖/删除(同版本覆盖重发的前提)
public class ModuleFileLockTests
{
// 把共享只读夹具 rps/1 拷到独立临时 gamesRoot(不许改 TestGames.Root 原件)
private static string CopyRps1ToTempRoot()
{
string root = Path.Combine(Path.GetTempPath(), "games_" + Guid.NewGuid().ToString("N"));
string dst = Path.Combine(root, "rps", "1");
Directory.CreateDirectory(dst);
string src = Path.Combine(TestGames.Root, "rps", "1");
foreach (var f in Directory.GetFiles(src))
File.Copy(f, Path.Combine(dst, Path.GetFileName(f)));
return root;
}
[Fact]
public void LoadedModule_DoesNotLockDlls_OverwriteAndDeleteSucceed()
{
string root = CopyRps1ToTempRoot();
var module = new GameModuleLoader().Load(root, "rps", 1);
try
{
// 先构造一次房间:RpsServerRoom 字段初始化器 new RpsLogic() 触发 RPS.Core
// 首次解析、经 GameModuleAlc 字节加载进本 ALC —— 此后两个 DLL 的 IL 都在内存。
// (不先触发的话,"删 Core 后 CreateRoom 成功"会被测试工程对 RPS.Core 的
// ProjectReference 经默认上下文回退兜住,测不到被测代码。)
Assert.NotNull(module.CreateRoom());
string serverDll = Path.Combine(root, "rps", "1", "RPS.Server.dll");
string coreDll = Path.Combine(root, "rps", "1", "RPS.Core.dll");
// 加载期间覆盖写入 —— LoadFromAssemblyPath 会锁文件抛 IOException,字节加载应成功
byte[] original = File.ReadAllBytes(serverDll);
File.WriteAllBytes(serverDll, original);
// 加载期间删除(两个都删:IL 已在内存,源文件不再被需要也不被锁定)
File.Delete(coreDll);
File.Delete(serverDll);
Assert.False(File.Exists(coreDll));
Assert.False(File.Exists(serverDll));
// 模块本体仍可用
Assert.NotNull(module.CreateRoom());
}
finally
{
module.Unload();
try { Directory.Delete(root, true); } catch { }
}
}
}
}