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 ModMenu v0.2.0
patchers/ModMenu/ModMenu.Patcher.dll
Decompiled 20 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 Mono.Cecil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ModMenu.Patcher")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Preloader part of ModMenu")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0+118507c856dd0bcaa86de9a6f1234131721214f8")] [assembly: AssemblyProduct("ModMenu.Patcher")] [assembly: AssemblyTitle("ModMenu.Patcher")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.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 ModMenu.Patcher { internal static class ChainloaderFilter { private static PropertyInfo _locationProperty; private static readonly List<PluginInfo> _seen = new List<PluginInfo>(); public static void Install() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown Harmony val = new Harmony("com.damia.modmenu.patcher"); MethodInfo methodInfo = AccessTools.Method(typeof(TypeLoader), "FindPluginTypes", (Type[])null, (Type[])null).MakeGenericMethod(typeof(PluginInfo)); val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(ChainloaderFilter), "FindPluginTypesPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void FindPluginTypesPostfix(string cacheName, Dictionary<string, List<PluginInfo>> __result) { if (cacheName != "chainloader" || __result == null) { return; } object data = AppDomain.CurrentDomain.GetData("ModMenu.Discovering"); bool flag = default(bool); int num; if (data is bool) { flag = (bool)data; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { return; } try { HashSet<string> hashSet = Patcher.ReadDisabled(Patcher.DisabledFile); _seen.AddRange(__result.Values.SelectMany((List<PluginInfo> result) => result)); List<PluginInfo> seen = _seen; if (hashSet.Count > 0 && !seen.Any((PluginInfo i) => string.Equals(i.Metadata.GUID, "com.damia.modmenu", StringComparison.OrdinalIgnoreCase))) { Patcher.Log.LogWarning((object)"ModMenu plugin not found; ignoring disabled.txt and loading every mod."); return; } HashSet<string> hashSet2 = ProtectedGuids(seen); List<PluginInfo> list = (AppDomain.CurrentDomain.GetData("ModMenu.Patcher.Skipped") as List<PluginInfo>) ?? new List<PluginInfo>(); foreach (string item in __result.Keys.ToList()) { List<PluginInfo> list2 = __result[item]; foreach (PluginInfo item2 in list2.ToList()) { string gUID = item2.Metadata.GUID; if (hashSet.Contains(gUID) && !hashSet2.Contains(gUID)) { if (_locationProperty == null) { _locationProperty = AccessTools.Property(typeof(PluginInfo), "Location"); } _locationProperty.SetValue(item2, item, null); list2.Remove(item2); list.Add(item2); Patcher.Log.LogMessage((object)$"Disabled in ModMenu, not loading [{item2}]"); } } if (list2.Count == 0) { __result.Remove(item); } } AppDomain.CurrentDomain.SetData("ModMenu.Patcher.Skipped", list); AppDomain.CurrentDomain.SetData("ModMenu.Patcher.Protected", hashSet2.ToArray()); } catch (Exception arg) { Patcher.Log.LogError((object)$"Could not filter disabled mods, every mod will load: {arg}"); } } private static HashSet<string> ProtectedGuids(List<PluginInfo> all) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, PluginInfo> dictionary = new Dictionary<string, PluginInfo>(StringComparer.OrdinalIgnoreCase); foreach (PluginInfo item in all) { dictionary[item.Metadata.GUID] = item; } HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "com.damia.modmenu" }; Queue<string> queue = new Queue<string>(hashSet); while (queue.Count > 0) { if (!dictionary.TryGetValue(queue.Dequeue(), out var value)) { continue; } foreach (BepInDependency dependency in value.Dependencies) { if ((dependency.Flags & 1) != 0 && hashSet.Add(dependency.DependencyGUID)) { queue.Enqueue(dependency.DependencyGUID); } } } return hashSet; } } public static class Patcher { public const string ModMenuGuid = "com.damia.modmenu"; public const string DataSkipped = "ModMenu.Patcher.Skipped"; public const string DataProtected = "ModMenu.Patcher.Protected"; public const string DataDisabledFile = "ModMenu.Patcher.DisabledFile"; public const string DataDiscovering = "ModMenu.Discovering"; internal static readonly ManualLogSource Log = Logger.CreateLogSource("ModMenu.Patcher"); public static IEnumerable<string> TargetDLLs { get; } = new string[0]; public static string DisabledFile => Path.Combine(Path.Combine(Paths.ConfigPath, "ModMenu"), "disabled.txt"); public static void Patch(AssemblyDefinition assembly) { } public static void Finish() { try { ChainloaderFilter.Install(); AppDomain.CurrentDomain.SetData("ModMenu.Patcher.DisabledFile", DisabledFile); } catch (Exception arg) { Log.LogError((object)$"Could not hook the chainloader, every mod will load: {arg}"); } } public static HashSet<string> ReadDisabled(string file) { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); if (!File.Exists(file)) { return hashSet; } string[] array = File.ReadAllLines(file); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && !text.StartsWith("#")) { hashSet.Add(text); } } return hashSet; } } internal static class PluginInfo { public const string Guid = "com.damia.modmenu.patcher"; public const string Name = "ModMenu.Patcher"; public const string Version = "0.2.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/ModMenu/ModMenu.dll
Decompiled 20 hours agousing System; using System.Collections; 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 System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using ModMenu.UI; using Mono.Cecil; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ModMenu")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Main-menu mod manager: switch mods on/off, edit their settings, profiles, update check (Nexus, Thunderstore)")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0+118507c856dd0bcaa86de9a6f1234131721214f8")] [assembly: AssemblyProduct("ModMenu")] [assembly: AssemblyTitle("ModMenu")] [assembly: InternalsVisibleTo("ModMenu.Tests")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.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 ModMenu { internal static class ConfigSources { private const BindingFlags InstanceFields = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private const BindingFlags StaticFields = BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly Dictionary<BaseUnityPlugin, List<ConfigFile>> Cache = new Dictionary<BaseUnityPlugin, List<ConfigFile>>(); public static List<ConfigFile> For(BaseUnityPlugin plugin) { if ((Object)(object)plugin == (Object)null) { return new List<ConfigFile>(); } if (Cache.TryGetValue(plugin, out var value)) { return value; } List<ConfigFile> list = new List<ConfigFile>(); Add(list, plugin.Config); try { Type type = ((object)plugin).GetType(); while (type != null && type != typeof(BaseUnityPlugin)) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { AddFromValue(list, field.FieldType, () => field.GetValue(plugin)); } type = type.BaseType; } foreach (Type item in LoadableTypes(((object)plugin).GetType().Assembly)) { if (item.ContainsGenericParameters || item.TypeInitializer != null) { continue; } FieldInfo[] fields = item.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field2 in fields) { if (!field2.IsLiteral) { AddFromValue(list, field2.FieldType, () => field2.GetValue(null)); } } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; PluginInfo info = plugin.Info; object obj; if (info == null) { obj = null; } else { BepInPlugin metadata = info.Metadata; obj = ((metadata != null) ? metadata.Name : null); } log.LogWarning((object)("Could not look for extra config files of " + (string?)obj + ": " + ex.Message)); } Cache[plugin] = list; return list; } private static void AddFromValue(List<ConfigFile> files, Type fieldType, Func<object> read) { if (!typeof(ConfigFile).IsAssignableFrom(fieldType) && !typeof(ConfigEntryBase).IsAssignableFrom(fieldType)) { return; } try { object obj = read(); object obj2 = ((obj is ConfigFile) ? obj : null); if (obj2 == null) { object obj3 = ((obj is ConfigEntryBase) ? obj : null); obj2 = ((obj3 != null) ? ((ConfigEntryBase)obj3).ConfigFile : null); } Add(files, (ConfigFile)obj2); } catch (Exception) { } } private static void Add(List<ConfigFile> files, ConfigFile file) { if (file != null && !files.Contains(file) && !string.Equals(file.ConfigFilePath, Paths.BepInExConfigPath, StringComparison.OrdinalIgnoreCase)) { files.Add(file); } } private static IEnumerable<Type> LoadableTypes(Assembly assembly) { try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.Where((Type t) => t != null); } } } internal static class GameRestart { private const string SteamAppId = "892970"; private static ProcessStartInfo UnixRestart(int pid, bool steam, string exe) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 string text = (((int)Application.platform == 1) ? "open" : "xdg-open"); string arg = (steam ? (text + " steam://rungameid/892970") : ("\"" + exe.Replace("\"", "") + "\"")); return new ProcessStartInfo { FileName = "/bin/sh", Arguments = $"-c 'while kill -0 {pid} 2>/dev/null; do sleep 1; done; {arg} >/dev/null 2>&1 &'", UseShellExecute = false, CreateNoWindow = true }; } public static void Restart() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Invalid comparison between Unknown and I4 try { Process currentProcess = Process.GetCurrentProcess(); int id = currentProcess.Id; string text = currentProcess.MainModule?.FileName ?? ""; bool flag = text.IndexOf("steamapps", StringComparison.OrdinalIgnoreCase) >= 0; string[] commandLineArgs = Environment.GetCommandLineArgs(); string text2 = string.Join(",", (from a in commandLineArgs.Skip(1) select "'" + a.Replace("\"", "").Replace("'", "''") + "'").ToArray()); string arg = (flag ? "Start-Process 'steam://rungameid/892970'" : ("Start-Process -FilePath '" + text.Replace("'", "''") + "'" + ((text2.Length > 0) ? (" -ArgumentList " + text2) : ""))); Process.Start(((int)Application.platform == 2) ? new ProcessStartInfo { FileName = "powershell.exe", Arguments = $"-NoProfile -WindowStyle Hidden -Command \"Wait-Process -Id {id} -ErrorAction SilentlyContinue; {arg}\"", UseShellExecute = false, CreateNoWindow = true } : UnixRestart(id, flag, text)); } catch (Exception ex) { Plugin.Log.LogError((object)("Could not schedule the restart, the game will only quit: " + ex.Message)); } Application.Quit(); } } internal enum ModState { Loaded, Disabled, Failed } internal sealed class ModEntry { public string Guid; public string Name; public string Version; public string Location; public ModState State; public string Error; public string OnlyFor; public BaseUnityPlugin Instance; public string[] HardDependencies = new string[0]; public bool Protected; public ModSource Source; public string LatestVersion; public bool UpdateAvailable; } internal static class ModCatalog { private const string DataSkipped = "ModMenu.Patcher.Skipped"; private const string DataProtected = "ModMenu.Patcher.Protected"; private const string DataDisabledFile = "ModMenu.Patcher.DisabledFile"; private const string DataDiscovering = "ModMenu.Discovering"; private static List<ModEntry> _mods; private static HashSet<string> _disabledAtStart; private static HashSet<string> _wanted; public static string Folder => Path.Combine(Paths.ConfigPath, "ModMenu"); public static string DisabledFile => Path.Combine(Folder, "disabled.txt"); public static string ProfilesFolder => Path.Combine(Folder, "profiles"); public static bool PatcherActive => AppDomain.CurrentDomain.GetData("ModMenu.Patcher.DisabledFile") != null; public static List<ModEntry> Mods { get { if (_mods == null) { Build(); } return _mods; } } public static HashSet<string> WantedDisabled { get { _ = Mods; return new HashSet<string>(_wanted, StringComparer.OrdinalIgnoreCase); } } public static bool RestartNeeded { get { _ = Mods; return _mods.Any((ModEntry m) => _wanted.Contains(m.Guid) != _disabledAtStart.Contains(m.Guid)); } } public static bool IsWantedDisabled(string guid) { _ = Mods; return _wanted.Contains(guid); } public static void SetWantedDisabled(string guid, bool disabled) { _ = Mods; ModEntry modEntry = _mods.FirstOrDefault((ModEntry m) => m.Guid == guid); if ((modEntry == null || !modEntry.Protected) && (disabled ? _wanted.Add(guid) : _wanted.Remove(guid))) { SaveWanted(); } } public static void ReplaceWanted(IEnumerable<string> guids) { _ = Mods; HashSet<string> protectedGuids = new HashSet<string>(from m in _mods where m.Protected select m.Guid, StringComparer.OrdinalIgnoreCase); _wanted = new HashSet<string>(guids.Where((string g) => !protectedGuids.Contains(g)), StringComparer.OrdinalIgnoreCase); SaveWanted(); } public static List<ModEntry> Dependents(string guid) { return Mods.Where((ModEntry m) => m.HardDependencies.Contains<string>(guid, StringComparer.OrdinalIgnoreCase)).ToList(); } public static List<string> MissingDependencies(ModEntry mod) { List<string> list = new List<string>(); string[] hardDependencies = mod.HardDependencies; foreach (string dependency in hardDependencies) { ModEntry modEntry = Mods.FirstOrDefault((ModEntry m) => string.Equals(m.Guid, dependency, StringComparison.OrdinalIgnoreCase)); if (modEntry == null || _wanted.Contains(modEntry.Guid)) { list.Add(modEntry?.Name ?? dependency); } } return list; } private static void Build() { Dictionary<string, ModEntry> dictionary = new Dictionary<string, ModEntry>(StringComparer.OrdinalIgnoreCase); string[] source = (AppDomain.CurrentDomain.GetData("ModMenu.Patcher.Protected") as string[]) ?? new string[1] { "com.damia.modmenu" }; foreach (PluginInfo value in Chainloader.PluginInfos.Values) { dictionary[value.Metadata.GUID] = FromInfo(value, (!((Object)(object)value.Instance != (Object)null)) ? ModState.Failed : ModState.Loaded); } _disabledAtStart = new HashSet<string>(StringComparer.OrdinalIgnoreCase); if (AppDomain.CurrentDomain.GetData("ModMenu.Patcher.Skipped") is List<PluginInfo> list) { foreach (PluginInfo item in list) { dictionary[item.Metadata.GUID] = FromInfo(item, ModState.Disabled); _disabledAtStart.Add(item.Metadata.GUID); } } foreach (PluginInfo info in DiscoverAll()) { if (!dictionary.ContainsKey(info.Metadata.GUID)) { ModEntry modEntry = FromInfo(info, ModState.Failed); modEntry.Error = Chainloader.DependencyErrors.FirstOrDefault((string e) => e.Contains("[" + ((object)info)?.ToString() + "]")); List<string> list2 = info.Processes.Select((BepInProcess p) => p.ProcessName).ToList(); if (list2.Count > 0 && !list2.Any((string p) => string.Equals(p.Replace(".exe", ""), Paths.ProcessName, StringComparison.OrdinalIgnoreCase))) { modEntry.OnlyFor = string.Join(", ", list2.ToArray()); } dictionary[info.Metadata.GUID] = modEntry; } } foreach (ModEntry value2 in dictionary.Values) { value2.Protected = source.Contains<string>(value2.Guid, StringComparer.OrdinalIgnoreCase); } _mods = dictionary.Values.OrderBy<ModEntry, string>((ModEntry m) => m.Name, StringComparer.OrdinalIgnoreCase).ToList(); _wanted = ReadGuidFile(DisabledFile); _wanted.RemoveWhere((string g) => _mods.Any((ModEntry m) => m.Protected && string.Equals(m.Guid, g, StringComparison.OrdinalIgnoreCase))); ModSources.Detect(_mods); Plugin.Log.LogInfo((object)($"Found {_mods.Count} mods: {_mods.Count((ModEntry m) => m.State == ModState.Loaded)} loaded, " + $"{_mods.Count((ModEntry m) => m.State == ModState.Disabled)} switched off, {_mods.Count((ModEntry m) => m.State == ModState.Failed)} not loaded; " + $"sources: {_mods.Count((ModEntry m) => m.Source.Kind == SourceKind.Nexus)} Nexus, {_mods.Count((ModEntry m) => m.Source.Kind == SourceKind.Thunderstore)} Thunderstore")); } private static IEnumerable<PluginInfo> DiscoverAll() { AppDomain.CurrentDomain.SetData("ModMenu.Discovering", true); Dictionary<string, List<PluginInfo>> dictionary; try { dictionary = TypeLoader.FindPluginTypes<PluginInfo>(Paths.PluginPath, (Func<TypeDefinition, PluginInfo>)Chainloader.ToPluginInfo, (Func<AssemblyDefinition, bool>)null, "chainloader"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not list the plugins folder: " + ex.Message)); yield break; } finally { AppDomain.CurrentDomain.SetData("ModMenu.Discovering", false); } foreach (KeyValuePair<string, List<PluginInfo>> pair in dictionary) { foreach (PluginInfo item in pair.Value) { if (string.IsNullOrEmpty(item.Location)) { AccessLocation(item, pair.Key); } yield return item; } } } private static void AccessLocation(PluginInfo info, string location) { AccessTools.Property(typeof(PluginInfo), "Location").SetValue(info, location, null); } private static ModEntry FromInfo(PluginInfo info, ModState state) { return new ModEntry { Guid = info.Metadata.GUID, Name = info.Metadata.Name, Version = (info.Metadata.Version?.ToString() ?? "?"), Location = info.Location, State = state, Instance = info.Instance, HardDependencies = (from d in info.Dependencies where (d.Flags & 1) > 0 select d.DependencyGUID).ToArray() }; } private static void SaveWanted() { try { Directory.CreateDirectory(Folder); List<string> list = new List<string> { "# Mods switched off by ModMenu (one plugin GUID per line). Delete a line, or this file, to switch a mod back on." }; list.AddRange(_wanted.OrderBy<string, string>((string g) => g, StringComparer.OrdinalIgnoreCase)); File.WriteAllLines(DisabledFile, list.ToArray()); } catch (Exception ex) { Plugin.Log.LogError((object)("Could not save " + DisabledFile + ": " + ex.Message)); } } internal static HashSet<string> ReadGuidFile(string file) { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); try { if (File.Exists(file)) { string[] array = File.ReadAllLines(file); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && !text.StartsWith("#")) { hashSet.Add(text); } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read " + file + ": " + ex.Message)); } return hashSet; } } internal enum SourceKind { Unknown, Nexus, Thunderstore } internal sealed class ModSource { public SourceKind Kind; public int NexusId; public string ThunderstoreNamespace; public string ThunderstoreName; public string InstalledVersion; public bool Guessed; public string PageUrl { get { if (Kind != SourceKind.Nexus) { if (Kind != SourceKind.Thunderstore || ThunderstoreNamespace == null) { return null; } return "https://thunderstore.io/c/valheim/p/" + ThunderstoreNamespace + "/" + ThunderstoreName + "/"; } return $"https://www.nexusmods.com/valheim/mods/{NexusId}"; } } } internal static class ModSources { private static readonly Regex VortexNew = new Regex("^(?<name>.+?) (?<id>\\d+) (?<ver>\\S+) \\d{4}-\\d{2}-\\d{2}T", RegexOptions.Compiled); private static readonly Regex VortexOld = new Regex("^(?<name>.+?)-(?<id>\\d+)-(?<ver>\\d+(?:-\\d+)*?)-\\d{9,}$", RegexOptions.Compiled); private static readonly Regex Dependency = new Regex("^(?<ns>[^-]+)-(?<name>.+)-\\d+\\.\\d+\\.\\d+$", RegexOptions.Compiled); public static void Detect(List<ModEntry> mods) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, string> vortex = ReadVortexManifests(); Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); Dictionary<ModEntry, JObject> dictionary2 = new Dictionary<ModEntry, JObject>(); foreach (ModEntry mod in mods) { if (string.IsNullOrEmpty(mod.Location)) { mod.Source = new ModSource(); continue; } mod.Source = FromVortex(mod, vortex) ?? new ModSource(); if (mod.Source.Kind != SourceKind.Unknown) { continue; } JObject val = FindManifest(mod.Location); if (val == null) { continue; } dictionary2[mod] = val; JToken obj = val["dependencies"]; foreach (JToken item in (JArray)(((object)((obj is JArray) ? obj : null)) ?? ((object)new JArray()))) { Match match = Dependency.Match(((string)item) ?? ""); if (match.Success) { dictionary[match.Groups["name"].Value] = match.Groups["ns"].Value; } } } foreach (KeyValuePair<ModEntry, JObject> item2 in dictionary2) { string text = (string)item2.Value["name"]; if (!string.IsNullOrEmpty(text)) { string name = new DirectoryInfo(Path.GetDirectoryName(item2.Key.Location)).Name; string value; string thunderstoreNamespace = (name.EndsWith("-" + text, StringComparison.OrdinalIgnoreCase) ? name.Substring(0, name.Length - text.Length - 1) : (dictionary.TryGetValue(text, out value) ? value : null)); item2.Key.Source = new ModSource { Kind = SourceKind.Thunderstore, ThunderstoreName = text, ThunderstoreNamespace = thunderstoreNamespace, InstalledVersion = (string)item2.Value["version_number"] }; } } foreach (ModEntry item3 in mods.Where((ModEntry m) => m.Source.Kind == SourceKind.Unknown && !string.IsNullOrEmpty(m.Location))) { item3.Source = new ModSource { Kind = SourceKind.Thunderstore, ThunderstoreName = item3.Name.Replace(" ", ""), Guessed = true }; } } private static ModSource FromVortex(ModEntry mod, Dictionary<string, string> vortex) { if (!vortex.TryGetValue(Normalize(mod.Location), out var value) || !ParseVortexArchive(value, out var id, out var version)) { return null; } return new ModSource { Kind = SourceKind.Nexus, NexusId = id, InstalledVersion = version }; } internal static bool ParseVortexArchive(string archive, out int id, out string version) { id = 0; version = null; Match match = VortexNew.Match(archive ?? ""); if (match.Success) { version = match.Groups["ver"].Value; } else { match = VortexOld.Match(archive ?? ""); if (!match.Success) { return false; } version = match.Groups["ver"].Value.Replace('-', '.'); } return int.TryParse(match.Groups["id"].Value, out id); } private static Dictionary<string, string> ReadVortexManifests() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, string> dictionary = new Dictionary<string, string>(); try { string[] files = Directory.GetFiles(Paths.PluginPath, "vortex.deployment*.json"); for (int i = 0; i < files.Length; i++) { JObject obj = JObject.Parse(File.ReadAllText(files[i])); string path = ((string)obj["targetPath"]) ?? Paths.PluginPath; JToken obj2 = obj["files"]; foreach (JToken item in (JArray)(((object)((obj2 is JArray) ? obj2 : null)) ?? ((object)new JArray()))) { string text = (string)item[(object)"relPath"]; string value = (string)item[(object)"source"]; if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(value)) { dictionary[Normalize(Path.Combine(path, text))] = value; } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read the Vortex deployment manifest: " + ex.Message)); } return dictionary; } private static JObject FindManifest(string dll) { string text = Normalize(Paths.PluginPath); string directoryName = Path.GetDirectoryName(dll); while (!string.IsNullOrEmpty(directoryName) && Normalize(directoryName).StartsWith(text) && Normalize(directoryName) != text) { string text2 = Path.Combine(directoryName, "manifest.json"); if (File.Exists(text2)) { try { return JObject.Parse(File.ReadAllText(text2)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read " + text2 + ": " + ex.Message)); return null; } } directoryName = Path.GetDirectoryName(directoryName); } return null; } private static string Normalize(string path) { return Path.GetFullPath(path).TrimEnd('\\', '/').ToLowerInvariant(); } public static int[] ParseVersion(string version) { if (string.IsNullOrEmpty(version)) { return null; } int result; int[] array = (from Match m in Regex.Matches(version, "\\d+") select int.TryParse(m.Value, out result) ? result : 0).ToArray(); if (array.Length != 0) { return array; } return null; } public static bool IsNewer(string latest, string installed) { int[] array = ParseVersion(latest); int[] array2 = ParseVersion(installed); if (array == null || array2 == null) { return false; } for (int i = 0; i < Math.Max(array.Length, array2.Length); i++) { int num = ((i < array.Length) ? array[i] : 0); int num2 = ((i < array2.Length) ? array2[i] : 0); if (num != num2) { return num > num2; } } return false; } } [BepInPlugin("com.damia.modmenu", "Mod Menu", "0.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static Plugin Instance; internal static ManualLogSource Log; internal static ConfigEntry<bool> CheckUpdatesOnOpen; internal static ConfigEntry<KeyboardShortcut> OpenKey; private Harmony _harmony; private void Awake() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; CheckUpdatesOnOpen = ((BaseUnityPlugin)this).Config.Bind<bool>("Updates", "CheckOnOpen", true, "Check Nexus Mods and Thunderstore for newer versions the first time the menu is opened in a session."); OpenKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "OpenKey", new KeyboardShortcut((KeyCode)109, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Opens the Mods window in the main menu - also when another mod reworks the menu and hides the button."); _harmony = new Harmony("com.damia.modmenu"); _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"ModMenu 0.2.0 loaded"); } private void Update() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) FejdStartup instance = FejdStartup.instance; if ((Object)(object)instance != (Object)null && !ModMenuWindow.IsOpen && (Object)(object)instance.m_menuList != (Object)null && instance.m_menuList.activeInHierarchy) { KeyboardShortcut value = OpenKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { MainMenuButton.OpenWindow(instance); } } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class Profiles { public static List<string> Names() { try { if (!Directory.Exists(ModCatalog.ProfilesFolder)) { return new List<string>(); } return Directory.GetFiles(ModCatalog.ProfilesFolder, "*.txt").Select(Path.GetFileNameWithoutExtension).OrderBy<string, string>((string n) => n, StringComparer.OrdinalIgnoreCase) .ToList(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not list profiles: " + ex.Message)); return new List<string>(); } } public static HashSet<string> Read(string name) { return ModCatalog.ReadGuidFile(PathOf(name)); } public static string Matching(HashSet<string> disabled) { return Names().FirstOrDefault((string n) => Read(n).SetEquals(disabled)); } public static string Save(string name, IEnumerable<string> disabledGuids) { name = Clean(name); if (name.Length == 0) { return null; } try { Directory.CreateDirectory(ModCatalog.ProfilesFolder); List<string> list = new List<string> { "# ModMenu profile: mods switched off (one plugin GUID per line)." }; list.AddRange(disabledGuids.OrderBy<string, string>((string g) => g, StringComparer.OrdinalIgnoreCase)); File.WriteAllLines(PathOf(name), list.ToArray()); return name; } catch (Exception ex) { Plugin.Log.LogError((object)("Could not save profile " + name + ": " + ex.Message)); return null; } } public static void Delete(string name) { try { File.Delete(PathOf(name)); } catch (Exception ex) { Plugin.Log.LogError((object)("Could not delete profile " + name + ": " + ex.Message)); } } private static string PathOf(string name) { return Path.Combine(ModCatalog.ProfilesFolder, Clean(name) + ".txt"); } private static string Clean(string name) { char[] invalid = Path.GetInvalidFileNameChars(); return new string((name ?? "").Where((char c) => !invalid.Contains(c)).ToArray()).Trim(); } } internal static class T { private static readonly Dictionary<string, (string en, string pl)> Strings = new Dictionary<string, (string, string)> { ["menu_button"] = ("Mods", "Mody"), ["title"] = ("Mods ({0})", "Mody ({0})"), ["close"] = ("Close", "Zamknij"), ["back"] = ("Back", "Wróć"), ["profiles"] = ("Profiles", "Profile"), ["check_updates"] = ("Check updates", "Sprawdź aktualizacje"), ["checking"] = ("Checking... {0}/{1}", "Sprawdzam... {0}/{1}"), ["restart"] = ("Restart game", "Uruchom ponownie"), ["restart_needed"] = ("Changes apply after a restart.", "Zmiany zadziałają po ponownym uruchomieniu gry."), ["no_patcher"] = ("ModMenu.Patcher is missing from BepInEx/patchers - switching mods off will not work.", "Brak ModMenu.Patcher w BepInEx/patchers - wyłączanie modów nie zadziała."), ["search"] = ("Search...", "Szukaj..."), ["settings"] = ("Settings", "Ustawienia"), ["page"] = ("Page", "Strona"), ["state_loaded"] = ("Loaded", "Działa"), ["state_disabled"] = ("Switched off", "Wyłączony"), ["only_for"] = ("Not for this program (only {0})", "Nie dla tego programu (tylko {0})"), ["state_failed"] = ("Failed to load", "Błąd ładowania"), ["state_off_next"] = ("Off after restart", "Wyłączy się po restarcie"), ["state_on_next"] = ("On after restart", "Włączy się po restarcie"), ["protected"] = ("Required by Mod Menu", "Wymagany przez Mod Menu"), ["update"] = ("Update: {0}", "Aktualizacja: {0}"), ["up_to_date"] = ("Up to date", "Aktualny"), ["needs"] = ("Needs: {0}", "Wymaga: {0}"), ["also_stops"] = ("Also stops: {0}", "Przestaną działać też: {0}"), ["update_error"] = ("Update check failed: {0}", "Nie udało się sprawdzić aktualizacji: {0}"), ["updates_found"] = ("Updates available: {0}", "Dostępne aktualizacje: {0}"), ["no_updates"] = ("All checked mods are up to date.", "Wszystkie sprawdzone mody są aktualne."), ["config_title"] = ("{0} - settings", "{0} - ustawienia"), ["config_none"] = ("This mod has no settings.", "Ten mod nie ma ustawień."), ["config_off"] = ("Switch the mod on and restart the game to edit its settings.", "Włącz moda i uruchom ponownie grę, żeby zmienić jego ustawienia."), ["config_hint"] = ("Saved at once. Some mods read a setting only at startup.", "Zapisuje się od razu. Niektóre mody czytają ustawienie tylko przy starcie gry."), ["advanced"] = ("advanced", "zaawansowane"), ["config_search"] = ("Search settings...", "Szukaj ustawień..."), ["config_no_match"] = ("No setting matches the search.", "Żadne ustawienie nie pasuje do wyszukiwania."), ["reset"] = ("Default", "Domyślne"), ["invalid"] = ("Invalid value", "Nieprawidłowa wartość"), ["profile_name"] = ("New profile name...", "Nazwa nowego profilu..."), ["profile_save"] = ("Save current", "Zapisz obecny"), ["profile_load"] = ("Load", "Wczytaj"), ["profile_overwrite"] = ("Overwrite", "Nadpisz"), ["profile_delete"] = ("Delete", "Usuń"), ["profile_active"] = ("(current)", "(obecny)"), ["profile_none"] = ("No profiles yet. A profile remembers which mods are switched off.", "Brak profili. Profil zapamiętuje, które mody są wyłączone."), ["profile_count"] = ("{0} off", "wyłączonych: {0}"), ["all_on"] = ("Switch all on", "Włącz wszystkie") }; public static string Get(string key, params object[] args) { if (!Strings.TryGetValue(key, out (string, string) value)) { return key; } string text; if (Localization.instance == null || !(Localization.instance.GetSelectedLanguage() == "Polish")) { (text, _) = value; } else { text = value.Item2; } string text2 = text; if (args.Length == 0) { return text2; } return string.Format(text2, args); } } internal static class UpdateChecker { private const string NexusApi = "https://api.nexusmods.com/v2/graphql"; private const string ThunderstorePackage = "https://thunderstore.io/api/experimental/package/{0}/{1}/"; private const string ThunderstoreSearch = "https://thunderstore.io/api/cyberstorm/listing/valheim/?q={0}"; private const int ParallelRequests = 6; private const int NexusBatch = 50; private const int NameBatch = 20; public static bool Running { get; private set; } public static bool Done { get; private set; } public static int Progress { get; private set; } public static int Total { get; private set; } public static string LastError { get; private set; } public static IEnumerator Run(List<ModEntry> mods, Action onChanged) { List<ModEntry> thunderstore; int next; int workers; if (!Running) { Running = true; LastError = null; List<ModEntry> nexus = mods.Where(delegate(ModEntry m) { ModSource source = m.Source; return source != null && source.Kind == SourceKind.Nexus; }).ToList(); thunderstore = mods.Where(delegate(ModEntry m) { ModSource source = m.Source; return source != null && source.Kind == SourceKind.Thunderstore; }).ToList(); Total = (nexus.Count + 50 - 1) / 50 + thunderstore.Count + 1; Progress = 0; onChanged(); for (int i = 0; i < nexus.Count; i += 50) { yield return CheckNexus(nexus.Skip(i).Take(50).ToList()); Progress++; onChanged(); } next = 0; workers = 0; for (int num = 0; num < 6; num++) { workers++; ((MonoBehaviour)Plugin.Instance).StartCoroutine(Worker()); } float deadline = Time.realtimeSinceStartup + 180f; while (workers > 0 && Time.realtimeSinceStartup < deadline) { yield return null; } List<ModEntry> unknown = thunderstore.Where((ModEntry m) => m.Source.Guessed && m.Source.ThunderstoreNamespace == null).ToList(); for (int i = 0; i < unknown.Count; i += 20) { yield return SearchNexusByName(unknown.Skip(i).Take(20).ToList()); } Progress++; Running = false; Done = true; List<ModEntry> list = mods.Where((ModEntry m) => m.UpdateAvailable).ToList(); Plugin.Log.LogInfo((object)($"Update check done: {mods.Count((ModEntry m) => m.LatestVersion != null)} mods checked, {list.Count} updates" + ((list.Count > 0) ? (": " + string.Join(", ", list.Select((ModEntry m) => m.Name + " " + (m.Source.InstalledVersion ?? m.Version) + " -> " + m.LatestVersion).ToArray())) : ""))); onChanged(); } IEnumerator Worker() { while (next < thunderstore.Count) { ModEntry mod = thunderstore[next++]; yield return CheckThunderstore(mod); Progress++; onChanged(); } workers--; } } private static IEnumerator CheckNexus(List<ModEntry> mods) { string text = string.Join(", ", (from id in mods.Select((ModEntry m) => m.Source.NexusId).Distinct() select $"{{gameDomain: \"valheim\", modId: {id}}}").ToArray()); yield return PostGraphQL("{ legacyModsByDomain(ids: [" + text + "]) { nodes { modId version } } }", delegate(JObject result) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) Dictionary<int, string> dictionary = new Dictionary<int, string>(); JToken obj = ((JToken)result).SelectToken("data.legacyModsByDomain.nodes"); foreach (JToken item in (JArray)(((object)((obj is JArray) ? obj : null)) ?? ((object)new JArray()))) { dictionary[(int)item[(object)"modId"]] = (string)item[(object)"version"]; } foreach (ModEntry mod in mods) { if (dictionary.TryGetValue(mod.Source.NexusId, out var value)) { SetLatest(mod, value); } } }); } private static IEnumerator SearchNexusByName(List<ModEntry> mods) { List<string> list = new List<string>(); for (int i = 0; i < mods.Count; i++) { list.Add($"m{i}: mods(filter: {{ gameDomainName: [{{value: \"valheim\"}}], name: [{{value: {JsonConvert.ToString(mods[i].Name)}, op: EQUALS}}] }}) {{ nodes {{ modId version author }} }}"); } yield return PostGraphQL("{ " + string.Join(" ", list.ToArray()) + " }", delegate(JObject result) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) for (int j = 0; j < mods.Count; j++) { JToken obj = ((JToken)result).SelectToken($"data.m{j}.nodes"); List<JToken> list2 = ((IEnumerable<JToken>)(((object)((obj is JArray) ? obj : null)) ?? ((object)new JArray()))).ToList(); string[] guidParts = mods[j].Guid.ToLowerInvariant().Split('.', '_', '-'); List<JToken> list3 = list2.Where((JToken n) => guidParts.Contains((((string)n[(object)"author"]) ?? "").Replace(" ", "").ToLowerInvariant())).ToList(); JToken val = ((list3.Count == 1) ? list3[0] : ((list2.Count == 1) ? list2[0] : null)); if (val != null) { mods[j].Source = new ModSource { Kind = SourceKind.Nexus, NexusId = (int)val[(object)"modId"] }; SetLatest(mods[j], (string)val[(object)"version"]); } } }); } private static IEnumerator PostGraphQL(string query, Action<JObject> onResult) { string s = JsonConvert.SerializeObject((object)new { query }); UnityWebRequest request = new UnityWebRequest("https://api.nexusmods.com/v2/graphql", "POST"); try { request.uploadHandler = (UploadHandler)new UploadHandlerRaw(Encoding.UTF8.GetBytes(s)); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); request.timeout = 20; yield return request.SendWebRequest(); if ((int)request.result != 1) { Fail("Nexus: " + request.error); yield break; } try { onResult(JObject.Parse(request.downloadHandler.text)); } catch (Exception ex) { Fail("Nexus: " + ex.Message); } } finally { ((IDisposable)request)?.Dispose(); } } private static IEnumerator CheckThunderstore(ModEntry mod) { ModSource source = mod.Source; if (source.ThunderstoreNamespace == null) { string found = null; yield return Get($"https://thunderstore.io/api/cyberstorm/listing/valheim/?q={Uri.EscapeDataString(source.ThunderstoreName)}", delegate(string text) { found = PickNamespace(mod, text); }); if (found == null) { yield break; } source.ThunderstoreNamespace = found; } yield return Get($"https://thunderstore.io/api/experimental/package/{source.ThunderstoreNamespace}/{source.ThunderstoreName}/", delegate(string text) { SetLatest(mod, (string)((JToken)JObject.Parse(text)).SelectToken("latest.version_number")); }); } private static string PickNamespace(ModEntry mod, string json) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) ModSource source = mod.Source; JToken obj = JObject.Parse(json)["results"]; IEnumerable<JToken> source2 = ((IEnumerable<JToken>)(((object)((obj is JArray) ? obj : null)) ?? ((object)new JArray()))).Where((JToken r) => string.Equals((string)r[(object)"name"], source.ThunderstoreName, StringComparison.OrdinalIgnoreCase)); if (source.Guessed) { List<JToken> list = source2.ToList(); string[] guidParts = mod.Guid.Split('.', '_', '-'); List<JToken> list2 = list.Where((JToken r) => guidParts.Contains<string>((string)r[(object)"namespace"], StringComparer.OrdinalIgnoreCase)).ToList(); source2 = ((list2.Count > 0) ? list2 : ((list.Count == 1) ? list : new List<JToken>())); } JToken val = source2.OrderByDescending((JToken r) => ((long?)r[(object)"download_count"]).GetValueOrDefault()).FirstOrDefault(); if (val == null) { return null; } source.ThunderstoreName = (string)val[(object)"name"]; return (string)val[(object)"namespace"]; } private static IEnumerator Get(string url, Action<string> onText) { UnityWebRequest request = UnityWebRequest.Get(url); try { request.timeout = 15; yield return request.SendWebRequest(); if ((int)request.result != 1) { if (request.responseCode != 404) { Fail("Thunderstore: " + request.error); } yield break; } try { onText(request.downloadHandler.text); } catch (Exception ex) { Fail("Thunderstore: " + ex.Message); } } finally { ((IDisposable)request)?.Dispose(); } } private static void SetLatest(ModEntry mod, string latest) { if (!string.IsNullOrEmpty(latest)) { mod.LatestVersion = latest; mod.UpdateAvailable = ModSources.IsNewer(latest, mod.Version) && (mod.Source.InstalledVersion == null || ModSources.IsNewer(latest, mod.Source.InstalledVersion)); } } private static void Fail(string error) { LastError = error; Plugin.Log.LogWarning((object)("Update check: " + error)); } } internal static class PluginInfo { public const string Guid = "com.damia.modmenu"; public const string Name = "ModMenu"; public const string Version = "0.2.0"; } } namespace ModMenu.UI { internal static class ConfigEditors { private const float EditorWidth = 300f; private const float ResetWidth = 100f; private const int MaxDropdownOptions = 60; public static List<ConfigEntryBase> Visible(ConfigFile config) { List<ConfigEntryBase> list = new List<ConfigEntryBase>(); foreach (ConfigDefinition item in config.Keys.ToList()) { ConfigEntryBase val = config[item]; if (val != null && Attribute<bool?>(val, "Browsable") != false) { list.Add(val); } } return list.OrderBy<ConfigEntryBase, string>(Category, StringComparer.OrdinalIgnoreCase).ThenByDescending((ConfigEntryBase e) => Attribute<int?>(e, "Order").GetValueOrDefault()).ThenBy<ConfigEntryBase, string>((ConfigEntryBase e) => e.Definition.Key, StringComparer.OrdinalIgnoreCase) .ToList(); } public static string Category(ConfigEntryBase entry) { return Attribute<string>(entry, "Category") ?? entry.Definition.Section; } public static string DisplayName(ConfigEntryBase entry) { return Attribute<string>(entry, "DispName") ?? entry.Definition.Key; } public static bool Matches(ConfigEntryBase entry, string filter) { if (!string.IsNullOrEmpty(filter) && DisplayName(entry).IndexOf(filter, StringComparison.OrdinalIgnoreCase) < 0 && entry.Definition.Key.IndexOf(filter, StringComparison.OrdinalIgnoreCase) < 0 && entry.Definition.Section.IndexOf(filter, StringComparison.OrdinalIgnoreCase) < 0) { ConfigDescription description = entry.Description; return (((description != null) ? description.Description : null) ?? "").IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0; } return true; } public static void Row(Transform content, ConfigEntryBase entry, float rowWidth, Action onReset) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) GUIManager instance = GUIManager.Instance; float num = rowWidth - 300f - 100f - 50f; GameObject val = UiKit.Row(content, 50f, shaded: true); string text = DisplayName(entry); if (Attribute<bool?>(entry, "IsAdvanced") == true) { text = text + " <size=13><color=#a89a80>(" + T.Get("advanced") + ")</color></size>"; } Text obj = UiKit.Label(val.transform, text, 17, instance.ValheimBeige, bold: true, (TextAnchor)3); obj.supportRichText = true; UiKit.Place(((Component)obj).gameObject, 12f, 8f, num, 24f); float num2 = 50f; ConfigDescription description = entry.Description; string text2 = ((description != null) ? description.Description : null); if (!string.IsNullOrEmpty(text2)) { Text obj2 = UiKit.Label(val.transform, text2.Trim(), 14, new Color(0.72f, 0.68f, 0.6f), bold: false, (TextAnchor)0); obj2.verticalOverflow = (VerticalWrapMode)1; UiKit.Place(((Component)obj2).gameObject, 12f, 32f, num, 20f); float num3 = Mathf.Ceil(obj2.preferredHeight) + 2f; ((Graphic)obj2).rectTransform.sizeDelta = new Vector2(num, num3); num2 = Mathf.Max(num2, 32f + num3 + 8f); } val.GetComponent<LayoutElement>().preferredHeight = num2; val.GetComponent<LayoutElement>().minHeight = num2; GameObject val2 = new GameObject("Editor", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); UiKit.PlaceRight(val2, 120f, 300f, 34f); bool readOnly = Attribute<bool?>(entry, "ReadOnly") == true; Button reset = UiKit.Button(val.transform, T.Get("reset"), delegate { Set(entry, entry.DefaultValue); onReset(); }, 14); UiKit.PlaceRight(((Component)reset).gameObject, 10f, 100f, 32f); ((Component)reset).gameObject.SetActive(Attribute<bool?>(entry, "HideDefaultButton") != true); Action changed = delegate { UiKit.SetEnabled(reset, !readOnly && !object.Equals(entry.BoxedValue, entry.DefaultValue)); }; changed(); BuildEditor(val2.transform, entry, readOnly, delegate(object value) { Set(entry, value); changed(); }); } private static void BuildEditor(Transform parent, ConfigEntryBase entry, bool readOnly, Action<object> set) { //IL_027a: Unknown result type (might be due to invalid IL or missing references) Type type = entry.SettingType; ConfigDescription description = entry.Description; AcceptableValueBase acceptable = ((description != null) ? description.AcceptableValues : null); Type type2 = ((object)acceptable)?.GetType(); bool flag = type2 != null && type2.IsGenericType && type2.GetGenericTypeDefinition() == typeof(AcceptableValueList<>); bool flag2 = type2 != null && type2.IsGenericType && type2.GetGenericTypeDefinition() == typeof(AcceptableValueRange<>); if (type == typeof(bool)) { Toggle obj = UiKit.Toggle(parent, (bool)entry.BoxedValue, delegate(bool v) { set(v); }); UiKit.PlaceLeft(((Component)obj).gameObject, 0f, 28f, 28f); ((Selectable)obj).interactable = !readOnly; return; } bool flag3 = type.IsEnum && !type.IsDefined(typeof(FlagsAttribute), inherit: false) && Enum.GetValues(type).Length <= 60; object[] array = (flag ? ((Array)type2.GetProperty("AcceptableValues").GetValue(acceptable, null)).Cast<object>().ToArray() : null); if ((flag && array.Length <= 60) || (!flag && flag3)) { object[] values = array ?? Enum.GetValues(type).Cast<object>().ToArray(); string[] options = values.Select((object v) => ToText(v, type)).ToArray(); int val = Array.FindIndex(values, (object v) => object.Equals(v, entry.BoxedValue)); Dropdown obj2 = UiKit.Dropdown(parent, options, Math.Max(0, val), delegate(int i) { set(values[i]); }); UiKit.Stretch(((Component)obj2).gameObject); ((Selectable)obj2).interactable = !readOnly; return; } if (!TomlTypeConverter.CanConvert(type)) { UiKit.Stretch(((Component)UiKit.Label(parent, entry.BoxedValue?.ToString() ?? "", 15, GUIManager.Instance.ValheimBeige, bold: false, (TextAnchor)3)).gameObject); return; } InputField field = UiKit.Input(parent, ""); field.SetTextWithoutNotify(ToText(entry.BoxedValue, type)); ((Selectable)field).interactable = !readOnly; if (flag2 && IsNumber(type)) { float min = Convert.ToSingle(type2.GetProperty("MinValue").GetValue(acceptable, null)); float max = Convert.ToSingle(type2.GetProperty("MaxValue").GetValue(acceptable, null)); bool whole = type != typeof(float) && type != typeof(double) && type != typeof(decimal); Slider slider = UiKit.Slider(parent, min, max, Convert.ToSingle(entry.BoxedValue), whole, delegate(float v) { try { set(Convert.ChangeType(whole ? Math.Round(v) : Math.Round(v, 3), type)); } catch (OverflowException) { } field.SetTextWithoutNotify(ToText(entry.BoxedValue, type)); }); UiKit.PlaceLeft(((Component)slider).gameObject, 0f, 200f, 24f); ((Selectable)slider).interactable = !readOnly; UiKit.PlaceRight(((Component)field).gameObject, 0f, 90f, 34f); ((UnityEvent<string>)(object)field.onEndEdit).AddListener((UnityAction<string>)delegate(string text) { if (TryParse(text, type, acceptable, out var value)) { set(value); } field.SetTextWithoutNotify(ToText(entry.BoxedValue, type)); slider.SetValueWithoutNotify(Convert.ToSingle(entry.BoxedValue)); }); return; } UiKit.Stretch(((Component)field).gameObject); ((UnityEvent<string>)(object)field.onEndEdit).AddListener((UnityAction<string>)delegate(string text) { if (TryParse(text, type, acceptable, out var value)) { set(value); } field.SetTextWithoutNotify(ToText(entry.BoxedValue, type)); }); } private static void Set(ConfigEntryBase entry, object value) { try { entry.BoxedValue = value; } catch (Exception ex) { Plugin.Log.LogWarning((object)$"Setting {entry.Definition} raised an error in its mod: {ex.Message}"); } try { if (entry.ConfigFile != null && !entry.ConfigFile.SaveOnConfigSet) { entry.ConfigFile.Save(); } } catch (Exception ex2) { ManualLogSource log = Plugin.Log; ConfigFile configFile = entry.ConfigFile; log.LogWarning((object)("Could not save " + ((configFile != null) ? configFile.ConfigFilePath : null) + ": " + ex2.Message)); } } internal static bool TryParse(string text, Type type, AcceptableValueBase acceptable, out object value) { try { if (IsNumber(type)) { text = text.Trim().Replace(',', '.'); } value = TomlTypeConverter.ConvertToValue(text, type); bool flag = acceptable != null && ((object)acceptable).GetType().IsGenericType && ((object)acceptable).GetType().GetGenericTypeDefinition() == typeof(AcceptableValueRange<>); return acceptable == null || flag || acceptable.IsValid(value); } catch (Exception) { value = null; return false; } } private static string ToText(object value, Type type) { try { return TomlTypeConverter.ConvertToString(value, type); } catch (Exception) { return value?.ToString() ?? ""; } } private static bool IsNumber(Type type) { if (!(type == typeof(int)) && !(type == typeof(float)) && !(type == typeof(double)) && !(type == typeof(long)) && !(type == typeof(short)) && !(type == typeof(byte)) && !(type == typeof(uint)) && !(type == typeof(ulong)) && !(type == typeof(ushort)) && !(type == typeof(sbyte))) { return type == typeof(decimal); } return true; } private static TValue Attribute<TValue>(ConfigEntryBase entry, string field) { ConfigDescription description = entry.Description; object[] array = ((description != null) ? description.Tags : null); if (array == null) { return default(TValue); } object[] array2 = array; foreach (object obj in array2) { if (obj != null && !(obj.GetType().Name != "ConfigurationManagerAttributes")) { object obj2 = obj.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj) ?? obj.GetType().GetProperty(field, BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj, null); if (obj2 is TValue) { return (TValue)obj2; } } } return default(TValue); } } [HarmonyPatch(typeof(FejdStartup), "Start")] internal static class MainMenuButton { private const string ButtonName = "ModMenuButton"; private static void Postfix(FejdStartup __instance) { try { Add(__instance); } catch (Exception arg) { Plugin.Log.LogError((object)$"Could not add the main menu button: {arg}"); } } private static void Add(FejdStartup startup) { //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) GameObject menuList = startup.m_menuList; if ((Object)(object)menuList == (Object)null || menuList.GetComponentsInChildren<Transform>(true).Any((Transform t) => ((Object)t).name == "ModMenuButton")) { return; } Button[] componentsInChildren = menuList.GetComponentsInChildren<Button>(true); Button val = ((IEnumerable<Button>)componentsInChildren).FirstOrDefault((Func<Button, bool>)((Button b) => Calls(b, "OnButtonSettings"))) ?? componentsInChildren.LastOrDefault(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Main menu has no buttons to copy; the Mods button was not added."); return; } GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent); ((Object)val2).name = "ModMenuButton"; MonoBehaviour[] componentsInChildren2 = val2.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val3 in componentsInChildren2) { if (((object)val3).GetType().Name == "Localize") { Object.Destroy((Object)(object)val3); } } UIGamePad[] componentsInChildren3 = val2.GetComponentsInChildren<UIGamePad>(true); foreach (UIGamePad val4 in componentsInChildren3) { if ((Object)(object)val4.m_hint != (Object)null) { Object.Destroy((Object)(object)val4.m_hint); } Object.Destroy((Object)(object)val4); } SetLabel(val2, T.Get("menu_button")); Button component = val2.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { OpenWindow(startup); }); if ((Object)(object)((Component)val2.transform.parent).GetComponent<LayoutGroup>() != (Object)null) { val2.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex() + 1); } else { Button[] array = componentsInChildren.OrderByDescending((Button b) => ((RectTransform)((Component)b).transform).anchoredPosition.y).ToArray(); if (array.Length >= 2) { RectTransform val5 = (RectTransform)((Component)array[^1]).transform; RectTransform val6 = (RectTransform)((Component)array[^2]).transform; ((RectTransform)val2.transform).anchoredPosition = val5.anchoredPosition + (val5.anchoredPosition - val6.anchoredPosition); } } startup.m_menuButtons = menuList.GetComponentsInChildren<Button>(); Plugin.Log.LogInfo((object)("Main menu button added after \"" + ((Object)val).name + "\"")); } internal static void OpenWindow(FejdStartup startup) { startup.m_menuList.SetActive(false); ModMenuWindow.Open(delegate { if ((Object)(object)startup != (Object)null) { startup.m_menuList.SetActive(true); } }); } private static bool Calls(Button button, string method) { for (int i = 0; i < ((UnityEventBase)button.onClick).GetPersistentEventCount(); i++) { if (((UnityEventBase)button.onClick).GetPersistentMethodName(i) == method) { return true; } } return false; } private static void SetLabel(GameObject button, string text) { TMP_Text componentInChildren = button.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = text; return; } Text componentInChildren2 = button.GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.text = text; } } } internal sealed class ModMenuWindow : MonoBehaviour { private enum View { Mods, Config, Profiles } private const float Width = 1060f; private const float Height = 740f; private const float Margin = 30f; private const float ListTop = 158f; private const float RowWidth = 974f; private static ModMenuWindow _instance; private static bool _checkedThisSession; private View _view; private ModEntry _configMod; private Action _onClosed; private bool _dirty; private bool _typingLastFrame; private Text _title; private Text _status; private Button _back; private Button _profilesButton; private Button _updatesButton; private Text _updatesLabel; private Button _restartButton; private InputField _search; private Button _allOnButton; private InputField _profileName; private Button _profileSave; private InputField _configSearch; private readonly HashSet<string> _collapsed = new HashSet<string>(); private ModEntry _collapsedFor; private const int ExpandedLimit = 40; private RectTransform _list; public static bool IsOpen { get { if ((Object)(object)_instance != (Object)null) { return ((Component)_instance).gameObject.activeSelf; } return false; } } public static void Open(Action onClosed) { if ((Object)(object)_instance == (Object)null) { if (GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null) { Plugin.Log.LogWarning((object)"Jotunn GUI is not ready yet; the Mods window cannot open now."); onClosed?.Invoke(); return; } try { _instance = Create(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Could not build the Mods window: {arg}"); onClosed?.Invoke(); return; } } _instance._onClosed = onClosed; _instance._view = View.Mods; ((Component)_instance).gameObject.SetActive(true); ((Component)_instance).transform.SetAsLastSibling(); _instance.FitToScreen(); _instance.Rebuild(); if (!_checkedThisSession && Plugin.CheckUpdatesOnOpen.Value) { _checkedThisSession = true; _instance.StartUpdateCheck(); } } private void FitToScreen() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (((Object)(object)GUIManager.CustomGUIFront != (Object)null) ? GUIManager.CustomGUIFront.GetComponent<RectTransform>() : null); if (!((Object)(object)val != (Object)null)) { return; } Rect rect = val.rect; if (((Rect)(ref rect)).width > 0f) { rect = val.rect; if (((Rect)(ref rect)).height > 0f) { float[] obj = new float[3] { 1f, 0f, 0f }; rect = val.rect; obj[1] = (((Rect)(ref rect)).width - 40f) / 1060f; rect = val.rect; obj[2] = (((Rect)(ref rect)).height - 40f) / 740f; float num = Mathf.Min(obj); ((Component)this).transform.localScale = Vector3.one * Mathf.Max(0.5f, num); } } } public void Close() { ((Component)this).gameObject.SetActive(false); Action onClosed = _onClosed; _onClosed = null; onClosed?.Invoke(); } private void Update() { if (_dirty) { _dirty = false; Rebuild(); } EventSystem current = EventSystem.current; GameObject val = ((current != null) ? current.currentSelectedGameObject : null); InputField val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<InputField>() : null); bool flag = (Object)(object)val2 != (Object)null && val2.isFocused; bool typingLastFrame = _typingLastFrame; _typingLastFrame = flag; if ((ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("JoyButtonB")) && !flag && !typingLastFrame) { if (_view == View.Mods) { Close(); } else { ShowView(View.Mods); } } } private void OnDestroy() { if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } private static ModMenuWindow Create() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 1060f, 740f, false); ((Object)val).name = "ModMenuWindow"; ModMenuWindow modMenuWindow = val.AddComponent<ModMenuWindow>(); try { modMenuWindow.Build(val.transform); return modMenuWindow; } catch { Object.Destroy((Object)(object)val); throw; } } private void Build(Transform root) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) GUIManager instance = GUIManager.Instance; _back = UiKit.Button(root, "< " + T.Get("back"), delegate { ShowView(View.Mods); }); UiKit.Place(((Component)_back).gameObject, 30f, 26f, 120f, 40f); _title = UiKit.Label(root, "", 28, instance.ValheimOrange, bold: true, (TextAnchor)3); UiKit.Place(((Component)_title).gameObject, 30f, 26f, 520f, 40f); UiKit.Place(((Component)UiKit.Button(root, T.Get("close"), Close)).gameObject, 890f, 26f, 140f, 40f); _updatesButton = UiKit.Button(root, T.Get("check_updates"), StartUpdateCheck); _updatesLabel = ((Component)_updatesButton).GetComponentInChildren<Text>(); UiKit.Place(((Component)_updatesButton).gameObject, 640f, 26f, 240f, 40f); _profilesButton = UiKit.Button(root, T.Get("profiles"), delegate { ShowView(View.Profiles); }); UiKit.Place(((Component)_profilesButton).gameObject, 480f, 26f, 150f, 40f); _status = UiKit.Label(root, "", 16, instance.ValheimBeige, bold: false, (TextAnchor)3); UiKit.Place(((Component)_status).gameObject, 30f, 72f, 750f, 40f); _restartButton = UiKit.Button(root, T.Get("restart"), GameRestart.Restart); UiKit.Place(((Component)_restartButton).gameObject, 800f, 72f, 230f, 40f); _search = UiKit.Input(root, T.Get("search")); UiKit.Place(((Component)_search).gameObject, 30f, 116f, 360f, 34f); ((UnityEvent<string>)(object)_search.onValueChanged).AddListener((UnityAction<string>)delegate { RebuildList(); }); _allOnButton = UiKit.Button(root, T.Get("all_on"), delegate { ModCatalog.ReplaceWanted(new string[0]); _dirty = true; }); UiKit.Place(((Component)_allOnButton).gameObject, 400f, 114f, 220f, 38f); _profileName = UiKit.Input(root, T.Get("profile_name")); UiKit.Place(((Component)_profileName).gameObject, 30f, 116f, 360f, 34f); _profileSave = UiKit.Button(root, T.Get("profile_save"), delegate { if (Profiles.Save(_profileName.text, ModCatalog.WantedDisabled) != null) { _profileName.text = ""; } _dirty = true; }); UiKit.Place(((Component)_profileSave).gameObject, 400f, 114f, 220f, 38f); _configSearch = UiKit.Input(root, T.Get("config_search")); UiKit.Place(((Component)_configSearch).gameObject, 30f, 116f, 360f, 34f); ((UnityEvent<string>)(object)_configSearch.onValueChanged).AddListener((UnityAction<string>)delegate { _dirty = true; }); _list = UiKit.ScrollList(root, 30f, 158f, 30f, 30f); } private void ShowView(View view, ModEntry configMod = null) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) _view = view; if (configMod != null && configMod != _configMod) { _configSearch.SetTextWithoutNotify(""); } _configMod = configMod ?? _configMod; _list.anchoredPosition = Vector2.zero; _dirty = true; } private void Rebuild() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) bool flag = _view == View.Mods; ((Component)_back).gameObject.SetActive(!flag); ((Graphic)_title).rectTransform.anchoredPosition = new Vector2(flag ? 30f : 165f, -26f); ((Graphic)_title).rectTransform.sizeDelta = new Vector2(flag ? 420f : 705f, 40f); ((Component)_profilesButton).gameObject.SetActive(flag); ((Component)_updatesButton).gameObject.SetActive(flag); ((Component)_search).gameObject.SetActive(flag); ((Component)_allOnButton).gameObject.SetActive(flag && ModCatalog.PatcherActive); ((Component)_profileName).gameObject.SetActive(_view == View.Profiles); ((Component)_profileSave).gameObject.SetActive(_view == View.Profiles); ((Component)_configSearch).gameObject.SetActive(_view == View.Config); RefreshHeader(); RebuildList(); } private void RefreshHeader() { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) GUIManager instance = GUIManager.Instance; switch (_view) { case View.Mods: _title.text = T.Get("title", ModCatalog.Mods.Count); break; case View.Config: _title.text = T.Get("config_title", _configMod?.Name); break; case View.Profiles: _title.text = T.Get("profiles"); break; } _updatesLabel.text = (UpdateChecker.Running ? T.Get("checking", UpdateChecker.Progress, UpdateChecker.Total) : T.Get("check_updates")); UiKit.SetEnabled(_updatesButton, !UpdateChecker.Running); bool restartNeeded = ModCatalog.RestartNeeded; ((Component)_restartButton).gameObject.SetActive(restartNeeded); if (!ModCatalog.PatcherActive) { SetStatus(T.Get("no_patcher"), Color.red); } else if (restartNeeded) { SetStatus(T.Get("restart_needed"), instance.ValheimYellow); } else if (_view == View.Config) { SetStatus(T.Get("config_hint"), instance.ValheimBeige); } else if (_view != View.Mods) { SetStatus("", instance.ValheimBeige); } else if (UpdateChecker.LastError != null) { SetStatus(T.Get("update_error", UpdateChecker.LastError), new Color(1f, 0.5f, 0.4f)); } else if (UpdateChecker.Done) { int num = ModCatalog.Mods.Count((ModEntry m) => m.UpdateAvailable); SetStatus((num > 0) ? T.Get("updates_found", num) : T.Get("no_updates"), (num > 0) ? instance.ValheimOrange : instance.ValheimBeige); } else { SetStatus("", instance.ValheimBeige); } } private void SetStatus(string text, Color color) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) _status.text = text; ((Graphic)_status).color = color; } private void StartUpdateCheck() { if (UpdateChecker.Running) { return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(UpdateChecker.Run(ModCatalog.Mods, delegate { if (!((Object)(object)this == (Object)null) && ((Component)this).gameObject.activeSelf) { RefreshHeader(); if (!UpdateChecker.Running && _view == View.Mods) { RebuildList(); } } })); } private void RebuildList() { UiKit.Clear((Transform)(object)_list); switch (_view) { case View.Mods: BuildModRows(); break; case View.Config: BuildConfigRows(); break; case View.Profiles: BuildProfileRows(); break; } } private void BuildModRows() { //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) GUIManager instance = GUIManager.Instance; string text = _search.text.Trim(); int num = 0; foreach (ModEntry mod in ModCatalog.Mods) { if (text.Length > 0 && mod.Name.IndexOf(text, StringComparison.OrdinalIgnoreCase) < 0 && mod.Guid.IndexOf(text, StringComparison.OrdinalIgnoreCase) < 0) { continue; } GameObject val = UiKit.Row((Transform)(object)_list, 60f, num++ % 2 == 0); bool flag = ModCatalog.IsWantedDisabled(mod.Guid); Toggle obj = UiKit.Toggle(val.transform, !flag, delegate(bool on) { ModCatalog.SetWantedDisabled(mod.Guid, !on); _dirty = true; }); UiKit.PlaceLeft(((Component)obj).gameObject, 12f, 28f, 28f); ((Selectable)obj).interactable = ModCatalog.PatcherActive && !mod.Protected; Text obj2 = UiKit.Label(val.transform, mod.Name + " <size=14><color=#a89a80>v" + mod.Version + "</color></size>", 19, (Color)(flag ? new Color(0.6f, 0.6f, 0.6f) : instance.ValheimBeige), bold: true, (TextAnchor)3); obj2.supportRichText = true; UiKit.PlaceLeft(((Component)obj2).gameObject, 52f, 502f, 28f, 12f); Text obj3 = UiKit.Label(val.transform, "", 14, instance.ValheimBeige, bold: false, (TextAnchor)3); UiKit.PlaceLeft(((Component)obj3).gameObject, 52f, 502f, 24f, -14f); Text val2 = obj3; (string, Color) tuple = StateLine(mod, flag); val2.text = tuple.Item1; ((Graphic)obj3).color = tuple.Item2; Button obj4 = UiKit.Button(val.transform, T.Get("settings"), delegate { ShowView(View.Config, mod); }, 15); UiKit.PlaceRight(((Component)obj4).gameObject, 10f, 130f, 36f); UiKit.SetEnabled(obj4, (Object)(object)mod.Instance != (Object)null); string url = mod.Source?.PageUrl; if (url != null) { UiKit.PlaceRight(((Component)UiKit.Button(val.transform, T.Get("page"), delegate { Application.OpenURL(url); }, 15)).gameObject, 150f, 100f, 36f); } if (mod.LatestVersion != null) { UiKit.PlaceRight(((Component)UiKit.Label(val.transform, mod.UpdateAvailable ? T.Get("update", mod.LatestVersion) : T.Get("up_to_date"), 15, (Color)(mod.UpdateAvailable ? instance.ValheimOrange : new Color(0.55f, 0.75f, 0.5f)), bold: true, (TextAnchor)5)).gameObject, 260f, 150f, 40f); } } } private static (string, Color) StateLine(ModEntry mod, bool wantedOff) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) Color item = default(Color); ((Color)(ref item))..ctor(0.55f, 0.75f, 0.5f); Color item2 = default(Color); ((Color)(ref item2))..ctor(0.6f, 0.6f, 0.6f); Color valheimYellow = GUIManager.Instance.ValheimYellow; Color item3 = default(Color); ((Color)(ref item3))..ctor(1f, 0.45f, 0.4f); if (mod.Protected) { return (T.Get("protected"), item2); } bool flag = mod.State == ModState.Disabled; if (wantedOff && !flag) { List<ModEntry> list = (from d in ModCatalog.Dependents(mod.Guid) where !ModCatalog.IsWantedDisabled(d.Guid) select d).ToList(); string text = T.Get("state_off_next"); if (list.Count > 0) { text = text + " - " + T.Get("also_stops", string.Join(", ", list.Select((ModEntry d) => d.Name).ToArray())); } return (text, valheimYellow); } if (!wantedOff && flag) { List<string> list2 = ModCatalog.MissingDependencies(mod); return (T.Get("state_on_next") + ((list2.Count > 0) ? (" - " + T.Get("needs", string.Join(", ", list2.ToArray()))) : ""), valheimYellow); } switch (mod.State) { case ModState.Disabled: return (T.Get("state_disabled"), item2); case ModState.Failed: if (mod.OnlyFor != null) { return (T.Get("only_for", mod.OnlyFor), item2); } return (T.Get("state_failed") + ((mod.Error != null) ? (": " + mod.Error) : ""), item3); default: return (T.Get("state_loaded"), item); } } private void BuildConfigRows() { _ = GUIManager.Instance; List<ConfigFile> list = (((Object)(object)_configMod?.Instance != (Object)null) ? ConfigSources.For(_configMod.Instance) : new List<ConfigFile>()); if ((Object)(object)_configMod?.Instance == (Object)null) { Message(T.Get("config_off")); return; } List<(string, string, List<ConfigEntryBase>)> list2 = new List<(string, string, List<ConfigEntryBase>)>(); foreach (ConfigFile item2 in list) { string text = ((list.Count > 1) ? (Path.GetFileNameWithoutExtension(item2.ConfigFilePath) + " / ") : ""); foreach (IGrouping<string, ConfigEntryBase> item3 in ConfigEditors.Visible(item2).GroupBy(ConfigEditors.Category)) { list2.Add((item2.ConfigFilePath + "|" + item3.Key, text + item3.Key, item3.ToList())); } } if (list2.Count == 0) { Message(T.Get("config_none")); return; } if (_collapsedFor != _configMod) { _collapsedFor = _configMod; _collapsed.Clear(); if (list2.Sum<(string, string, List<ConfigEntryBase>)>(((string key, string title, List<ConfigEntryBase> entries) g) => g.entries.Count) > 40) { _collapsed.UnionWith(list2.Select<(string, string, List<ConfigEntryBase>), string>(((string key, string title, List<ConfigEntryBase> entries) g) => g.key)); } } string filter = _configSearch.text.Trim(); bool flag = filter.Length > 0; int num = 0; foreach (var item4 in list2) { string key = item4.Item1; string item = item4.Item2; List<ConfigEntryBase> list3 = item4.Item3.Where((ConfigEntryBase e) => ConfigEditors.Matches(e, filter)).ToList(); if (list3.Count == 0) { continue; } bool flag2 = flag || !_collapsed.Contains(key); SectionHeader(item, list3.Count, flag2, flag ? null : ((Action)delegate { if (!_collapsed.Remove(key)) { _collapsed.Add(key); } _dirty = true; })); if (!flag2) { continue; } foreach (ConfigEntryBase item5 in list3) { ConfigEditors.Row((Transform)(object)_list, item5, 974f, delegate { _dirty = true; }); num++; } } if (flag && num == 0) { Message(T.Get("config_no_match")); } } private void SectionHeader(string title, int count, bool open, Action toggle) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown GUIManager instance = GUIManager.Instance; GameObject val = UiKit.Row((Transform)(object)_list, 38f, shaded: false); string arg = ((toggle == null) ? "" : (open ? "[-] " : "[+] ")); Text obj = UiKit.Label(val.transform, $"{arg}{title} <size=15><color=#a89a80>({count})</color></size>", 21, instance.ValheimOrange, bold: true, (TextAnchor)3); obj.supportRichText = true; UiKit.Stretch(((Component)obj).gameObject); ((Graphic)obj).rectTransform.offsetMin = new Vector2(8f, 0f); if (toggle != null) { Image component = val.GetComponent<Image>(); ((Graphic)component).raycastTarget = true; ((Graphic)component).color = new Color(0f, 0f, 0f, 0.25f); Button obj2 = val.AddComponent<Button>(); ((Selectable)obj2).targetGraphic = (Graphic)(object)component; ((UnityEvent)obj2.onClick).AddListener((UnityAction)delegate { toggle(); }); } } private void Message(string text) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) UiKit.Stretch(((Component)UiKit.Label(UiKit.Row((Transform)(object)_list, 60f, shaded: false).transform, text, 18, GUIManager.Instance.ValheimBeige, bold: false, (TextAnchor)4)).gameObject); } private void BuildProfileRows() { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) GUIManager instance = GUIManager.Instance; List<string> list = Profiles.Names(); if (list.Count == 0) { Message(T.Get("profile_none")); return; } HashSet<string> wantedDisabled = ModCatalog.WantedDisabled; int num = 0; foreach (string profile in list) { HashSet<string> hashSet = Profiles.Read(profile); bool flag = hashSet.SetEquals(wantedDisabled); GameObject val = UiKit.Row((Transform)(object)_list, 54f, num++ % 2 == 0); UiKit.PlaceLeft(((Component)UiKit.Label(val.transform, profile + (flag ? (" " + T.Get("profile_active")) : ""), 19, flag ? instance.ValheimOrange : instance.ValheimBeige, bold: true, (TextAnchor)3)).gameObject, 14f, 480f, 28f, 10f); UiKit.PlaceLeft(((Component)UiKit.Label(val.transform, T.Get("profile_count", hashSet.Count), 14, new Color(0.65f, 0.6f, 0.5f), bold: false, (TextAnchor)3)).gameObject, 14f, 480f, 22f, -13f); UiKit.PlaceRight(((Component)UiKit.Button(val.transform, T.Get("profile_delete"), delegate { Profiles.Delete(profile); _dirty = true; }, 15)).gameObject, 10f, 120f, 36f); UiKit.PlaceRight(((Component)UiKit.Button(val.transform, T.Get("profile_overwrite"), delegate { Profiles.Save(profile, ModCatalog.WantedDisabled); _dirty = true; }, 15)).gameObject, 140f, 140f, 36f); Button obj = UiKit.Button(val.transform, T.Get("profile_load"), delegate { ModCatalog.ReplaceWanted(Profiles.Read(profile)); ShowView(View.Mods); }, 15); UiKit.PlaceRight(((Component)obj).gameObject, 290f, 140f, 36f); UiKit.SetEnabled(obj, ModCatalog.PatcherActive && !flag); } } } internal static class UiKit { public static GUIManager Gui => GUIManager.Instance; public static RectTransform Place(GameObject go, float x, float y, float width, float height) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown RectTransform val = (RectTransform)go.transform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 1f); val.pivot = val2; Vector2 anchorMin = (val.anchorMax = val2); val.anchorMin = anchorMin; val.anchoredPosition = new Vector2(x, 0f - y); val.sizeDelta = new Vector2(width, height); return val; } public static RectTransform PlaceRight(GameObject go, float right, float width, float height) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown RectTransform val = (RectTransform)go.transform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(1f, 0.5f); val.pivot = val2; Vector2 anchorMin = (val.anchorMax = val2); val.anchorMin = anchorMin; val.anchoredPosition = new Vector2(0f - right, 0f); val.sizeDelta = new Vector2(width, height); return val; } public static RectTransform PlaceLeft(GameObject go, float left, float width, float height, float y = 0f) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown RectTransform val = (RectTransform)go.transform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 0.5f); val.pivot = val2; Vector2 anchorMin = (val.anchorMax = val2); val.anchorMin = anchorMin; val.anchoredPosition = new Vector2(left, y); val.sizeDelta = new Vector2(width, height); return val; } public static void Stretch(GameObject go) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)go.transform; val.anchorMin = Vector2.zero; val.anchorMax = Vector2.one; Vector2 offsetMin = (val.offsetMax = Vector2.zero); val.offsetMin = offsetMin; } public static Text Label(Transform parent, string text, int size, Color color, bool bold = true, TextAnchor alignment = (TextAnchor)3) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) Text component = Gui.CreateText(text, parent, Vector2.zero, Vector2.zero, Vector2.zero, bold ? Gui.AveriaSerifBold : Gui.AveriaSerif, size, color, true, Color.black, 100f, 30f, false).GetComponent<Text>(); component.alignment = alignment; component.horizontalOverflow = (HorizontalWrapMode)0; component.verticalOverflow = (VerticalWrapMode)0; ((Graphic)component).raycastTarget = false; return component; } public static Button Button(Transform parent, string text, Action onClick, int fontSize = 16) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown GameObject obj = Gui.CreateButton(text, parent, Vector2.zero, Vector2.zero, Vector2.zero, 0f, 0f); Button component = obj.GetComponent<Button>(); Text componentInChildren = obj.GetComponentInChildren<Text>(); componentInChildren.fontSize = fontSize; Stretch(((Component)componentInChildren).gameObject); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { onClick(); }); return component; } public static void SetEnabled(Button button, bool enabled) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) ((Selectable)button).interactable = enabled; Text componentInChildren = ((Component)button).GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren != (Object)null) { Color color = ((Graphic)componentInChildren).color; color.a = (enabled ? 1f : 0.35f); ((Graphic)componentInChildren).color = color; } } public static InputField Input(Transform parent, string placeholder, int fontSize = 16) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) InputField component = Gui.CreateInputField(parent, Vector2.zero, Vector2.zero, Vector2.zero, (ContentType)0, placeholder, fontSize, 0f, 0f).GetComponent<InputField>(); Graphic[] array = (Graphic[])(object)new Graphic[2] { (Graphic)component.textComponent, component.placeholder }; foreach (Graphic obj in array) { RectTransform rectTransform = obj.rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = new Vector2(10f, 4f); rectTransform.offsetMax = new Vector2(-10f, -4f); Text val = (Text)(object)((obj is Text) ? obj : null); if (val != null) { val.alignment = (TextAnchor)3; } } return component; } public static Toggle Toggle(Transform parent, bool value, Action<bool> onChange, float size = 28f) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Gui.CreateToggle(parent, size, size); obj.transform.localScale = Vector3.one; obj.transform.localPosition = Vector3.zero; obj.transform.localRotation = Quaternion.identity; Toggle component = obj.GetComponent<Toggle>(); component.SetIsOnWithoutNotify(value); ((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool v) { onChange(v); }); Transform val = obj.transform.Find("Label"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } return component; } public static Dropdown Dropdown(Transform parent, string[] options, int value, Action<int> onChange) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Dropdown component = Gui.CreateDropDown(parent, Vector2.zero, Vector2.zero, Vector2.zero, 16, 300f, 32f).GetComponent<Dropdown>(); component.AddOptions(new List<string>(options)); component.SetValueWithoutNotify(value); ((UnityEvent<int>)(object)component.onValueChanged).AddListener((UnityAction<int>)delegate(int v) { onChange(v); }); return component; } public static Slider Slider(Transform parent, float min, float max, float value, bool whole, Action<float> onChange) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) GameObject obj = DefaultControls.CreateSlider(Gui.ValheimControlResources); obj.transform.SetParent(parent, false); Slider component = obj.GetComponent<Slider>(); Gui.ApplySliderStyle(component, new Vector2(16f, 24f)); component.minValue = min; component.maxValue = max; component.wholeNumbers = whole; component.SetValueWithoutNotify(value); ((UnityEvent<float>)(object)component.onValueChanged).AddListener((UnityAction<float>)delegate(float v) { onChange(v); }); return component; } public static RectTransform ScrollList(Transform parent, float left, float top, float right, float bottom) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown GameObject obj = DefaultControls.CreateScrollView(Gui.ValheimControlResources); ((Object)obj).name = "ModMenuList"; obj.transform.SetParent(parent, false); RectTransform val = (RectTransform)obj.transform; val.anchorMin = Vector2.zero; val.anchorMax = Vector2.one; val.offsetMin = new Vector2(left, bottom); val.offsetMax = new Vector2(0f - right, 0f - top); ScrollRect component = obj.GetComponent<ScrollRect>(); component.horizontal = false; component.movementType = (MovementType)2; if ((Object)(object)component.horizontalScrollbar != (Object)null) { Object.Destroy((Object)(object)((Component)component.horizontalScrollbar).gameObject); component.horizontalScrollbar = null; } component.verticalScrollbarVisibility = (ScrollbarVisibility)2; Gui.ApplyScrollRectStyle(component); RectTransform content = component.content; content.anchorMin = new Vector2(0f, 1f); content.anchorMax = new Vector2(1f, 1f); content.pivot = new Vector2(0.5f, 1f); Vector2 offsetMin = (content.offsetMax = Vector2.zero); content.offsetMin = offsetMin; VerticalLayoutGroup obj2 = ((Component)content).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj2).padding = new RectOffset(6, 6, 6, 6); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; ((Component)content).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; return content; } public static GameObject Row(Transform content, float height, bool shaded) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown GameObject val = new GameObject("Row", new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val.transform.SetParent(content, false); val.GetComponent<LayoutElement>().preferredHeight = height; val.GetComponent<LayoutElement>().minHeight = height; Image component = val.GetComponent<Image>(); ((Graphic)component).color = (shaded ? new Color(1f, 1f, 1f, 0.05f) : new Color(0f, 0f, 0f, 0f)); ((Graphic)component).raycastTarget = false; return val; } public static void Clear(Transform content) { for (int num = content.childCount - 1; num >= 0; num--) { GameObject gameObject = ((Component)content.GetChild(num)).gameObject; gameObject.SetActive(false); Object.Destroy((Object)(object)gameObject); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }