imnyang/BlockModLoader
Archived
Watch
2
0
Fork
You've already forked BlockModLoader
0
This repository has been archived on 2026-10-08. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
BlockModLoader/LoaderGuard.cs

88 lines
3.6 KiB
C#

// SPDX-License-Identifier: GPL-3.0-only
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
namespace BlockModLoader
{
[Flags]
public enum WhiteListLoader
{
None = 0,
MelonLoader = 1,
BepInEx = 2,
UMM = 4,
All = MelonLoader | BepInEx | UMM
}
public static class LoaderGuard
{
public static void EnsureAllowed(string modName)
{
EnsureAllowed(modName, null);
}
public static void EnsureAllowed(string modName, string recommendedLoader)
{
EnsureAllowed(modName, WhiteListLoader.None, recommendedLoader);
}
public static void EnsureAllowed(string modName, WhiteListLoader whiteListLoader,
string recommendedLoader = null)
{
EnsureAllowed(modName, AppDomain.CurrentDomain.GetAssemblies(), ShowAlert, Environment.FailFast,
recommendedLoader, whiteListLoader);
}
internal static void EnsureAllowed(string modName, IEnumerable<Assembly> assemblies,
Action<string> showAlert, Action<string> terminate, string recommendedLoader = null,
WhiteListLoader whiteListLoader = WhiteListLoader.None)
{
if ((whiteListLoader & ~WhiteListLoader.All) != 0)
throw new ArgumentOutOfRangeException(nameof(whiteListLoader));
foreach (var assembly in assemblies)
{
var loader = GetLoader(assembly.GetName().Name);
if (loader == WhiteListLoader.None || (whiteListLoader & loader) != 0)
continue;
var loaderName = loader == WhiteListLoader.UMM ? "Unity Mod Manager (UMM)" : loader.ToString();
var message = modName + " cannot run while " + loaderName + " is active.\n\n"
+ "Remove the unsupported mod loader and follow this mod's installation instructions.\n\n"
+ (string.IsNullOrWhiteSpace(recommendedLoader)
? string.Empty
: "Recommended mod loader: " + recommendedLoader.Trim() + ".\n\n")
+ "The game will close after this message.";
// Loader exception handlers can swallow a thrown exception, so termination
// must happen even if the native dialog fails.
try { showAlert(message); }
finally { terminate(message); }
return;
}
}
private static WhiteListLoader GetLoader(string assemblyName)
{
if (string.Equals(assemblyName, "MelonLoader", StringComparison.OrdinalIgnoreCase))
return WhiteListLoader.MelonLoader;
if (string.Equals(assemblyName, "BepInEx", StringComparison.OrdinalIgnoreCase)
|| string.Equals(assemblyName, "BepInEx.Core", StringComparison.OrdinalIgnoreCase))
return WhiteListLoader.BepInEx;
if (string.Equals(assemblyName, "UnityModManager", StringComparison.OrdinalIgnoreCase))
return WhiteListLoader.UMM;
return WhiteListLoader.None;
}
private static void ShowAlert(string message)
{
Console.Error.WriteLine(message);
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
MessageBoxW(IntPtr.Zero, message, "Unsupported mod loader", 0x10 | 0x10000);
}
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern int MessageBoxW(IntPtr window, string text, string caption, uint type);
}
}