Decompiled source of ModPermChecker v1.0.0

ModPermChecker.dll

Decompiled 16 hours ago
using 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 + " 模組權限驗證通過。"));
			}
		}
	}
}