Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ModPermChecker v1.0.0
ModPermChecker.dll
Decompiled 16 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("YourName")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Custom Mod Permission Checker for Valheim")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ModPermChecker")] [assembly: AssemblyTitle("ModPermChecker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ModPermChecker { [BepInPlugin("com.custom.modpermchecker", "ModPermChecker", "1.0.0")] public class ModPermCheckerPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Game), "Awake")] public static class GameAwake_Patch { public static void Postfix() { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<ZPackage>("RPC_VerifyClientMods", (Action<long, ZPackage>)RPC_VerifyClientMods); } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] public static class ClientSendMods_Patch { public static void Postfix(ZNet __instance, ZRpc rpc) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown if (__instance.IsServer()) { return; } List<string> list = Chainloader.PluginInfos.Keys.ToList(); ZPackage val = new ZPackage(); val.Write(list.Count); foreach (string item in list) { val.Write(item); } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RPC_VerifyClientMods", new object[1] { val }); } } [Serializable] public class ConfigModel { public List<string> SpecialMods = new List<string>(); public List<UserPermission> Permissions = new List<UserPermission>(); } [Serializable] public class UserPermission { public string SteamID; public List<string> AllowedMods = new List<string>(); } public const string ModGUID = "com.custom.modpermchecker"; public const string ModName = "ModPermChecker"; public const string ModVersion = "1.0.0"; internal static ManualLogSource ModLogger; private static readonly string ConfigPath = Path.Combine(Paths.ConfigPath, "CustomModPermissions.json"); private static ConfigModel serverConfig; private static readonly Dictionary<string, HashSet<string>> AllowedPermissions = new Dictionary<string, HashSet<string>>(); private static readonly HashSet<string> RestrictedMods = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) ModLogger = ((BaseUnityPlugin)this).Logger; new Harmony("com.custom.modpermchecker").PatchAll(); LoadPermissionsConfig(); ModLogger.LogInfo((object)"ModPermChecker v1.0.0 載入完成!"); } public static void LoadPermissionsConfig() { if (!File.Exists(ConfigPath)) { CreateDefaultConfig(); } try { serverConfig = JsonUtility.FromJson<ConfigModel>(File.ReadAllText(ConfigPath)); RestrictedMods.Clear(); AllowedPermissions.Clear(); if (serverConfig != null) { if (serverConfig.SpecialMods != null) { foreach (string specialMod in serverConfig.SpecialMods) { RestrictedMods.Add(specialMod.Trim()); } } if (serverConfig.Permissions != null) { foreach (UserPermission permission in serverConfig.Permissions) { string key = permission.SteamID.Trim(); if (!AllowedPermissions.ContainsKey(key)) { AllowedPermissions[key] = new HashSet<string>(StringComparer.OrdinalIgnoreCase); } if (permission.AllowedMods == null) { continue; } foreach (string allowedMod in permission.AllowedMods) { AllowedPermissions[key].Add(allowedMod.Trim()); } } } } ManualLogSource modLogger = ModLogger; if (modLogger != null) { modLogger.LogInfo((object)$"成功載入受限模組: {RestrictedMods.Count} 個, 授權使用者: {AllowedPermissions.Count} 位。"); } } catch (Exception ex) { ManualLogSource modLogger2 = ModLogger; if (modLogger2 != null) { modLogger2.LogError((object)("解析 CustomModPermissions.json 失敗: " + ex.Message)); } } } private static void CreateDefaultConfig() { string contents = JsonUtility.ToJson((object)new ConfigModel { SpecialMods = new List<string> { "com.author.infinityhammer", "com.author.worldeditcommands" }, Permissions = new List<UserPermission> { new UserPermission { SteamID = "76561198000000000", AllowedMods = new List<string> { "com.author.infinityhammer", "com.author.worldeditcommands" } } } }, true); File.WriteAllText(ConfigPath, contents); } private static void RPC_VerifyClientMods(long sender, ZPackage pkg) { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } ZNetPeer peer = ZNet.instance.GetPeer(sender); if (peer == null) { return; } string hostName = peer.m_socket.GetHostName(); int num = pkg.ReadInt(); List<string> list = new List<string>(); for (int i = 0; i < num; i++) { list.Add(pkg.ReadString()); } foreach (string item in list) { if (RestrictedMods.Contains(item) && (!AllowedPermissions.ContainsKey(hostName) || !AllowedPermissions[hostName].Contains(item))) { ManualLogSource modLogger = ModLogger; if (modLogger != null) { modLogger.LogWarning((object)("玩家 " + hostName + " 未獲授權安裝受限模組: [" + item + "],已強制斷開連線!")); } peer.m_rpc.Invoke("Error", new object[1] { 8 }); ZNet.instance.Disconnect(peer); return; } } ManualLogSource modLogger2 = ModLogger; if (modLogger2 != null) { modLogger2.LogInfo((object)("玩家 " + hostName + " 模組權限驗證通過。")); } } } }