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
+49
View File
@@ -0,0 +1,49 @@
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
namespace XWorld.Server.Host
{
// 可卸载上下文:框架契约走默认上下文(类型标识跨界一致),小游戏私有 DLL 载入本上下文。
// DLL 一律字节加载(LoadFromStream):不持有文件句柄,同版本覆盖重发不被文件锁挡住。
// 代价:字节加载的 Assembly.Location 为空——小游戏 DLL 不得依赖它。
internal sealed class GameModuleAlc : AssemblyLoadContext
{
private readonly string _moduleDir;
public GameModuleAlc(string name, string moduleDir) : base(name, isCollectible: true)
{
_moduleDir = moduleDir;
}
protected override Assembly Load(AssemblyName assemblyName)
{
// 设计 §4.2:框架契约类型必须在默认 ALC,不随小游戏卸载。
// 约束:XWorld.Framework.Shared 只能依赖 BCLSystem.*);若将来加第三方依赖,需同步扩展下面白名单。
if (assemblyName.Name == "XWorld.Framework.Shared")
return null;
// BCL / 运行时程序集始终走默认上下文,防止游戏目录里同名文件遮蔽(类型标识错乱)
string n = assemblyName.Name;
if (n != null && (n.StartsWith("System.", System.StringComparison.Ordinal) ||
n.StartsWith("Microsoft.", System.StringComparison.Ordinal) ||
n == "System" || n == "netstandard" || n == "mscorlib"))
return null;
// 小游戏私有程序集放在版本目录里,载入本可卸载上下文
string candidate = Path.Combine(_moduleDir, assemblyName.Name + ".dll");
if (File.Exists(candidate))
return LoadBytes(candidate);
return null; // 其余交默认上下文
}
public Assembly LoadEntry(string serverDllPath) => LoadBytes(serverDllPath);
private Assembly LoadBytes(string path)
{
using (var ms = new MemoryStream(File.ReadAllBytes(path)))
return LoadFromStream(ms);
}
}
}