using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace REPOModManager; [BepInPlugin("com.dsh.repo.modmanager", "模组禁用", "1.0.0")] public class ModManagerPlugin : BaseUnityPlugin { public class ModEntry { public string FullPath; public string DisplayName; public bool Enabled; } public class ToggleBinding { public ConfigEntry entry; public ModEntry mod; } private static ModManagerPlugin instance; private bool showWindow = false; private ConfigEntry toggleKey; private string pluginsDir; private List mods = new List(); private List bindings = new List(); private bool applyingValue = false; private Vector2 scroll = Vector2.zero; private string statusText = ""; private static readonly string SelfDll = "REPO_ModManager.dll"; private void Awake() { instance = this; toggleKey = ((BaseUnityPlugin)this).Config.Bind("热键 Hotkeys", "打开管理器按键 ToggleKey", 291, "打开/关闭MOD禁用窗口的按键(Unity KeyCode 数值,默认 F10=291)"); pluginsDir = Paths.PluginPath; RefreshList(); BuildToggleEntries(); ReconcileEntryValues(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"模组禁用 v1.0.0 已加载。在 REPOConfig 的【模组 Mods】菜单展开本MOD即可开关每个插件(重启游戏生效);按 F10 可打开独立窗口"); } private void BuildToggleEntries() { foreach (ModEntry mod in mods) { ToggleBinding b = new ToggleBinding(); b.mod = mod; b.entry = BindToggle(mod); b.entry.SettingChanged += delegate { OnToggleChanged(b); }; bindings.Add(b); } } private ConfigEntry BindToggle(ModEntry m) { return ((BaseUnityPlugin)this).Config.Bind("插件开关", SanitizeKey(m.DisplayName), m.Enabled, "打开=启用,关闭=禁用。重启游戏后生效。"); } private void OnToggleChanged(ToggleBinding b) { if (!applyingValue) { bool value = b.entry.Value; if (value != b.mod.Enabled) { Toggle(b.mod); SyncEntries(); } } } private void SyncEntries() { applyingValue = true; try { foreach (ToggleBinding binding in bindings) { binding.entry.Value = binding.mod.Enabled; } } catch { } applyingValue = false; } private void ReconcileEntryValues() { SyncEntries(); } private static string SanitizeKey(string s) { string text = ""; foreach (char c in s) { text = ((c != '\\' && c != '=' && c != '\n' && c != '\t' && c != '"' && c != '\'' && c != '[' && c != ']') ? (text + c) : (text + "/")); } return text; } private void Update() { try { if (Input.GetKeyDown((KeyCode)toggleKey.Value)) { showWindow = !showWindow; if (showWindow) { RefreshList(); } } } catch { } } private void SetStatus(string msg) { statusText = msg; } private void RefreshList() { mods.Clear(); if (!Directory.Exists(pluginsDir)) { return; } string[] files = Directory.GetFiles(pluginsDir, "*.dll", SearchOption.AllDirectories); string[] array = files; foreach (string text in array) { if (!string.Equals(Path.GetFileName(text), SelfDll, StringComparison.OrdinalIgnoreCase)) { mods.Add(new ModEntry { FullPath = text, DisplayName = Rel(text), Enabled = true }); } } string[] files2 = Directory.GetFiles(pluginsDir, "*.disabled", SearchOption.AllDirectories); array = files2; foreach (string text2 in array) { mods.Add(new ModEntry { FullPath = text2, DisplayName = Rel(text2), Enabled = false }); } mods.Sort((ModEntry a, ModEntry b) => string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase)); } private string Rel(string path) { string text = path.Substring(pluginsDir.Length); return text.TrimStart('\\', '/'); } private void Toggle(ModEntry m) { try { if (m.Enabled) { string text = m.FullPath + ".disabled"; File.Move(m.FullPath, text); m.FullPath = text; m.Enabled = false; SetStatus("已禁用: " + m.DisplayName + "(重启游戏后生效)"); } else { string text = m.FullPath.Substring(0, m.FullPath.Length - 9); File.Move(m.FullPath, text); m.FullPath = text; m.Enabled = true; SetStatus("已启用: " + m.DisplayName + "(重启游戏后生效)"); } } catch (Exception ex) { SetStatus("操作失败: " + m.DisplayName + " - " + ex.Message); } } private int EnableAll() { int num = 0; foreach (ModEntry mod in mods) { if (!mod.Enabled) { Toggle(mod); num++; } } return num; } private int DisableAll() { int num = 0; foreach (ModEntry mod in mods) { if (mod.Enabled) { Toggle(mod); num++; } } return num; } private void OnGUI() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) if (!showWindow) { return; } GUI.Box(new Rect(10f, 10f, 580f, 640f), "模组禁用(按 F10 关闭)"); GUI.Label(new Rect(25f, 38f, 550f, 20f), "禁用/启用后需重启游戏才会生效。也可以在 REPOConfig 的【模组 Mods】菜单里开关。请勿禁用前置库(如 REPOLib前置库、自动翻译器 等)。"); if (GUI.Button(new Rect(25f, 62f, 110f, 26f), "刷新列表")) { RefreshList(); SetStatus("列表已刷新"); } if (GUI.Button(new Rect(145f, 62f, 110f, 26f), "全部启用")) { int num = EnableAll(); SyncEntries(); SetStatus("已尝试启用 " + num + " 个MOD(重启后生效)"); } if (GUI.Button(new Rect(265f, 62f, 110f, 26f), "全部禁用")) { int num2 = DisableAll(); SyncEntries(); SetStatus("已尝试禁用 " + num2 + " 个MOD(重启后生效)"); } GUI.Label(new Rect(385f, 66f, 200f, 20f), "共 " + mods.Count + " 个插件"); scroll = GUI.BeginScrollView(new Rect(25f, 96f, 550f, 460f), scroll, new Rect(0f, 0f, 530f, (float)(mods.Count * 26 + 6))); int num3 = 0; foreach (ModEntry mod in mods) { string text = (mod.Enabled ? "[开] " : "[关] ") + mod.DisplayName; GUI.Label(new Rect(4f, (float)(num3 * 26), 400f, 22f), text); if (GUI.Button(new Rect(410f, (float)(num3 * 26), 110f, 22f), mod.Enabled ? "禁用" : "启用")) { Toggle(mod); SyncEntries(); } num3++; } GUI.EndScrollView(); GUI.Label(new Rect(25f, 568f, 550f, 60f), statusText); } }