using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ConsolePanel; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.U2D; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("AdminQoL")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("sighsorry")] [assembly: AssemblyProduct("AdminQoL")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyFileVersion("1.0.2")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 LocalizationManager { [PublicAPI] public class Localizer { private static readonly Dictionary>> PlaceholderProcessors; private static readonly Dictionary> loadedTexts; private static readonly ConditionalWeakTable localizationLanguage; private static readonly List> localizationObjects; private static BaseUnityPlugin? _plugin; private static readonly List fileExtensions; private static BaseUnityPlugin plugin { get { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown if (_plugin == null) { IEnumerable source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } public static event Action? OnLocalizationComplete; private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out string value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out Dictionary> value2)) { text = value2.Aggregate(text, (string current, KeyValuePair> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder(string key, string placeholder, ConfigEntry config, Func? convertConfigValue = null) where T : notnull { string key2 = key; string placeholder2 = placeholder; Func convertConfigValue2 = convertConfigValue; ConfigEntry config2 = config; if (convertConfigValue2 == null) { convertConfigValue2 = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key2)) { PlaceholderProcessors[key2] = new Dictionary>(); } config2.SettingChanged += delegate { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key2][placeholder2] = () => convertConfigValue2(config2.Value); UpdatePlaceholderText(Localization.instance, key2); } } public static void AddText(string key, string text) { List> list = new List>(); foreach (WeakReference localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference item in list) { localizationObjects.Remove(item); } } public static void Load() { _ = plugin; } public static void LoadLocalizationLater(Localization __instance) { LoadLocalization(Localization.instance, __instance.GetSelectedLanguage()); } public static void SafeCallLocalizeComplete() { Localizer.OnLocalizationComplete?.Invoke(); } private static void LoadLocalization(Localization __instance, string language) { if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference(__instance)); } localizationLanguage.Add(__instance, language); Dictionary dictionary = new Dictionary(); foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f) { string[] array = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' }); if (array.Length >= 2) { string text = array[1]; if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } } byte[] array2 = LoadTranslationFromAssembly("English"); if (array2 == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize>(Encoding.UTF8.GetString(array2)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text2 = null; if (language != "English") { if (dictionary.TryGetValue(language, out var value)) { text2 = File.ReadAllText(value); } else { byte[] array3 = LoadTranslationFromAssembly(language); if (array3 != null) { text2 = Encoding.UTF8.GetString(array3); } } } if (text2 == null && dictionary.TryGetValue("English", out var value2)) { text2 = File.ReadAllText(value2); } if (text2 != null) { foreach (KeyValuePair item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize>(text2) ?? new Dictionary()) { dictionary2[item2.Key] = item2.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair item3 in dictionary2) { UpdatePlaceholderText(__instance, item3.Key); } } static Localizer() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown PlaceholderProcessors = new Dictionary>>(); loadedTexts = new Dictionary>(); localizationLanguage = new ConditionalWeakTable(); localizationObjects = new List>(); fileExtensions = new List(2) { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static byte[]? LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null) { string resourceFileName2 = resourceFileName; using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName2, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } public static class LocalizationManagerVersion { public const string Version = "1.4.1"; } } namespace ConsolePanel { internal static class ConsoleCommandOwnership { [StructLayout(LayoutKind.Auto)] [CompilerGenerated] private struct <>c__DisplayClass21_0 { public HashSet aliases; } [CompilerGenerated] private sealed class d__21 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private PluginInfo pluginInfo; public PluginInfo <>3__pluginInfo; private HashSet.Enumerator <>7__wrap1; string IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__21(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = default(HashSet.Enumerator); <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <>c__DisplayClass21_0 <>c__DisplayClass21_ = default(<>c__DisplayClass21_0); <>c__DisplayClass21_.aliases = new HashSet(StringComparer.OrdinalIgnoreCase); g__AddAlias|21_0(pluginInfo.Metadata.Name, ref <>c__DisplayClass21_); g__AddAlias|21_0(pluginInfo.Metadata.GUID, ref <>c__DisplayClass21_); string location = pluginInfo.Location; if (!string.IsNullOrWhiteSpace(location)) { g__AddAlias|21_0(Path.GetFileNameWithoutExtension(location), ref <>c__DisplayClass21_); string fileName = Path.GetFileName(Path.GetDirectoryName(location) ?? ""); g__AddAlias|21_0(fileName, ref <>c__DisplayClass21_); if (!string.IsNullOrWhiteSpace(fileName)) { int num = fileName.IndexOf('-'); if (num >= 0 && num + 1 < fileName.Length) { g__AddAlias|21_0(fileName.Substring(num + 1), ref <>c__DisplayClass21_); } } } <>7__wrap1 = <>c__DisplayClass21_.aliases.GetEnumerator(); <>1__state = -3; break; } case 1: <>1__state = -3; break; } if (<>7__wrap1.MoveNext()) { string current = <>7__wrap1.Current; <>2__current = current; <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap1 = default(HashSet.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap1).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__21 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__21(0); } d__.pluginInfo = <>3__pluginInfo; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private static readonly Dictionary Owners = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly HashSet CommonAliasTokens = new HashSet(StringComparer.OrdinalIgnoreCase) { "a", "an", "and", "the", "mod", "mods", "plugin", "plugins", "valheim", "configuration", "config", "manager", "command", "commands", "data", "world", "expand", "json", "yaml", "dotnet", "detector" }; private static int _terminalInitDepth; internal static int Version { get; private set; } internal static void EnterTerminalInit() { _terminalInitDepth++; } internal static void ExitTerminalInit() { _terminalInitDepth = Mathf.Max(0, _terminalInitDepth - 1); } internal static void MarkDirty() { Version++; } internal static void Record(ConsoleCommand command) { if (command != null && !string.IsNullOrWhiteSpace(command.Command)) { string value = DetectOwner(command.Command); if (!string.IsNullOrWhiteSpace(value)) { Owners[command.Command] = value; } Version++; } } internal static string GetOwner(string commandName) { if (!string.IsNullOrWhiteSpace(commandName) && Owners.TryGetValue(commandName, out string value)) { return value; } return InferOwner(commandName); } private static string DetectOwner(string commandName) { string text = InferOwnerFromExplicitCommandName(commandName); if (!string.IsNullOrWhiteSpace(text)) { return text; } StackTrace stackTrace = new StackTrace(fNeedFileInfo: false); bool flag = _terminalInitDepth > 0; Assembly executingAssembly = Assembly.GetExecutingAssembly(); for (int i = 0; i < stackTrace.FrameCount; i++) { Assembly assembly = (stackTrace.GetFrame(i)?.GetMethod())?.DeclaringType?.Assembly; if (assembly == null) { continue; } string text2 = assembly.GetName().Name ?? ""; if (text2.Equals("assembly_valheim", StringComparison.OrdinalIgnoreCase)) { flag = true; } else if ((object)assembly != executingAssembly && !ShouldSkipAssembly(text2)) { string text3 = TryFindPluginName(assembly); if (string.IsNullOrWhiteSpace(text3)) { return text2; } if (!ShouldSkipOwner(text3)) { return text3; } } } string text4 = InferOwner(commandName); if (!string.Equals(text4, "Other Mods", StringComparison.OrdinalIgnoreCase)) { return text4; } if (!flag) { return text4; } return "Valheim"; } private static bool ShouldSkipAssembly(string assemblyName) { if (string.IsNullOrWhiteSpace(assemblyName)) { return true; } switch (assemblyName.ToLowerInvariant()) { case "0harmony": case "mscorlib": case "jotunn": case "system": case "system.core": case "unityengine": case "bepinex": case "unityengine.coremodule": return true; default: return false; } } private static bool ShouldSkipOwner(string owner) { string text = NormalizeIdentifier(owner); if (text == "jotunn" || text == "valheimmoddingjotunn") { return true; } return false; } private static string? TryFindPluginName(Assembly assembly) { string text = SafeLocation(assembly); foreach (PluginInfo value in Chainloader.PluginInfos.Values) { BaseUnityPlugin instance = value.Instance; if ((Object)(object)instance != (Object)null && (object)((object)instance).GetType().Assembly == assembly) { return value.Metadata.Name; } if (!string.IsNullOrWhiteSpace(text) && string.Equals(SafePath(value.Location), text, StringComparison.OrdinalIgnoreCase)) { return value.Metadata.Name; } } return null; } private static string InferOwner(string commandName) { string text = commandName?.Trim().ToLowerInvariant() ?? ""; if (text.Length == 0) { return "Other Mods"; } string text2 = InferOwnerFromExplicitCommandName(text); if (!string.IsNullOrWhiteSpace(text2)) { return text2; } string text3 = InferOwnerFromLoadedPlugins(text); if (!string.IsNullOrWhiteSpace(text3)) { return text3; } return "Other Mods"; } private static string? InferOwnerFromExplicitCommandName(string? commandName) { string text = commandName?.Trim().ToLowerInvariant() ?? ""; if (text.Length == 0) { return null; } if (text.StartsWith("adminqol_", StringComparison.OrdinalIgnoreCase)) { return "AdminQoL"; } if (text.StartsWith("dns:", StringComparison.OrdinalIgnoreCase) || text.StartsWith("dns_", StringComparison.OrdinalIgnoreCase)) { return "DropNSpawn"; } if (text.StartsWith("jewelcrafting", StringComparison.OrdinalIgnoreCase)) { return "Jewelcrafting"; } if (text.StartsWith("epicloot", StringComparison.OrdinalIgnoreCase) || text.StartsWith("magic", StringComparison.OrdinalIgnoreCase)) { return "Epic Loot"; } if (text.StartsWith("vnei_", StringComparison.OrdinalIgnoreCase)) { return "VNEI"; } if (text.StartsWith("esp_", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "esp", StringComparison.OrdinalIgnoreCase)) { return "ESP"; } if (text.StartsWith("ew_mus", StringComparison.OrdinalIgnoreCase) || text.StartsWith("ew_music", StringComparison.OrdinalIgnoreCase)) { return "Expand World Music"; } if (text.StartsWith("ew_event", StringComparison.OrdinalIgnoreCase) || text.StartsWith("expand_events", StringComparison.OrdinalIgnoreCase)) { return "Expand World Events"; } if (text.StartsWith("ew_faction", StringComparison.OrdinalIgnoreCase) || text.StartsWith("expand_factions", StringComparison.OrdinalIgnoreCase)) { return "Expand World Factions"; } if (text.StartsWith("ew_", StringComparison.OrdinalIgnoreCase) || text.StartsWith("expand_", StringComparison.OrdinalIgnoreCase)) { return "Expand World Data"; } if (text.StartsWith("hammer_", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "hammer", StringComparison.OrdinalIgnoreCase)) { return "Infinity Hammer"; } if (text.StartsWith("world_edit", StringComparison.OrdinalIgnoreCase)) { return "World Edit Commands"; } if (text.StartsWith("xray", StringComparison.OrdinalIgnoreCase)) { return "XRayVision"; } return null; } private static string? InferOwnerFromLoadedPlugins(string commandName) { string text = commandName?.Trim().ToLowerInvariant() ?? ""; if (text.Length == 0) { return null; } string normalizedCommand = NormalizeIdentifier(text); string result = null; int num = 0; foreach (PluginInfo value in Chainloader.PluginInfos.Values) { if (ShouldSkipOwner(value.Metadata.Name)) { continue; } foreach (string pluginAlias in GetPluginAliases(value)) { if (pluginAlias.Length > num && CommandStartsWithAlias(text, normalizedCommand, pluginAlias)) { result = value.Metadata.Name; num = pluginAlias.Length; } } } return result; } private static bool CommandStartsWithAlias(string command, string normalizedCommand, string alias) { if (command.StartsWith(alias, StringComparison.OrdinalIgnoreCase)) { if (command.Length != alias.Length) { return IsAliasBoundary(command[alias.Length]); } return true; } return normalizedCommand.StartsWith(alias, StringComparison.OrdinalIgnoreCase); } private static bool IsAliasBoundary(char value) { switch (value) { case ' ': case '-': case '.': case ':': case '_': return true; default: return false; } } [IteratorStateMachine(typeof(d__21))] private static IEnumerable GetPluginAliases(PluginInfo pluginInfo) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__21(-2) { <>3__pluginInfo = pluginInfo }; } private static IEnumerable SplitIdentifierTokens(string value) { return value.Replace('.', ' ').Replace('_', ' ').Replace('-', ' ') .Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); } private static string NormalizeIdentifier(string value) { if (string.IsNullOrWhiteSpace(value)) { return ""; } return new string(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray()); } private static string SafeLocation(Assembly assembly) { try { return SafePath(assembly.Location); } catch { return ""; } } private static string SafePath(string path) { try { return string.IsNullOrWhiteSpace(path) ? "" : Path.GetFullPath(path); } catch { return path ?? ""; } } [CompilerGenerated] internal static void g__AddAlias|21_0(string? raw, ref <>c__DisplayClass21_0 P_1) { if (string.IsNullOrWhiteSpace(raw)) { return; } string text = NormalizeIdentifier(raw); if (text.Length >= 3 && !CommonAliasTokens.Contains(text)) { P_1.aliases.Add(text); } List list = (from token in SplitIdentifierTokens(raw).Select(NormalizeIdentifier) where token.Length >= 3 && !CommonAliasTokens.Contains(token) select token).ToList(); foreach (string item in list) { P_1.aliases.Add(item); } string text2 = string.Concat(list.Select((string token) => token[0])); if (text2.Length >= 2 && !CommonAliasTokens.Contains(text2)) { P_1.aliases.Add(text2); } } } internal static class ConsoleCommandCatalog { internal static List CaptureVisibleCommands(Console? console) { List list = new List(); foreach (KeyValuePair command in Terminal.commands) { ConsoleCommand value = command.Value; if (value == null || string.IsNullOrWhiteSpace(value.Command)) { continue; } if ((Object)(object)console != (Object)null) { try { if (!value.ShowCommand((Terminal)(object)console)) { continue; } } catch { continue; } } string text = ConsoleCommandOwnership.GetOwner(value.Command); if (string.Equals(text, "Other Mods", StringComparison.OrdinalIgnoreCase) && IsLikelyValheimCommand(value.Command)) { text = "Valheim"; } list.Add(new CommandEntry(value.Command, value.Description ?? "", text)); } AddCompatibilityCommands(list); return list; } internal static int OwnerSortWeight(string owner) { if (string.Equals(owner, "Valheim", StringComparison.OrdinalIgnoreCase)) { return 0; } if (string.Equals(owner, "AdminQoL", StringComparison.OrdinalIgnoreCase)) { return 1; } if (string.Equals(owner, "Other Mods", StringComparison.OrdinalIgnoreCase)) { return 1000; } return 10; } private static void AddCompatibilityCommands(List entries) { AddCreatureLevelControlCommands(entries); } private static void AddCreatureLevelControlCommands(List entries) { if (IsPluginLoaded("org.bepinex.plugins.creaturelevelcontrol")) { entries.Add(new CommandEntry("cllc", "Show Creature Level & Loot Control command help.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc killall", "Remove all nearby creatures.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc killhighstars", "Remove nearby creatures with at least the given stars. Optional: [stars], default 6.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc worldlevel", "Display the current world level.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc sectorkills", "Display creatures killed in the current sector.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc resetsector", "Reset nearby creature sectors.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc starchance", "Display current star chances. Optional: [creature].", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc spawn", "Spawn a creature. Args: [creature] [level] [affix] [extraeffect] [infusion].", "Creature Level & Loot Control")); } } private static bool IsPluginLoaded(string guid) { string guid2 = guid; return Chainloader.PluginInfos.Values.Any((PluginInfo pluginInfo) => string.Equals(pluginInfo.Metadata.GUID, guid2, StringComparison.OrdinalIgnoreCase)); } private static bool IsLikelyValheimCommand(string command) { string command2 = command; return new string[25] { "help", "devcommands", "debugmode", "spawn", "itemset", "god", "fly", "ghost", "freefly", "save", "ping", "kick", "ban", "unban", "banned", "resetknownitems", "resetcharacter", "resetplayerprefs", "setkey", "removekey", "resetkeys", "players", "fov", "info", "gc" }.Any((string hint) => string.Equals(command2, hint, StringComparison.OrdinalIgnoreCase)); } } internal static class ConsolePanelConfig { internal const string PanelSection = "3 - Console Panel"; internal const string FavoritesSection = "4 - Console Panel Favorites"; } internal static class ConsolePanelLayout { internal const int MaxFavoriteTabs = 5; internal const int CanvasSortingOrder = 5000; internal const int UiLayer = 5; internal const float DefaultPanelWidth = 900f; internal const float DefaultPanelHeight = 450f; internal const float DefaultVanillaConsoleBottomOffset = 120f; internal const float PanelLeft = 5f; internal const float RowHeight = 30f; internal const float ScrollbarWidth = 2f; internal const float ScrollSensitivity = 240f; internal const float CommandRefreshSeconds = 3f; internal const float PanelGapBelowConsole = 30f; internal const float CategoryWidth = 150f; internal const float MinPanelWidth = 360f; internal const float MinPanelHeight = 180f; internal const float MinCategoryWidth = 80f; internal const float MaxCategoryWidthRatio = 0.45f; internal const float Gutter = 8f; internal const float MinCommandHeaderWidth = 160f; internal const float SearchReservedWidth = 180f; internal const float SearchExtraWidth = 120f; internal const float SearchMinWidth = 150f; internal const float FavoriteActionSpacing = 3f; internal const float FavoriteActionButtonWidth = 20f; internal const float CompactButtonMinWidth = 14f; internal const float CompactButtonPreferredWidth = 18f; internal const float VirtualCommandPadding = 4f; internal const float VirtualCommandSpacing = 4f; internal const int VirtualCommandLookBehindRows = 2; internal const int VirtualCommandLookAheadRows = 6; internal const int CommandPreviewCount = 5; internal const int ManualClickSuppressionFrames = 3; } internal static class ConsolePanelInputBlock { private static bool _active; private static bool _hasStoredMouseCapture; private static bool _previousMouseCapture; internal static bool IsActive => _active; internal static void SetActive(bool active, bool releaseMouseCapture = false) { if (_active == active) { if (active && releaseMouseCapture) { ApplyMouseCaptureBlock(); } else if (active) { RestoreMouseCapture(); } } else { _active = active; if (active && releaseMouseCapture) { ApplyMouseCaptureBlock(); } else { RestoreMouseCapture(); } } } private static void ApplyMouseCaptureBlock() { GameCamera instance = GameCamera.instance; if (!((Object)(object)instance == (Object)null)) { if (!_hasStoredMouseCapture) { _previousMouseCapture = instance.m_mouseCapture; _hasStoredMouseCapture = true; } instance.m_mouseCapture = false; instance.UpdateMouseCapture(); } } private static void RestoreMouseCapture() { GameCamera instance = GameCamera.instance; if ((Object)(object)instance != (Object)null && _hasStoredMouseCapture) { instance.m_mouseCapture = _previousMouseCapture; instance.UpdateMouseCapture(); } _hasStoredMouseCapture = false; } } internal static class ConsolePanelModule { internal static ConfigEntry PanelWidth; internal static ConfigEntry PanelHeight; internal static ConfigEntry VanillaConsoleBottomOffset; internal static ConfigEntry ReleaseMouseCursor; internal static ConfigEntry TogglePanelKey; internal static ConfigEntry VisualStyle; internal static ConfigEntry FavoriteTabCount; internal static ConfigEntry[] FavoriteTabCommands; private static ConfigFile? ConfigFile; private static ConsolePanelController? Controller; internal static void Initialize(GameObject host, ConfigFile config) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown ConfigFile = config; PanelWidth = config.Bind("3 - Console Panel", "Panel Width", 900f, "Width of the command browser panel."); PanelHeight = config.Bind("3 - Console Panel", "Panel Height", 450f, "Maximum height of the command browser panel. The panel shrinks if needed to preserve the fixed gap below the console."); VanillaConsoleBottomOffset = config.Bind("3 - Console Panel", "Vanilla Console Bottom Offset", 120f, "Bottom Y offset applied to Valheim's own console rect while the console is visible."); VisualStyle = config.Bind("3 - Console Panel", "Panel Visual Style", PanelVisualStyle.Modern, "Visual style for ConsolePanel. Wood uses Valheim-style wood panels, Modern uses ConfigurationManager-like flat panels."); ReleaseMouseCursor = config.Bind("3 - Console Panel", "Release Mouse Cursor", true, "Unlock and show the mouse cursor while the F5 console panel is visible so category, command, and favorite buttons can be clicked."); TogglePanelKey = config.Bind("3 - Console Panel", "Toggle Panel Key", new KeyboardShortcut((KeyCode)287, Array.Empty()), "Keyboard shortcut that toggles ConsolePanel while Valheim's F5 console is visible."); FavoriteTabCount = config.Bind("4 - Console Panel Favorites", "Favorite Tab Count", 3, new ConfigDescription("Number of numbered favorite command tabs to show.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 5), Array.Empty())); FavoriteTabCommands = new ConfigEntry[5]; for (int i = 0; i < 5; i++) { FavoriteTabCommands[i] = config.Bind("4 - Console Panel Favorites", $"Favorite {i + 1} Commands", "", $"Pipe-separated favorite console commands for numbered favorite tab {i + 1}."); } FavoriteTabCount.SettingChanged += delegate { Controller?.OnFavoriteConfigChanged(); }; for (int j = 0; j < 5; j++) { FavoriteTabCommands[j].SettingChanged += delegate { Controller?.OnFavoriteConfigChanged(); }; } if ((Object)(object)Controller == (Object)null) { Controller = host.AddComponent(); } } internal static void Shutdown() { if ((Object)(object)Controller != (Object)null) { Object.Destroy((Object)(object)Controller); Controller = null; } ConfigFile? configFile = ConfigFile; if (configFile != null) { configFile.Save(); } ConfigFile = null; } internal static void SaveConfig() { ConfigFile? configFile = ConfigFile; if (configFile != null) { configFile.Save(); } } internal static void UpdateConfigWithoutImmediateSave(Func update) { if (ConfigFile != null) { bool saveOnConfigSet = ConfigFile.SaveOnConfigSet; ConfigFile.SaveOnConfigSet = false; try { if (update()) { ConfigFile.Save(); } return; } finally { ConfigFile.SaveOnConfigSet = saveOnConfigSet; } } if (update()) { SaveConfig(); } } internal static void Diagnostic(string message) { } } [HarmonyPatch] internal static class ConsoleCommandConstructorPatch { private static IEnumerable TargetMethods() { return typeof(ConsoleCommand).GetConstructors(BindingFlags.Instance | BindingFlags.Public); } private static void Postfix(ConsoleCommand __instance) { ConsoleCommandOwnership.Record(__instance); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class TerminalInitPatch { private static void Prefix() { ConsoleCommandOwnership.EnterTerminalInit(); } private static void Postfix() { ConsoleCommandOwnership.ExitTerminalInit(); ConsoleCommandOwnership.MarkDirty(); } } [HarmonyPatch(typeof(Console), "Update")] internal static class ConsoleUpdateLayoutPatch { [HarmonyPriority(800)] private static void Postfix() { ConsolePanelController.ApplyAfterVanillaConsoleUpdate(); } } [HarmonyPatch(typeof(TMP_InputField), "ActivateInputField")] internal static class ConsoleInputActivatePatch { private static bool Prefix(TMP_InputField __instance) { return !ConsolePanelController.ShouldBlockConsoleInputActivation(__instance); } } [HarmonyPatch(typeof(Player), "TakeInput")] internal static class PlayerTakeInputPatch { private static void Postfix(ref bool __result) { if (ConsolePanelInputBlock.IsActive) { __result = false; } } } [HarmonyPatch(typeof(PlayerController), "TakeInput")] internal static class PlayerControllerTakeInputPatch { private static void Postfix(ref bool __result) { if (ConsolePanelInputBlock.IsActive) { __result = false; } } } [HarmonyPatch(typeof(TextInput), "IsVisible")] internal static class ConsolePanelTextInputVisiblePatch { private static void Postfix(ref bool __result) { if (ConsolePanelInputBlock.IsActive && ConsolePanelModule.ReleaseMouseCursor.Value) { __result = true; } } } internal sealed class ConsolePanelController : MonoBehaviour { private enum SurfaceRole { Panel, Header, Search, Scroll, Info, MutedInfo, Button, FavoriteBar, Tooltip, ScrollbarBackground, ScrollbarHandle } private sealed class CommandRowView { private readonly ConsolePanelController _owner; private readonly Button _commandButton; private readonly TextMeshProUGUI? _commandLabel; private readonly Transform _actionsTransform; private readonly LayoutElement _actionElement; private readonly List