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 MegingjordReforged v1.0.0
Plugins/MegingjordReforged.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using MegingjordReforged.Source.Config; using MegingjordReforged.Source.Definitions; using MegingjordReforged.Source.Items; using MegingjordReforged.Source.Managers; using MegingjordReforged.Source.Registry; using MegingjordReforged.Source.StatusEffects; using MegingjordReforged.Source.Utilities; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 MegingjordReforged { [BepInPlugin("NoxiousVex.MegingjordReforged", "Megingjord Reforged: Enhanced Belt Variants", "1.0.0")] public class Plugin : BaseUnityPlugin { private const string ModGUID = "NoxiousVex.MegingjordReforged"; private const string ModName = "Megingjord Reforged: Enhanced Belt Variants"; public const string ModVersion = "1.0.0"; private void Awake() { try { ModLogger.LogStart("================================="); ModLogger.LogStart("Megingjord Reforged: Enhanced Belt Variants : v1.0.0 loading..."); ConfigManager.Load(((BaseUnityPlugin)this).Config); VersionManager.Verify(ConfigManager.ConfigPath); if (!ConfigManager.Current.General.EnableMod) { ModLogger.LogWarning("Megingjord Reforged is disabled in configuration."); return; } BeltRegistry.RegisterBelts(); ServerSyncRegistry.RegisterSyncDefinitions(); ServerSyncManager.Initialize(); PrefabManager.OnVanillaPrefabsAvailable += InitializeAfterPrefabs; ModLogger.LogDebug("Waiting for vanilla prefab availability..."); } catch (Exception arg) { ModLogger.LogError(string.Format("{0} failed during initialization: {1}", "Megingjord Reforged: Enhanced Belt Variants", arg)); ModLogger.LogStart("================================="); } } private static void InitializeAfterPrefabs() { try { ModLogger.LogDebug("Vanilla prefabs available. Initializing content..."); StatusEffectRegistry.RegisterStatusEffects(); BeltPrefabManager.RegisterBelts(); BeltItemManager.RegisterRecipes(); ModLogger.LogStart("Megingjord Reforged: Enhanced Belt Variants : v1.0.0 loaded successfully."); ModLogger.LogStart("================================="); } catch (Exception arg) { ModLogger.LogError($"Prefab initialization failed: {arg}"); } } } } namespace MegingjordReforged.Source.Utilities { public static class ConfigFormatter { private static readonly string[] PreferredSectionOrder = new string[13] { "General", "Logging", "Belts - Aedigjord", "Belts - Aedigjord - Effects", "Belts - Seidgjord", "Belts - Seidgjord - Effects", "Belts - Skadigjord", "Belts - Skadigjord - Effects", "Belts - Alagjord", "Belts - Alagjord - Effects", "Belts - Fornmegingjord", "Belts - Fornmegingjord - Effects", "Advanced" }; private const string FormatVersionKey = "# MegingjordReforged Config Format Version:"; public static int GetStoredFormatVersion(string configPath) { if (string.IsNullOrWhiteSpace(configPath) || !File.Exists(configPath)) { return 0; } try { string[] array = File.ReadAllLines(configPath, Encoding.UTF8); foreach (string text in array) { if (text.StartsWith("# MegingjordReforged Config Format Version:", StringComparison.OrdinalIgnoreCase) && int.TryParse(text.Replace("# MegingjordReforged Config Format Version:", string.Empty).Trim(), out var result)) { return result; } } } catch (Exception ex) { ModLogger.LogWarning("Unable to read configuration format version: " + ex.Message); } return 0; } public static void Format(string configPath, int formatVersion) { if (string.IsNullOrWhiteSpace(configPath)) { ModLogger.LogWarning("ConfigFormatter received an invalid path."); return; } if (!File.Exists(configPath)) { ModLogger.LogWarning("Configuration file does not exist: " + configPath); return; } try { string[] lines = File.ReadAllLines(configPath, Encoding.UTF8); List<string> list = new List<string>(); List<string> list2 = BuildFormattedConfiguration(ParseSections(lines, list)); list2.InsertRange(0, list); AddFormatVersion(list2, formatVersion); WriteFormattedFile(configPath, list2); ModLogger.LogInfo($"Configuration formatted to version {formatVersion}."); } catch (Exception arg) { ModLogger.LogError($"Config formatting failed: {arg}"); } } private static Dictionary<string, List<string>> ParseSections(string[] lines, List<string> header) { Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase); string text = null; foreach (string text2 in lines) { string text3 = text2.Trim(); if (text3.StartsWith("[") && text3.EndsWith("]")) { text = text3.Substring(1, text3.Length - 2).Trim(); if (!dictionary.ContainsKey(text)) { dictionary[text] = new List<string>(); } } else if (text == null) { header.Add(text2); } else { dictionary[text].Add(text2); } } return dictionary; } private static List<string> BuildFormattedConfiguration(Dictionary<string, List<string>> sections) { List<string> list = new List<string>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); string[] preferredSectionOrder = PreferredSectionOrder; foreach (string text in preferredSectionOrder) { if (sections.TryGetValue(text, out List<string> value)) { WriteSection(list, text, value); hashSet.Add(text); } } foreach (KeyValuePair<string, List<string>> section in sections) { if (!hashSet.Contains(section.Key)) { WriteSection(list, section.Key, section.Value); } } return list; } private static void WriteSection(List<string> output, string name, List<string> contents) { if (output.Count > 0) { output.Add(string.Empty); } output.Add("[" + name + "]"); output.AddRange(contents); } private static void AddFormatVersion(List<string> lines, int version) { lines.RemoveAll((string line) => line.StartsWith("# MegingjordReforged Config Format Version:", StringComparison.OrdinalIgnoreCase)); lines.Insert(0, string.Format("{0} {1}", "# MegingjordReforged Config Format Version:", version)); lines.Insert(1, string.Empty); } private static void WriteFormattedFile(string path, List<string> lines) { string text = path + ".tmp"; try { File.WriteAllLines(text, NormalizeSpacing(lines), Encoding.UTF8); File.Copy(text, path, overwrite: true); File.Delete(text); } catch { if (File.Exists(text)) { File.Delete(text); } throw; } } private static List<string> NormalizeSpacing(List<string> lines) { List<string> list = new List<string>(); bool flag = false; foreach (string line in lines) { bool flag2 = string.IsNullOrWhiteSpace(line); if (!(flag2 && flag)) { list.Add(line); flag = flag2; } } return list; } } public static class ConfigValueConverter { public static float RegenMultiplier(float percentage) { return 1f + percentage / 100f; } public static float RegenMultiplier(float percentage, float minimum, float maximum) { return RegenMultiplier(Mathf.Clamp(percentage, minimum, maximum)); } public static float PercentageToMultiplier(float percentage) { return percentage / 100f; } public static float Multiplier(float percentage) { return PercentageToMultiplier(percentage); } public static float Multiplier(float percentage, float minimum, float maximum) { return PercentageToMultiplier(Mathf.Clamp(percentage, minimum, maximum)); } public static float Flat(float value, float minimum, float maximum) { return Mathf.Clamp(value, minimum, maximum); } } public static class ModLogger { public static void LogStart(string message) { WriteInfo("[Startup] " + message); } public static void LogDebug(string message) { if (IsDebugEnabled()) { WriteInfo("[Debug] " + message); } } public static void LogInfo(string message) { if (IsInfoEnabled()) { WriteInfo("[Info] " + message); } } public static void LogWarning(string message) { if (IsWarningEnabled()) { WriteWarning("[Warning] " + message); } } public static void LogError(string message) { WriteError("[Error] " + message); } private static bool IsDebugEnabled() { if (ConfigManager.Current == null) { return false; } return ConfigManager.Current.Logging == ConfigLoggingMode.Debug; } private static bool IsInfoEnabled() { if (ConfigManager.Current == null) { return false; } if (ConfigManager.Current.Logging != ConfigLoggingMode.Standard) { return ConfigManager.Current.Logging == ConfigLoggingMode.Debug; } return true; } private static bool IsWarningEnabled() { if (ConfigManager.Current == null) { return true; } return ConfigManager.Current.Logging != ConfigLoggingMode.Minimal; } private static void WriteInfo(string message) { Logger.LogInfo((object)message); } private static void WriteWarning(string message) { Logger.LogWarning((object)message); } private static void WriteError(string message) { Logger.LogError((object)message); } } public static class ServerSyncSerializer { public static ZPackage Serialize(ServerSyncPackage package) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(package.Version); val.Write(package.SchemaVersion); val.Write(package.Values.Count); foreach (KeyValuePair<string, string> value in package.Values) { val.Write(value.Key); val.Write(value.Value); } return val; } public static ServerSyncPackage Deserialize(ZPackage package) { ServerSyncPackage serverSyncPackage = new ServerSyncPackage(); serverSyncPackage.Version = package.ReadString(); serverSyncPackage.SchemaVersion = package.ReadInt(); int num = package.ReadInt(); for (int i = 0; i < num; i++) { string key = package.ReadString(); string value = package.ReadString(); serverSyncPackage.Values[key] = value; } return serverSyncPackage; } } } namespace MegingjordReforged.Source.StatusEffects { public class SE_Aedigjord : SE_Stats { public SE_Aedigjord() { ((Object)this).name = "SE_Aedigjord"; ((StatusEffect)this).m_name = "Aedigjord"; ((StatusEffect)this).m_tooltip = "Fueled by fury and the strength of forgotten heroes."; ApplyConfiguration(); } public void ApplyConfiguration() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) BeltEffectOptions effects = ConfigResolveManager.GetBeltOptions("Aedigjord").Effects; base.m_addMaxCarryWeight = 0f; base.m_addArmor = 0f; base.m_healthRegenMultiplier = 1f; base.m_attackStaminaUseModifier = 0f; base.m_addMaxCarryWeight = ConfigValueConverter.Flat(effects.CarryWeight, 0f, 500f); base.m_addArmor = ConfigValueConverter.Flat(effects.Armor, 0f, 25f); base.m_healthRegenMultiplier = ConfigValueConverter.RegenMultiplier(effects.HealthRegenModifier); base.m_attackStaminaUseModifier = ConfigValueConverter.PercentageToMultiplier(effects.AttackStaminaUseModifier); base.m_percentigeDamageModifiers.m_slash = 0.2f; base.m_percentigeDamageModifiers.m_blunt = 0.3f; base.m_skillLevel = (SkillType)3; base.m_skillLevelModifier = 30f; base.m_skillLevel2 = (SkillType)1; base.m_skillLevelModifier2 = 20f; base.m_adrenalineModifier = 1f; } } public class SE_Alagjord : SE_Stats { public SE_Alagjord() { ((Object)this).name = "SE_Alagjord"; ((StatusEffect)this).m_name = "Alagjord"; ((StatusEffect)this).m_tooltip = "Its wearer moves as freely as the waves themselves."; ApplyConfiguration(); } public void ApplyConfiguration() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) BeltEffectOptions effects = ConfigResolveManager.GetBeltOptions("Alagjord").Effects; base.m_addMaxCarryWeight = 0f; base.m_staminaRegenMultiplier = 1f; base.m_swimStaminaUseModifier = 0f; base.m_addMaxCarryWeight = ConfigValueConverter.Flat(effects.CarryWeight, 0f, 500f); base.m_staminaRegenMultiplier = ConfigValueConverter.RegenMultiplier(effects.StaminaRegenModifier); base.m_swimStaminaUseModifier = ConfigValueConverter.Multiplier(effects.SwimStaminaUseModifier); base.m_swimSpeedModifier = 0.3f; base.m_skillLevel = (SkillType)103; base.m_skillLevelModifier = 35f; base.m_skillLevel2 = (SkillType)104; base.m_skillLevelModifier2 = 20f; } } public class SE_Fornmegingjord : SE_Stats { public SE_Fornmegingjord() { ((Object)this).name = "SE_Fornmegingjord"; ((StatusEffect)this).m_name = "Fornmegingjord"; ((StatusEffect)this).m_tooltip = "A treasure worthy of heroes and kings."; ApplyConfiguration(); } public void ApplyConfiguration() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) BeltEffectOptions effects = ConfigResolveManager.GetBeltOptions("Fornmegingjord").Effects; base.m_addMaxCarryWeight = 0f; base.m_addMaxCarryWeight = ConfigValueConverter.Flat(effects.CarryWeight, 0f, 1000f); base.m_percentigeDamageModifiers.m_spirit = 0.4f; base.m_percentigeDamageModifiers.m_lightning = 0.3f; base.m_skillLevel = (SkillType)13; base.m_skillLevelModifier = 25f; base.m_skillLevel2 = (SkillType)12; base.m_skillLevelModifier2 = 25f; } } public class SE_Seidgjord : SE_Stats { public SE_Seidgjord() { ((Object)this).name = "SE_Seidgjord"; ((StatusEffect)this).m_name = "Seidgjord"; ((StatusEffect)this).m_tooltip = "Carrying the whispers of forgotten runes and arcane power."; ApplyConfiguration(); } public void ApplyConfiguration() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) BeltEffectOptions effects = ConfigResolveManager.GetBeltOptions("Seidgjord").Effects; base.m_addMaxCarryWeight = 0f; base.m_healthRegenMultiplier = 1f; base.m_staminaRegenMultiplier = 1f; base.m_eitrRegenMultiplier = 1f; base.m_addMaxCarryWeight = ConfigValueConverter.Flat(effects.CarryWeight, 0f, 500f); base.m_healthRegenMultiplier = ConfigValueConverter.RegenMultiplier(effects.HealthRegenModifier); base.m_staminaRegenMultiplier = ConfigValueConverter.RegenMultiplier(effects.StaminaRegenModifier); base.m_eitrRegenMultiplier = ConfigValueConverter.RegenMultiplier(effects.EitrRegenModifier); base.m_skillLevel = (SkillType)9; base.m_skillLevelModifier = 30f; base.m_skillLevel2 = (SkillType)10; base.m_skillLevelModifier2 = 20f; } } public class SE_Skadigjord : SE_Stats { public SE_Skadigjord() { ((Object)this).name = "SE_Skadigjord"; ((StatusEffect)this).m_name = "Skadigjord"; ((StatusEffect)this).m_tooltip = "Light as the wind, granting unmatched speed and agility."; ApplyConfiguration(); } public void ApplyConfiguration() { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) BeltEffectOptions effects = ConfigResolveManager.GetBeltOptions("Skadigjord").Effects; base.m_addMaxCarryWeight = 0f; base.m_staminaRegenMultiplier = 1f; base.m_runStaminaUseModifier = 0f; base.m_jumpStaminaUseModifier = 0f; base.m_dodgeStaminaUseModifier = 0f; base.m_sneakStaminaUseModifier = 0f; base.m_addMaxCarryWeight = ConfigValueConverter.Flat(effects.CarryWeight, 0f, 500f); base.m_staminaRegenMultiplier = ConfigValueConverter.RegenMultiplier(effects.StaminaRegenModifier); base.m_runStaminaUseModifier = ConfigValueConverter.PercentageToMultiplier(effects.RunStaminaUseModifier); base.m_jumpStaminaUseModifier = ConfigValueConverter.PercentageToMultiplier(effects.JumpStaminaUseModifier); base.m_dodgeStaminaUseModifier = ConfigValueConverter.PercentageToMultiplier(effects.DodgeStaminaUseModifier); base.m_sneakStaminaUseModifier = ConfigValueConverter.PercentageToMultiplier(effects.SneakStaminaUseModifier); base.m_percentigeDamageModifiers.m_pierce = 0.3f; base.m_skillLevel = (SkillType)8; base.m_skillLevelModifier = 20f; base.m_skillLevel2 = (SkillType)14; base.m_skillLevelModifier2 = 35f; } } } namespace MegingjordReforged.Source.Registry { public static class BeltEffectRegistry { private static readonly Dictionary<string, List<BeltEffectDefinition>> Effects = new Dictionary<string, List<BeltEffectDefinition>>(); public static void RegisterEffects() { Effects.Clear(); RegisterAedigjordEffects(); RegisterAlagjordEffects(); RegisterFornmegingjordEffects(); RegisterSeidgjordEffects(); RegisterSkadigjordEffects(); } public static IReadOnlyList<BeltEffectDefinition> GetEffects(string beltName) { if (Effects.TryGetValue(beltName, out List<BeltEffectDefinition> value)) { return value; } return new List<BeltEffectDefinition>(); } private static void RegisterAedigjordEffects() { Effects["Aedigjord"] = new List<BeltEffectDefinition> { new BeltEffectDefinition { EffectName = "addMaxCarryWeight", DefaultValue = 250f, MinimumValue = 0f, MaximumValue = 500f, AllowZero = true, Description = "Additional maximum carry weight." }, new BeltEffectDefinition { EffectName = "addArmor", DefaultValue = 25f, MinimumValue = 0f, MaximumValue = 25f, AllowZero = true, Description = "Additional armor granted by the belt." }, new BeltEffectDefinition { EffectName = "healthRegenMultiplier", DefaultValue = -0.25f, MinimumValue = -1f, MaximumValue = 3f, AllowZero = true, Description = "Health regeneration modifier." }, new BeltEffectDefinition { EffectName = "attackStaminaUseModifier", DefaultValue = -0.5f, MinimumValue = -0.01f, MaximumValue = 1f, AllowZero = true, Description = "Attack stamina consumption modifier." } }; } private static void RegisterAlagjordEffects() { Effects["Alagjord"] = new List<BeltEffectDefinition>(); } private static void RegisterFornmegingjordEffects() { Effects["Fornmegingjord"] = new List<BeltEffectDefinition>(); } private static void RegisterSeidgjordEffects() { Effects["Seidgjord"] = new List<BeltEffectDefinition>(); } private static void RegisterSkadigjordEffects() { Effects["Skadigjord"] = new List<BeltEffectDefinition>(); } } public static class BeltRegistry { public static readonly Dictionary<string, BeltDefinition> Belts = new Dictionary<string, BeltDefinition>(); public static void RegisterBelts() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Expected O, but got Unknown //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Expected O, but got Unknown //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Expected O, but got Unknown //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Expected O, but got Unknown //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Expected O, but got Unknown //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Expected O, but got Unknown //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Expected O, but got Unknown ModLogger.LogDebug("Registering belt definitions..."); Belts.Clear(); BeltDefinition beltDefinition = new BeltDefinition(); beltDefinition.ConfigKey = "Aedigjord"; beltDefinition.PrefabName = "MR_Aedigjord"; beltDefinition.DisplayName = "Aedigjord"; beltDefinition.Description = "A reforged warrior's girdle infused with the fury of battle rage."; beltDefinition.IconName = "Aedigjord.png"; beltDefinition.TextureName = "Aedigjord_d.png"; beltDefinition.Type = BeltType.BeltAedigjord; beltDefinition.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig { Item = "BeltStrength", Amount = 1 }, new RequirementConfig { Item = "GemstoneRed", Amount = 3 } }; AddBelt(beltDefinition); beltDefinition = new BeltDefinition(); beltDefinition.ConfigKey = "Seidgjord"; beltDefinition.PrefabName = "MR_Seidgjord"; beltDefinition.DisplayName = "Seidgjord"; beltDefinition.Description = "A mystical girdle empowered by ancient seiðr magic."; beltDefinition.IconName = "Seidgjord.png"; beltDefinition.TextureName = "Seidgjord_d.png"; beltDefinition.Type = BeltType.BeltSeidgjord; beltDefinition.Requirements = (RequirementConfig[])(object)new RequirementConfig[4] { new RequirementConfig { Item = "BeltStrength", Amount = 1 }, new RequirementConfig { Item = "GemstoneRed", Amount = 1 }, new RequirementConfig { Item = "GemstoneBlue", Amount = 1 }, new RequirementConfig { Item = "Eitr", Amount = 20 } }; AddBelt(beltDefinition); beltDefinition = new BeltDefinition(); beltDefinition.ConfigKey = "Skadigjord"; beltDefinition.PrefabName = "MR_Skadigjord"; beltDefinition.DisplayName = "Skadigjord"; beltDefinition.Description = "A hunter's girdle blessed with the swiftness of the wild."; beltDefinition.IconName = "Skadigjord.png"; beltDefinition.TextureName = "Skadigjord_d.png"; beltDefinition.Type = BeltType.BeltSkadigjord; beltDefinition.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig { Item = "BeltStrength", Amount = 1 }, new RequirementConfig { Item = "GemstoneGreen", Amount = 3 } }; AddBelt(beltDefinition); beltDefinition = new BeltDefinition(); beltDefinition.ConfigKey = "Alagjord"; beltDefinition.PrefabName = "MR_Alagjord"; beltDefinition.DisplayName = "Alagjord"; beltDefinition.Description = "A sea-forged girdle granting mastery over the waves."; beltDefinition.IconName = "Alagjord.png"; beltDefinition.TextureName = "Alagjord_d.png"; beltDefinition.Type = BeltType.BeltAlagjord; beltDefinition.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig { Item = "BeltStrength", Amount = 1 }, new RequirementConfig { Item = "GemstoneBlue", Amount = 3 } }; AddBelt(beltDefinition); beltDefinition = new BeltDefinition(); beltDefinition.ConfigKey = "Fornmegingjord"; beltDefinition.PrefabName = "MR_Fornmegingjord"; beltDefinition.DisplayName = "Fornmegingjord"; beltDefinition.Description = "An ancient relic containing the forgotten strength of Thor's Megingjord."; beltDefinition.IconName = "Fornmegingjord.png"; beltDefinition.TextureName = "Fornmegingjord_d.png"; beltDefinition.Type = BeltType.BeltFornmegingjord; beltDefinition.Requirements = (RequirementConfig[])(object)new RequirementConfig[4] { new RequirementConfig { Item = "BeltStrength", Amount = 1 }, new RequirementConfig { Item = "GemstoneRed", Amount = 3 }, new RequirementConfig { Item = "GemstoneBlue", Amount = 3 }, new RequirementConfig { Item = "GemstoneGreen", Amount = 3 } }; AddBelt(beltDefinition); ModLogger.LogDebug($"Registered {Belts.Count} belt definitions."); } private static void AddBelt(BeltDefinition belt) { Belts[belt.PrefabName] = belt; ModLogger.LogDebug("Added belt definition: " + belt.PrefabName); } public static bool IsBelt(string prefabName) { return Belts.ContainsKey(prefabName); } public static BeltDefinition? GetBelt(string prefabName) { if (Belts.TryGetValue(prefabName, out BeltDefinition value)) { return value; } return null; } } public static class ServerSyncRegistry { private static readonly List<ServerSyncDefinition> Definitions = new List<ServerSyncDefinition>(); public static IReadOnlyList<ServerSyncDefinition> SyncDefinitions => Definitions; public static IReadOnlyCollection<string> GetSyncedKeys() { List<string> list = new List<string>(); foreach (ServerSyncDefinition definition in Definitions) { if (definition.Enabled) { list.Add(definition.Identifier); } } return list; } public static void RegisterSyncDefinitions() { Definitions.Clear(); RegisterGeneral(); RegisterBelts(); RegisterBeltEffects(); RegisterAdvanced(); } private static void RegisterGeneral() { Register("General", "Enable Mod", "General.EnableMod"); Register("General", "Enable Server Sync", "General.EnableServerSync"); } private static void RegisterBelts() { string[] array = new string[5] { "Aedigjord", "Seidgjord", "Skadigjord", "Alagjord", "Fornmegingjord" }; foreach (string text in array) { Register("Belts - " + text, "Recipe", "Belts." + text + ".Recipe"); Register("Belts - " + text, "Crafting Station", "Belts." + text + ".CraftingStation"); Register("Belts - " + text, "Crafting Station Level", "Belts." + text + ".CraftingStationLevel"); } } private static void RegisterBeltEffects() { string[] array = new string[5] { "Aedigjord", "Seidgjord", "Skadigjord", "Alagjord", "Fornmegingjord" }; foreach (string belt in array) { RegisterEffect(belt, "Carry Weight", "CarryWeight"); RegisterEffect(belt, "Armor", "Armor"); RegisterEffect(belt, "Health Regen Modifier", "HealthRegenModifier"); RegisterEffect(belt, "Stamina Regen Modifier", "StaminaRegenModifier"); RegisterEffect(belt, "Eitr Regen Modifier", "EitrRegenModifier"); RegisterEffect(belt, "Attack Stamina Use Modifier", "AttackStaminaUseModifier"); RegisterEffect(belt, "Swim Stamina Use Modifier", "SwimStaminaUseModifier"); RegisterEffect(belt, "Run Stamina Use Modifier", "RunStaminaUseModifier"); RegisterEffect(belt, "Jump Stamina Use Modifier", "JumpStaminaUseModifier"); RegisterEffect(belt, "Dodge Stamina Use Modifier", "DodgeStaminaUseModifier"); RegisterEffect(belt, "Sneak Stamina Use Modifier", "SneakStaminaUseModifier"); } } private static void RegisterEffect(string belt, string displayName, string effectKey) { Register("Belts - " + belt + " - Effects", displayName, "Belts." + belt + ".Effects." + effectKey); } private static void RegisterAdvanced() { Register("Advanced", "Experimental Features", "Advanced.ExperimentalFeatures"); } private static void Register(string section, string key, string identifier) { Definitions.Add(new ServerSyncDefinition { Section = section, Key = key, Identifier = identifier, Enabled = true }); } } public static class StatusEffectRegistry { private static bool _registered; public static SE_Aedigjord? Aedigjord { get; private set; } public static SE_Seidgjord? Seidgjord { get; private set; } public static SE_Skadigjord? Skadigjord { get; private set; } public static SE_Alagjord? Alagjord { get; private set; } public static SE_Fornmegingjord? Fornmegingjord { get; private set; } public static void RegisterStatusEffects() { if (_registered) { ModLogger.LogDebug("Status effects have already been registered."); return; } ModLogger.LogDebug("Registering Megingjord Reforged status effects..."); Aedigjord = CreateEffect<SE_Aedigjord>("Aedigjord"); Seidgjord = CreateEffect<SE_Seidgjord>("Seidgjord"); Skadigjord = CreateEffect<SE_Skadigjord>("Skadigjord"); Alagjord = CreateEffect<SE_Alagjord>("Alagjord"); Fornmegingjord = CreateEffect<SE_Fornmegingjord>("Fornmegingjord"); _registered = true; ModLogger.LogDebug("Completed status effect registration."); } public static void RefreshStatusEffects() { if (!_registered) { ModLogger.LogWarning("Cannot refresh status effects before registration."); return; } ModLogger.LogDebug("Refreshing Megingjord Reforged status effects..."); Aedigjord?.ApplyConfiguration(); Seidgjord?.ApplyConfiguration(); Skadigjord?.ApplyConfiguration(); Alagjord?.ApplyConfiguration(); Fornmegingjord?.ApplyConfiguration(); ModLogger.LogDebug("Finished refreshing status effects."); } private static T? CreateEffect<T>(string configKey) where T : StatusEffect { if (!IsEnabled(configKey)) { ModLogger.LogDebug("Status effect disabled: " + configKey); return default(T); } T val = ScriptableObject.CreateInstance<T>(); ApplyEffectIcon((StatusEffect)(object)val, configKey); RegisterEffect((StatusEffect)(object)val); return val; } private static void ApplyEffectIcon(StatusEffect effect, string configKey) { BeltDefinition belt = BeltRegistry.GetBelt("MR_" + configKey); if (belt == null) { ModLogger.LogWarning("Could not locate belt definition for status effect: " + ((Object)effect).name); return; } Sprite val = BeltIconManager.LoadIcon(belt.IconName); if ((Object)(object)val == (Object)null) { ModLogger.LogWarning("Could not load icon for status effect: " + ((Object)effect).name); return; } effect.m_icon = val; ModLogger.LogDebug("Assigned status effect icon: " + ((Object)effect).name); } private static void RegisterEffect(StatusEffect effect) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if ((Object)(object)effect == (Object)null) { ModLogger.LogWarning("Attempted to register null status effect."); return; } if ((Object)(object)effect.m_icon == (Object)null) { ModLogger.LogWarning("Status effect " + ((Object)effect).name + " registered without an icon."); } ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(effect, true)); ModLogger.LogInfo("Registered status effect: " + ((Object)effect).name); } private static bool IsEnabled(string configKey) { ConfigManager.Current.Belts.GetBeltOptions(configKey); return true; } } } namespace MegingjordReforged.Source.Items { public static class BeltItemManager { private static readonly Dictionary<string, CustomRecipe> RegisteredRecipes = new Dictionary<string, CustomRecipe>(); private static bool _registered; public static void RegisterRecipes() { if (_registered) { ModLogger.LogDebug("Recipes have already been registered."); return; } _registered = true; ModLogger.LogDebug("Registering Megingjord Reforged recipes..."); foreach (BeltDefinition value in BeltRegistry.Belts.Values) { RegisterRecipe(value); } ModLogger.LogDebug("Finished registering belt recipes."); } public static void RefreshRecipes() { ModLogger.LogDebug("Refreshing belt recipes..."); ClearRecipes(); RegisterRecipes(); ModLogger.LogDebug("Finished refreshing belt recipes."); } private static void ClearRecipes() { foreach (CustomRecipe value in RegisteredRecipes.Values) { ItemManager.Instance.RemoveRecipe(value); } RegisteredRecipes.Clear(); _registered = false; ModLogger.LogDebug("Cleared Megingjord Reforged recipes."); } private static void RegisterRecipe(BeltDefinition belt) { //IL_0043: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown IndividualBeltOptions beltOptions = ConfigResolveManager.GetBeltOptions(belt.ConfigKey); if (beltOptions.CraftingStation == CraftingStationType.Disabled) { ModLogger.LogDebug("Recipe disabled: " + belt.PrefabName); return; } string text = "Recipe_" + belt.PrefabName; RequirementConfig[] requirements = GetRequirements(belt, beltOptions); CustomRecipe val = new CustomRecipe(new RecipeConfig { Name = text, Item = belt.PrefabName, Amount = belt.Amount, CraftingStation = GetCraftingStation(beltOptions), MinStationLevel = GetStationLevel(beltOptions), Requirements = requirements }); if (!ItemManager.Instance.AddRecipe(val)) { ModLogger.LogWarning("Failed adding recipe: " + text); return; } RegisteredRecipes.Add(text, val); ModLogger.LogInfo("Registered recipe: " + text); } private static RequirementConfig[] GetRequirements(BeltDefinition belt, IndividualBeltOptions options) { if (string.IsNullOrWhiteSpace(options.Recipe)) { return belt.Requirements; } RequirementConfig[] array = ConfigRecipeParser.ParseRecipe(options.Recipe); if (array != null && array.Length != 0) { ModLogger.LogDebug("Using custom recipe for " + belt.PrefabName); return array; } ModLogger.LogWarning("Invalid recipe override for " + belt.PrefabName + ". Using default."); return belt.Requirements; } private static string GetCraftingStation(IndividualBeltOptions options) { return options.CraftingStation switch { CraftingStationType.None => "", CraftingStationType.Workbench => "piece_workbench", CraftingStationType.Forge => "forge", CraftingStationType.Stonecutter => "piece_stonecutter", CraftingStationType.ArtisanTable => "piece_artisanstation", CraftingStationType.BlackForge => "blackforge", CraftingStationType.GaldrTable => "piece_magetable", _ => "piece_magetable", }; } private static int GetStationLevel(IndividualBeltOptions options) { if (options.CraftingStationLevel <= 0) { return 4; } return options.CraftingStationLevel; } } } namespace MegingjordReforged.Source.Managers { public static class BeltIconManager { public static Sprite? LoadIcon(string iconName) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(iconName)) { ModLogger.LogWarning("Attempted to load an icon with an empty name."); return null; } try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = "MegingjordReforged.Assets.Icons." + iconName; ModLogger.LogDebug("Searching embedded icon resource: " + text); using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { ModLogger.LogError("Icon resource was not found: " + text); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { ModLogger.LogError("Failed converting icon resource into texture: " + iconName); return null; } Sprite result = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); ModLogger.LogDebug("Created sprite instance for icon: " + iconName); return result; } catch (Exception arg) { ModLogger.LogError($"Exception while loading icon '{iconName}': {arg}"); return null; } } } public static class BeltModelManager { public static void ApplyTexture(GameObject beltObject, string textureName) { if ((Object)(object)beltObject == (Object)null) { ModLogger.LogError("Cannot apply belt texture. Belt object is null."); return; } Texture2D val = LoadTexture(textureName); if ((Object)(object)val == (Object)null) { ModLogger.LogError("Could not load belt texture: " + textureName); return; } Renderer[] componentsInChildren = beltObject.GetComponentsInChildren<Renderer>(true); if (componentsInChildren.Length == 0) { ModLogger.LogError("No renderers found on " + ((Object)beltObject).name); return; } ModLogger.LogDebug($"Applying texture {textureName} to {((Object)beltObject).name} using {componentsInChildren.Length} renderer(s)."); Renderer[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { Material[] materials = array[i].materials; foreach (Material val2 in materials) { bool flag = false; if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", (Texture)(object)val); flag = true; } if (val2.HasProperty("_BaseMap")) { val2.SetTexture("_BaseMap", (Texture)(object)val); flag = true; } if (flag) { ModLogger.LogDebug("Applied texture " + textureName + " to material " + ((Object)val2).name + "."); } } } } private static Texture2D? LoadTexture(string textureName) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = "MegingjordReforged.Assets.Textures." + textureName; ModLogger.LogDebug("Loading texture resource: " + text); using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { ModLogger.LogError("Could not find texture resource: " + text); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { ModLogger.LogError("Failed loading texture: " + textureName); return null; } ((Object)val).name = textureName; ((Texture)val).wrapMode = (TextureWrapMode)0; ((Texture)val).filterMode = (FilterMode)1; ModLogger.LogDebug("Successfully loaded texture: " + textureName); return val; } } public static class BeltPrefabManager { private const string BasePrefab = "BeltStrength"; private static bool _registered; public static void RegisterBelts() { if (_registered) { ModLogger.LogDebug("Belts have already been registered."); return; } _registered = true; ModLogger.LogDebug("Registering Megingjord Reforged belt prefabs..."); foreach (BeltDefinition value in BeltRegistry.Belts.Values) { CreateBeltPrefab(value); } ModLogger.LogDebug("Finished registering belt prefabs."); } private static void CreateBeltPrefab(BeltDefinition belt) { //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown GameObject prefab = PrefabManager.Instance.GetPrefab("BeltStrength"); if ((Object)(object)prefab == (Object)null) { ModLogger.LogError("Unable to locate vanilla prefab: BeltStrength"); return; } GameObject val = PrefabManager.Instance.CreateClonedPrefab(belt.PrefabName, prefab); ModLogger.LogDebug("Created belt clone: " + belt.PrefabName); ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { ModLogger.LogError("Missing ItemDrop component on " + belt.PrefabName); return; } component.m_itemData.m_shared.m_name = belt.DisplayName; component.m_itemData.m_shared.m_description = belt.Description; Sprite val2 = BeltIconManager.LoadIcon(belt.IconName); if ((Object)(object)val2 != (Object)null) { component.m_itemData.m_shared.m_icons[0] = val2; ModLogger.LogDebug("Applied icon: " + belt.IconName); } ApplyBeltTextures(val, belt.TextureName); FixEquipAttach(val, belt.TextureName); StatusEffect statusEffect = GetStatusEffect(belt); if ((Object)(object)statusEffect == (Object)null) { ModLogger.LogWarning("No status effect assigned to " + belt.PrefabName); } else { component.m_itemData.m_shared.m_equipStatusEffect = statusEffect; ModLogger.LogDebug("Assigned status effect to " + belt.PrefabName); } ItemManager.Instance.AddItem(new CustomItem(val, true)); ModLogger.LogInfo("Registered belt prefab: " + belt.PrefabName); } private static StatusEffect? GetStatusEffect(BeltDefinition belt) { return (StatusEffect?)(belt.Type switch { BeltType.BeltAedigjord => StatusEffectRegistry.Aedigjord, BeltType.BeltSeidgjord => StatusEffectRegistry.Seidgjord, BeltType.BeltSkadigjord => StatusEffectRegistry.Skadigjord, BeltType.BeltAlagjord => StatusEffectRegistry.Alagjord, BeltType.BeltFornmegingjord => StatusEffectRegistry.Fornmegingjord, _ => null, }); } private static void ApplyBeltTextures(GameObject beltObject, string textureName) { string[] array = new string[2] { "attach/belt1", "attach_skin/belt1" }; foreach (string text in array) { Transform val = beltObject.transform.Find(text); if (!((Object)(object)val == (Object)null)) { BeltModelManager.ApplyTexture(((Component)val).gameObject, textureName); } } } private static void FixEquipAttach(GameObject beltObject, string textureName) { Transform val = beltObject.transform.Find("attach"); if ((Object)(object)val == (Object)null) { ModLogger.LogWarning("No attach object found for " + ((Object)beltObject).name); return; } Transform val2 = val.Find("belt1"); if ((Object)(object)val2 == (Object)null) { ModLogger.LogWarning("No belt visual found for " + ((Object)beltObject).name); } else { BeltModelManager.ApplyTexture(((Component)val2).gameObject, textureName); } } } public static class ConfigManager { public static MegingjordConfig Current { get; private set; } = new MegingjordConfig(); public static string ConfigPath { get; private set; } = string.Empty; public static void Load(ConfigFile configFile) { try { ConfigPath = configFile.ConfigFilePath; configFile.Bind<bool>("General", "Enable Mod", true, (ConfigDescription)null); configFile.Bind<ConfigLoggingMode>("Logging", "Logging Mode", ConfigLoggingMode.Standard, (ConfigDescription)null); string[] array = new string[5] { "Aedigjord", "Seidgjord", "Skadigjord", "Alagjord", "Fornmegingjord" }; foreach (string text in array) { configFile.Bind<CraftingStationType>("Belts - " + text, "Crafting Station", CraftingStationType.GaldrTable, (ConfigDescription)null); } configFile.Bind<bool>("Advanced", "Experimental Features", false, (ConfigDescription)null); Current = new MegingjordConfig { General = LoadGeneral(configFile), Logging = LoadLogging(configFile), Belts = LoadBelts(configFile), Advanced = LoadAdvanced(configFile) }; ModLogger.LogDebug("Configuration loaded successfully."); } catch (Exception ex) { ModLogger.LogWarning("Configuration failed to load. " + ex.Message); Current = new MegingjordConfig(); } } private static ConfigGeneralOptions LoadGeneral(ConfigFile configFile) { return new ConfigGeneralOptions { EnableMod = configFile.Bind<bool>("General", "Enable Mod", true, (ConfigDescription)null).Value, EnableServerSync = configFile.Bind<bool>("General", "Enable Server Sync", true, (ConfigDescription)null).Value }; } private static ConfigLoggingMode LoadLogging(ConfigFile configFile) { return configFile.Bind<ConfigLoggingMode>("Logging", "Logging Mode", ConfigLoggingMode.Standard, (ConfigDescription)null).Value; } private static ConfigBeltOptions LoadBelts(ConfigFile configFile) { return new ConfigBeltOptions { Aedigjord = LoadIndividualBelt(configFile, "Aedigjord"), Seidgjord = LoadIndividualBelt(configFile, "Seidgjord"), Skadigjord = LoadIndividualBelt(configFile, "Skadigjord"), Alagjord = LoadIndividualBelt(configFile, "Alagjord"), Fornmegingjord = LoadIndividualBelt(configFile, "Fornmegingjord") }; } private static IndividualBeltOptions LoadIndividualBelt(ConfigFile configFile, string beltName) { return new IndividualBeltOptions { CraftingStation = configFile.Bind<CraftingStationType>("Belts - " + beltName, "Crafting Station", CraftingStationType.GaldrTable, (ConfigDescription)null).Value, CraftingStationLevel = configFile.Bind<int>("Belts - " + beltName, "Crafting Station Level", 4, (ConfigDescription)null).Value, Recipe = configFile.Bind<string>("Belts - " + beltName, "Recipe", string.Empty, (ConfigDescription)null).Value, Effects = LoadBeltEffects(configFile, beltName) }; } private static BeltEffectOptions LoadBeltEffects(ConfigFile configFile, string beltName) { return beltName switch { "Aedigjord" => LoadAedigjordEffects(configFile), "Seidgjord" => LoadSeidgjordEffects(configFile), "Skadigjord" => LoadSkadigjordEffects(configFile), "Alagjord" => LoadAlagjordEffects(configFile), "Fornmegingjord" => LoadFornmegingjordEffects(configFile), _ => LoadDefaultEffects(), }; } private static BeltEffectOptions LoadFornmegingjordEffects(ConfigFile configFile) { return new BeltEffectOptions { CarryWeight = configFile.Bind<float>("Belts - Fornmegingjord - Effects", "Carry Weight", 450f, (ConfigDescription)null).Value }; } private static BeltEffectOptions LoadAedigjordEffects(ConfigFile configFile) { string section = "Belts - Aedigjord - Effects"; return new BeltEffectOptions { CarryWeight = LoadCarryWeight(configFile, section), Armor = LoadArmor(configFile, section), HealthRegenModifier = LoadPercentage(configFile, section, "Health Regen Modifier", 50f), AttackStaminaUseModifier = LoadPercentage(configFile, section, "Attack Stamina Use Modifier", -30f) }; } private static BeltEffectOptions LoadSeidgjordEffects(ConfigFile configFile) { string section = "Belts - Seidgjord - Effects"; return new BeltEffectOptions { CarryWeight = LoadCarryWeight(configFile, section), HealthRegenModifier = LoadPercentage(configFile, section, "Health Regen Modifier", 25f), StaminaRegenModifier = LoadPercentage(configFile, section, "Stamina Regen Modifier", 25f), EitrRegenModifier = LoadPercentage(configFile, section, "Eitr Regen Modifier", 100f) }; } private static BeltEffectOptions LoadSkadigjordEffects(ConfigFile configFile) { string section = "Belts - Skadigjord - Effects"; return new BeltEffectOptions { CarryWeight = LoadCarryWeight(configFile, section), StaminaRegenModifier = LoadPercentage(configFile, section, "Stamina Regen Modifier", 100f), RunStaminaUseModifier = LoadPercentage(configFile, section, "Run Stamina Use Modifier", -20f), JumpStaminaUseModifier = LoadPercentage(configFile, section, "Jump Stamina Use Modifier", -10f) }; } private static BeltEffectOptions LoadAlagjordEffects(ConfigFile configFile) { return new BeltEffectOptions(); } private static BeltEffectOptions LoadDefaultEffects() { return new BeltEffectOptions(); } private static float LoadCarryWeight(ConfigFile configFile, string section) { return configFile.Bind<float>(section, "Carry Weight", 150f, (ConfigDescription)null).Value; } private static float LoadArmor(ConfigFile configFile, string section) { return configFile.Bind<float>(section, "Armor", 25f, (ConfigDescription)null).Value; } private static float LoadPercentage(ConfigFile configFile, string section, string key, float defaultValue) { return configFile.Bind<float>(section, key, defaultValue, (ConfigDescription)null).Value; } private static ConfigAdvancedOptions LoadAdvanced(ConfigFile configFile) { return new ConfigAdvancedOptions { ExperimentalFeatures = configFile.Bind<bool>("Advanced", "Experimental Features", false, (ConfigDescription)null).Value }; } } public static class ConfigResolveManager { public static bool HasServerOverrides => RuntimeConfigOverride.Contains("General.EnableMod"); public static T Get<T>(string key, T localValue) { return ServerSyncManager.GetValue(key, localValue); } public static IndividualBeltOptions GetBeltOptions(string beltName) { IndividualBeltOptions beltOptions = ConfigManager.Current.Belts.GetBeltOptions(beltName); return new IndividualBeltOptions { CraftingStation = Get("Belts." + beltName + ".CraftingStation", beltOptions.CraftingStation), CraftingStationLevel = Get("Belts." + beltName + ".CraftingStationLevel", beltOptions.CraftingStationLevel), Recipe = Get("Belts." + beltName + ".Recipe", beltOptions.Recipe), Effects = GetEffects(beltName, beltOptions.Effects) }; } private static BeltEffectOptions GetEffects(string beltName, BeltEffectOptions localEffects) { return new BeltEffectOptions { CarryWeight = Get("Belts." + beltName + ".Effects.CarryWeight", localEffects.CarryWeight), Armor = Get("Belts." + beltName + ".Effects.Armor", localEffects.Armor), HealthRegenModifier = Get("Belts." + beltName + ".Effects.HealthRegenModifier", localEffects.HealthRegenModifier), StaminaRegenModifier = Get("Belts." + beltName + ".Effects.StaminaRegenModifier", localEffects.StaminaRegenModifier), EitrRegenModifier = Get("Belts." + beltName + ".Effects.EitrRegenModifier", localEffects.EitrRegenModifier), AttackStaminaUseModifier = Get("Belts." + beltName + ".Effects.AttackStaminaUseModifier", localEffects.AttackStaminaUseModifier), SwimStaminaUseModifier = Get("Belts." + beltName + ".Effects.SwimStaminaUseModifier", localEffects.SwimStaminaUseModifier), RunStaminaUseModifier = Get("Belts." + beltName + ".Effects.RunStaminaUseModifier", localEffects.RunStaminaUseModifier), JumpStaminaUseModifier = Get("Belts." + beltName + ".Effects.JumpStaminaUseModifier", localEffects.JumpStaminaUseModifier), DodgeStaminaUseModifier = Get("Belts." + beltName + ".Effects.DodgeStaminaUseModifier", localEffects.DodgeStaminaUseModifier), SneakStaminaUseModifier = Get("Belts." + beltName + ".Effects.SneakStaminaUseModifier", localEffects.SneakStaminaUseModifier) }; } } public static class RuntimeConfigOverride { private static readonly Dictionary<string, string> Overrides = new Dictionary<string, string>(); public static bool Contains(string key) { return Overrides.ContainsKey(key); } public static void Set(string key, object value) { Overrides[key] = value.ToString() ?? string.Empty; } public static bool TryGet<T>(string key, out T value) { value = default(T); if (!Overrides.TryGetValue(key, out string value2)) { return false; } try { Type typeFromHandle = typeof(T); if (typeFromHandle == typeof(string)) { value = (T)(object)value2; return true; } if (typeFromHandle.IsEnum) { value = (T)Enum.Parse(typeFromHandle, value2); return true; } value = (T)Convert.ChangeType(value2, typeFromHandle, CultureInfo.InvariantCulture); return true; } catch { return false; } } public static void Remove(string key) { Overrides.Remove(key); } public static void Clear() { Overrides.Clear(); } } public static class ServerSyncDataProvider { private static readonly string[] BeltNames = new string[5] { "Aedigjord", "Seidgjord", "Skadigjord", "Alagjord", "Fornmegingjord" }; public static ServerSyncPackage CreatePackage() { ServerSyncPackage serverSyncPackage = new ServerSyncPackage { Version = "1.0.0", SchemaVersion = VersionManager.SchemaVersion }; foreach (KeyValuePair<string, string> serverValue in GetServerValues()) { serverSyncPackage.Values[serverValue.Key] = serverValue.Value; } return serverSyncPackage; } private static Dictionary<string, string> GetServerValues() { Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (ServerSyncDefinition syncDefinition in ServerSyncRegistry.SyncDefinitions) { if (!syncDefinition.Enabled) { continue; } if (TryGetValue(syncDefinition.Identifier, out string value)) { dictionary[syncDefinition.Identifier] = value; continue; } ModLogger.LogWarning("Unable to resolve synchronized key '" + syncDefinition.Identifier + "'."); if (TryGetDefaultValue(syncDefinition.Identifier, out string value2)) { dictionary[syncDefinition.Identifier] = value2; } } return dictionary; } private static bool TryGetValue(string key, out string value) { value = string.Empty; switch (key) { case "General.EnableMod": value = ConfigManager.Current.General.EnableMod.ToString(); return true; case "General.EnableServerSync": value = ConfigManager.Current.General.EnableServerSync.ToString(); return true; case "Advanced.ExperimentalFeatures": value = ConfigManager.Current.Advanced.ExperimentalFeatures.ToString(); return true; default: { string[] beltNames = BeltNames; foreach (string text in beltNames) { IndividualBeltOptions beltOptions = ConfigManager.Current.Belts.GetBeltOptions(text); if (beltOptions == null) { continue; } if (key == "Belts." + text + ".Recipe") { value = beltOptions.Recipe; return true; } if (key == "Belts." + text + ".CraftingStation") { value = beltOptions.CraftingStation.ToString(); return true; } if (key == "Belts." + text + ".CraftingStationLevel") { value = beltOptions.CraftingStationLevel.ToString(); return true; } foreach (KeyValuePair<string, string> effectValue in GetEffectValues(text, beltOptions)) { if (key == effectValue.Key) { value = effectValue.Value; return true; } } } return false; } } } private static Dictionary<string, string> GetEffectValues(string belt, IndividualBeltOptions options) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); BeltEffectOptions effects = options.Effects; if (effects == null) { return dictionary; } string text = "Belts." + belt + ".Effects."; dictionary[text + "CarryWeight"] = effects.CarryWeight.ToString(); dictionary[text + "Armor"] = effects.Armor.ToString(); dictionary[text + "HealthRegenModifier"] = effects.HealthRegenModifier.ToString(); dictionary[text + "StaminaRegenModifier"] = effects.StaminaRegenModifier.ToString(); dictionary[text + "EitrRegenModifier"] = effects.EitrRegenModifier.ToString(); dictionary[text + "AttackStaminaUseModifier"] = effects.AttackStaminaUseModifier.ToString(); dictionary[text + "RunStaminaUseModifier"] = effects.RunStaminaUseModifier.ToString(); dictionary[text + "JumpStaminaUseModifier"] = effects.JumpStaminaUseModifier.ToString(); dictionary[text + "DodgeStaminaUseModifier"] = effects.DodgeStaminaUseModifier.ToString(); dictionary[text + "SneakStaminaUseModifier"] = effects.SneakStaminaUseModifier.ToString(); dictionary[text + "SwimStaminaUseModifier"] = effects.SwimStaminaUseModifier.ToString(); return dictionary; } private static bool TryGetDefaultValue(string key, out string value) { value = string.Empty; if (key.Contains("CraftingStationLevel")) { value = "4"; return true; } if (key.Contains("CraftingStation")) { value = CraftingStationType.GaldrTable.ToString(); return true; } if (key.Contains("ExperimentalFeatures")) { value = "false"; return true; } return false; } } public static class ServerSyncManager { [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private static class RPC_PeerInfoPatch { private static void Postfix(ZNet __instance, ZRpc rpc) { if (!__instance.IsServer()) { return; } foreach (ZNetPeer peer in __instance.GetPeers()) { if (peer.m_rpc == rpc) { SendSynchronizationData(peer); break; } } } } [CompilerGenerated] private static class <>O { public static CoroutineHandler <0>__ServerReceive; public static CoroutineHandler <1>__ClientReceive; } private static bool Initialized; private static CustomRPC? SyncRPC; public static void Initialize() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown if (Initialized) { return; } Initialized = true; if (!ConfigManager.Current.General.EnableServerSync) { ModLogger.LogDebug("Server synchronization disabled through configuration."); return; } ModLogger.LogDebug("Initializing ServerSync Manager."); NetworkManager instance = NetworkManager.Instance; object obj = <>O.<0>__ServerReceive; if (obj == null) { CoroutineHandler val = ServerReceive; <>O.<0>__ServerReceive = val; obj = (object)val; } object obj2 = <>O.<1>__ClientReceive; if (obj2 == null) { CoroutineHandler val2 = ClientReceive; <>O.<1>__ClientReceive = val2; obj2 = (object)val2; } SyncRPC = instance.AddRPC("MegingjordServerSync", (CoroutineHandler)obj, (CoroutineHandler)obj2); new Harmony("NoxiousVex.MegingjordReforged.ServerSync").PatchAll(typeof(ServerSyncManager)); ModLogger.LogDebug("ServerSync RPC registered."); } private static void SendSynchronizationData(ZNetPeer peer) { if (SyncRPC != null) { ZPackage val = ServerSyncSerializer.Serialize(ServerSyncDataProvider.CreatePackage()); SyncRPC.SendPackage(peer.m_uid, val); ModLogger.LogDebug($"ServerSync data sent to peer {peer.m_uid}."); } } private static IEnumerator ServerReceive(long sender, ZPackage package) { ModLogger.LogWarning($"Rejected ServerSync request from client {sender}."); yield break; } private static IEnumerator ClientReceive(long sender, ZPackage package) { ServerSyncPackage package2 = ServerSyncSerializer.Deserialize(package); if (!ValidatePackage(package2)) { ModLogger.LogWarning("Rejected incompatible ServerSync package."); yield break; } ApplyServerOverrides(package2); StatusEffectRegistry.RefreshStatusEffects(); BeltItemManager.RefreshRecipes(); ModLogger.LogDebug("Server synchronization data applied."); } private static bool ValidatePackage(ServerSyncPackage package) { if (package.SchemaVersion != VersionManager.SchemaVersion) { ModLogger.LogWarning("Rejected ServerSync package. " + $"Received schema {package.SchemaVersion}, " + $"expected schema {VersionManager.SchemaVersion}."); return false; } if (package.Version != "1.0.0") { ModLogger.LogWarning("ServerSync package version mismatch. Received " + package.Version + ", local version 1.0.0."); return false; } return true; } private static void ApplyServerOverrides(ServerSyncPackage package) { RuntimeConfigOverride.Clear(); foreach (KeyValuePair<string, string> value in package.Values) { if (!IsKnownSyncKey(value.Key)) { ModLogger.LogWarning("Ignoring unknown ServerSync key '" + value.Key + "'."); } else { RuntimeConfigOverride.Set(value.Key, value.Value); } } } private static bool IsKnownSyncKey(string key) { foreach (ServerSyncDefinition syncDefinition in ServerSyncRegistry.SyncDefinitions) { if (syncDefinition.Identifier == key) { return true; } } return false; } public static T GetValue<T>(string key, T localValue) { if (RuntimeConfigOverride.TryGet<T>(key, out var value)) { return value; } return localValue; } public static void Shutdown() { Initialized = false; RuntimeConfigOverride.Clear(); StatusEffectRegistry.RefreshStatusEffects(); BeltItemManager.RefreshRecipes(); ModLogger.LogDebug("ServerSync Manager shutdown."); } } public static class VersionManager { private const int CurrentSchemaVersion = 1; private const int CurrentFormatVersion = 1; private const string FormatVersionKey = "# MegingjordReforged Config Format Version:"; private static bool Verified; public static int SchemaVersion => 1; public static int FormatVersion => 1; public static void Verify(string configPath) { if (Verified) { return; } try { ModLogger.LogDebug("Beginning version verification..."); CheckModVersion(); CheckSchemaVersion(); CheckConfigFormatVersion(configPath); Verified = true; ModLogger.LogDebug("Version verification completed."); } catch (Exception arg) { ModLogger.LogError($"Version verification failed: {arg}"); } } private static void CheckModVersion() { } private static void CheckSchemaVersion() { ModLogger.LogDebug($"ServerSync schema version verified: {1}."); } private static void CheckConfigFormatVersion(string configPath) { if (string.IsNullOrWhiteSpace(configPath)) { ModLogger.LogWarning("Unable to verify config format version. Invalid path."); } else if (File.Exists(configPath)) { int num = ReadStoredFormatVersion(configPath); if (num < 1) { ModLogger.LogInfo($"Updating configuration format from version {num} to {1}."); ConfigFormatter.Format(configPath, 1); } } } private static int ReadStoredFormatVersion(string configPath) { try { string[] array = File.ReadAllLines(configPath, Encoding.UTF8); foreach (string text in array) { if (text.StartsWith("# MegingjordReforged Config Format Version:", StringComparison.OrdinalIgnoreCase) && int.TryParse(text.Replace("# MegingjordReforged Config Format Version:", string.Empty).Trim(), out var result)) { return result; } } } catch (Exception ex) { ModLogger.LogWarning("Unable to read configuration format version: " + ex.Message); } return 0; } } } namespace MegingjordReforged.Source.Definitions { public class MegingjordConfig { public string ConfigPath { get; set; } = string.Empty; public ConfigGeneralOptions General { get; set; } = new ConfigGeneralOptions(); public ConfigLoggingMode Logging { get; set; } = ConfigLoggingMode.Standard; public ConfigBeltOptions Belts { get; set; } = new ConfigBeltOptions(); public ConfigAdvancedOptions Advanced { get; set; } = new ConfigAdvancedOptions(); } public class BeltDefinition { public string ConfigKey { get; set; } = string.Empty; public string PrefabName { get; set; } = string.Empty; public string DisplayName { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public string IconName { get; set; } = string.Empty; public string TextureName { get; set; } = string.Empty; public BeltType Type { get; set; } public RequirementConfig[] Requirements { get; set; } = Array.Empty<RequirementConfig>(); public int Amount { get; set; } = 1; } public enum BeltType { BeltAedigjord, BeltAlagjord, BeltFornmegingjord, BeltSeidgjord, BeltSkadigjord } public class BeltEffectDefinition { public string EffectName { get; set; } = string.Empty; public bool Configurable { get; set; } = true; public float DefaultValue { get; set; } public float MinimumValue { get; set; } public float MaximumValue { get; set; } public bool AllowZero { get; set; } = true; public string Description { get; set; } = string.Empty; public float Validate(float value) { if (!AllowZero && value == 0f) { return DefaultValue; } if (value < MinimumValue) { return MinimumValue; } if (value > MaximumValue) { return MaximumValue; } return value; } } public enum CraftingStationType { Disabled, None, Workbench, Forge, Stonecutter, ArtisanTable, BlackForge, GaldrTable } public class ServerSyncDefinition { public string Section { get; set; } = string.Empty; public string Key { get; set; } = string.Empty; public string Identifier { get; set; } = string.Empty; public bool Enabled { get; set; } = true; } public class ServerSyncPackage { public string Version { get; set; } = string.Empty; public int SchemaVersion { get; set; } public Dictionary<string, string> Values { get; set; } = new Dictionary<string, string>(); } } namespace MegingjordReforged.Source.Config { public class BeltEffectOptions { public float CarryWeight { get; set; } public float Armor { get; set; } public float HealthRegenModifier { get; set; } public float StaminaRegenModifier { get; set; } public float EitrRegenModifier { get; set; } public float AttackStaminaUseModifier { get; set; } public float SwimStaminaUseModifier { get; set; } public float RunStaminaUseModifier { get; set; } public float JumpStaminaUseModifier { get; set; } public float DodgeStaminaUseModifier { get; set; } public float SneakStaminaUseModifier { get; set; } } public class ConfigAdvancedOptions { public bool ExperimentalFeatures { get; set; } } public class ConfigBeltOptions { public IndividualBeltOptions Aedigjord { get; set; } = new IndividualBeltOptions(); public IndividualBeltOptions Alagjord { get; set; } = new IndividualBeltOptions(); public IndividualBeltOptions Fornmegingjord { get; set; } = new IndividualBeltOptions(); public IndividualBeltOptions Seidgjord { get; set; } = new IndividualBeltOptions(); public IndividualBeltOptions Skadigjord { get; set; } = new IndividualBeltOptions(); public IndividualBeltOptions GetBeltOptions(string configKey) { return configKey switch { "Aedigjord" => Aedigjord, "Alagjord" => Alagjord, "Fornmegingjord" => Fornmegingjord, "Seidgjord" => Seidgjord, "Skadigjord" => Skadigjord, _ => new IndividualBeltOptions(), }; } } public class ConfigGeneralOptions { public bool EnableMod { get; set; } = true; public bool EnableServerSync { get; set; } = true; } public enum ConfigLoggingMode { Minimal, Warnings, Standard, Debug } public static class ConfigRecipeParser { public static RequirementConfig[]? ParseRecipe(string recipeString) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00f7: Expected O, but got Unknown if (string.IsNullOrWhiteSpace(recipeString)) { return null; } List<RequirementConfig> list = new List<RequirementConfig>(); string[] array = recipeString.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length != 2) { ModLogger.LogWarning("Invalid recipe entry '" + text + "'. Expected ItemPrefab:Amount."); continue; } string text2 = array2[0].Trim(); string s = array2[1].Trim(); if (string.IsNullOrWhiteSpace(text2)) { ModLogger.LogWarning("Invalid recipe entry '" + text + "'. Item name cannot be empty."); continue; } if (!int.TryParse(s, out var result)) { ModLogger.LogWarning("Invalid recipe entry '" + text + "'. Amount must be numeric."); continue; } if (result <= 0) { ModLogger.LogWarning("Invalid recipe entry '" + text + "'. Amount must be greater than zero."); continue; } list.Add(new RequirementConfig { Item = text2, Amount = result }); } if (list.Count == 0) { ModLogger.LogWarning("Recipe override contained no valid ingredients. Default recipe will be used."); return null; } ModLogger.LogDebug($"Parsed custom recipe with {list.Count} ingredient(s)."); return list.ToArray(); } } public class IndividualBeltOptions { public CraftingStationType CraftingStation { get; set; } = CraftingStationType.GaldrTable; public int CraftingStationLevel { get; set; } public string Recipe { get; set; } = string.Empty; public BeltEffectOptions Effects { get; set; } = new BeltEffectOptions(); } }