diff --git a/README.md b/README.md index 2cb08dd..c4b6199 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,117 @@ -# 실제 적용 계획이 없습니다. -# 제가 공개적으로 배포하는 모드에 이를 적용하는 일이 일어날 일이 없습니다. \ No newline at end of file +# BlockModLoader + +A .NET Framework 4.8 library with no Unity or mod loader dependency. +Call `BlockModLoader.LoaderGuard.EnsureAllowed("YourMod")` before initializing +a mod or game integration. Building this library does not require a game installation. + +By default, the guard blocks any of these loaded assemblies in the current AppDomain +(exact names, case-insensitive): + +| Loader | Assembly names | +| --- | --- | +| MelonLoader | `MelonLoader` | +| BepInEx | `BepInEx`, `BepInEx.Core` | +| Unity Mod Manager (UMM) | `UnityModManager` | + +The BepInEx assembly names follow the [BepInEx 5 API](https://docs.bepinex.dev/api/index.html) +and [BepInEx 6 API](https://docs.bepinex.dev/master/api/index.html); UMM uses +[`UnityModManager`](https://github.com/newman55/unity-mod-manager/blob/master/UnityModManager/UnityModManager.csproj). + +When a non-whitelisted supported loader is detected, the guard names it in a Windows error +dialog and calls `Environment.FailFast` after dismissal, terminating the entire +game process. Termination also happens if showing the dialog fails. On other +platforms the message is written to standard error before termination. +When multiple loaders are present, the first detected non-whitelisted loader triggers +one dialog and termination. Without a whitelist, all three loaders are blocked. + +The guard checks only assemblies already loaded when `EnsureAllowed` is called. +It does not inspect installation folders, modify loader files, or monitor later +assembly loads. Names such as `MelonLoader.Helper` or `BepInEx.Helper` are not +matched. Renamed or modified loader binaries can bypass the check. + +This is an initialization guard. Merely placing its DLL in a game or loader +folder will not invoke it: the consuming mod or game must call `EnsureAllowed`. + +## Allowed loaders + +Use `WhiteListLoader` to allow selected loaders for each guard call: + +```csharp +using BlockModLoader; + +// Allow BepInEx; block MelonLoader and UMM. +LoaderGuard.EnsureAllowed("YourMod", whiteListLoader: WhiteListLoader.BepInEx, + recommendedLoader: "BepInEx"); + +// Allow both BepInEx and UMM; block MelonLoader. +LoaderGuard.EnsureAllowed("YourMod", WhiteListLoader.BepInEx | WhiteListLoader.UMM); +``` + +Available values are `None`, `MelonLoader`, `BepInEx`, `UMM`, and `All`. +Combine values with `|`. `None` (the default for existing calls) blocks all three; +`All` allows all three. `BepInEx` allows both `BepInEx` and `BepInEx.Core`. +An allowed loader does not prevent detection of another blocked loader in the +same AppDomain. Unknown flag values throw `ArgumentOutOfRangeException`. +The whitelist applies only to these three known loaders; other assemblies are +still ignored. Each call supplies its own whitelist, with no shared global setting. + +## Recommended loader in the alert + +Pass an optional display name as the second argument to include a recommendation +in the alert: + +```csharp +BlockModLoader.LoaderGuard.EnsureAllowed("YourMod", recommendedLoader: "YourPreferredLoader"); +``` + +The alert adds `Recommended mod loader: YourPreferredLoader.` before the game +closure notice. Omit the second argument, or pass null, an empty string, or +whitespace, to keep the original generic guidance. Leading and trailing +whitespace is trimmed. This setting changes only the alert text; it does not +allow the recommended loader or change which loaders are blocked. + +## Migration from BlockMelonLoader + +Replace the `BlockMelonLoader` package reference with `BlockModLoader` version +`1.0.0`, update imports to `using BlockModLoader;`, and ship `BlockModLoader.dll` +alongside your mod DLL. NuGet copies the runtime asset to the consuming project's +build output. The `LoaderGuard.EnsureAllowed("YourMod")` method remains the same, +but now blocks BepInEx and UMM as well as MelonLoader. + +## Build and test + +On Windows, run `./build.ps1 -Test`. Visual Studio or Rider MSBuild is required; +use `-MSBuildPath` to select it explicitly. The script downloads .NET Framework +4.8 reference assemblies into the ignored `packages` folder when needed. +The DLL is written to `bin/Release/BlockModLoader.dll` and the NuGet package to +`artifacts/BlockModLoader.1.0.0.nupkg`. Packaging uses `NuGet.Build.Tasks.Pack`. + +The standalone tests check every loader name, case-insensitive detection, +unrelated assemblies, multiple loaders, notification ordering, and dialog failure +handling, plus every whitelist combination and invalid flags. +They substitute the dialog and termination callbacks and do not crash +the game. Run them directly with `Tests/bin/Release/BlockModLoader.Tests.exe`. + +## Installation + +The NuGet feed for this project is: + +```text +https://git.mizuki.guru/api/packages/imnyang/nuget/index.json +``` + +After the new package has been published to that feed, add it to the consuming +project's `NuGet.Config`, then add the dependency: + +```xml + +``` + +For local development, build this repository and use the generated `.nupkg` in +a local NuGet feed. The source repository is not required when building a consumer. +New library versions must use a new package version and update the consumer's +dependency version. The source repository is https://git.mizuki.guru/imnyang/BlockModLoader. + +## License + +GNU General Public License version 3 only (`GPL-3.0-only`); see `LICENSE.md`.