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 CustomSkillLoss v1.1.0
plugins/NoSkillLoss.dll
Decompiled 8 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("NoSkillLoss")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+bf2bc9f88d199faeb3495278be834c45b0c1cf83")] [assembly: AssemblyProduct("NoSkillLoss")] [assembly: AssemblyTitle("NoSkillLoss")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace CustomSkillLoss; [BepInPlugin("CustomSkillLoss", "Custom Skill Loss", "1.0.0")] public class CustomSkillLossPlugin : BaseUnityPlugin { public const string PluginGUID = "CustomSkillLoss"; public const string PluginName = "Custom Skill Loss"; public const string PluginVersion = "1.0.0"; private static CustomSkillLossPlugin _instance; private Harmony _harmony; private DateTime _lastConfigWriteTime; private DateTime _lastConfigReloadTime = DateTime.MinValue; private float _configCheckTimer = 0f; private const float CONFIG_CHECK_INTERVAL = 2f; private const double CONFIG_RELOAD_DEBOUNCE_SECONDS = 3.0; private static Dictionary<SkillType, ConfigEntry<float>> _skillLossConfig; private void Awake() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown _instance = this; InitializeConfig(); SetupConfigMonitoring(); _harmony = new Harmony("CustomSkillLoss"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Custom Skill Loss 1.0.0 loaded!"); } private void Update() { _configCheckTimer += Time.deltaTime; if (_configCheckTimer >= 2f) { _configCheckTimer = 0f; CheckConfigFileForChanges(); } } private void SetupConfigMonitoring() { try { if (File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath)) { _lastConfigWriteTime = File.GetLastWriteTime(((BaseUnityPlugin)this).Config.ConfigFilePath); } else { _lastConfigWriteTime = DateTime.MinValue; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Error setting up config monitoring: " + ex.Message)); } } private void CheckConfigFileForChanges() { try { if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath)) { return; } DateTime lastWriteTime = File.GetLastWriteTime(((BaseUnityPlugin)this).Config.ConfigFilePath); if (lastWriteTime > _lastConfigWriteTime) { if ((DateTime.Now - _lastConfigReloadTime).TotalSeconds < 3.0) { _lastConfigWriteTime = lastWriteTime; return; } _lastConfigWriteTime = lastWriteTime; _lastConfigReloadTime = DateTime.Now; Thread.Sleep(100); ((BaseUnityPlugin)this).Config.Reload(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Config file reloaded successfully!"); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Error checking config file: " + ex.Message)); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void InitializeConfig() { //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Expected O, but got Unknown _skillLossConfig = new Dictionary<SkillType, ConfigEntry<float>>(); Dictionary<SkillType, (string, string)> dictionary = new Dictionary<SkillType, (string, string)> { { (SkillType)1, ("Combat Skills", "Swords") }, { (SkillType)2, ("Combat Skills", "Knives") }, { (SkillType)3, ("Combat Skills", "Clubs") }, { (SkillType)4, ("Combat Skills", "Polearms") }, { (SkillType)5, ("Combat Skills", "Spears") }, { (SkillType)6, ("Combat Skills", "Blocking") }, { (SkillType)7, ("Combat Skills", "Axes") }, { (SkillType)8, ("Combat Skills", "Bows") }, { (SkillType)14, ("Combat Skills", "Crossbows") }, { (SkillType)9, ("Combat Skills", "Elemental Magic") }, { (SkillType)10, ("Combat Skills", "Blood Magic") }, { (SkillType)11, ("Combat Skills", "Unarmed") }, { (SkillType)12, ("Utility Skills", "Pickaxes") }, { (SkillType)13, ("Utility Skills", "Woodcutting") }, { (SkillType)104, ("Utility Skills", "Fishing") }, { (SkillType)105, ("Crafting Skills", "Cooking") }, { (SkillType)107, ("Crafting Skills", "Crafting") }, { (SkillType)106, ("Crafting Skills", "Farming") }, { (SkillType)100, ("Movement Skills", "Jump") }, { (SkillType)102, ("Movement Skills", "Run") }, { (SkillType)101, ("Movement Skills", "Sneak") }, { (SkillType)103, ("Movement Skills", "Swim") }, { (SkillType)110, ("Movement Skills", "Ride") }, { (SkillType)108, ("Movement Skills", "Dodge") } }; foreach (KeyValuePair<SkillType, (string, string)> item in dictionary) { SkillType key = item.Key; var (text, text2) = item.Value; _skillLossConfig[key] = ((BaseUnityPlugin)this).Config.Bind<float>(text, text2 + " Loss %", 5f, new ConfigDescription("Percentage of " + text2.ToLower() + " skill lost on death (0-100)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); } } public static float GetSkillLossPercentage(SkillType skillType) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (_skillLossConfig.TryGetValue(skillType, out var value)) { return value.Value / 100f; } return 0.05f; } } [HarmonyPatch(typeof(Skills), "OnDeath")] public static class SkillsOnDeathPatch { private static bool Prefix(Skills __instance) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) FieldInfo field = typeof(Skills).GetField("m_skillData", BindingFlags.Instance | BindingFlags.NonPublic); if (field == null) { Debug.LogError((object)"CustomSkillLoss: Could not find skill data field"); return true; } object value = field.GetValue(__instance); if (!(value is IDictionary dictionary)) { Debug.LogError((object)"CustomSkillLoss: Skill data is not a dictionary"); return true; } int num = 0; foreach (DictionaryEntry item in dictionary) { if (item.Key is SkillType skillType && item.Value != null && ProcessSkillData(item.Value, skillType)) { num++; } } if ((Object)(object)Player.m_localPlayer != (Object)null && num > 0) { ((Character)Player.m_localPlayer).Message((MessageType)1, "$msg_skills_lowered", 0, (Sprite)null); } return false; } private static bool ProcessSkillData(object skillData, SkillType skillType) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) try { Type type = skillData.GetType(); FieldInfo field = type.GetField("m_level", BindingFlags.Instance | BindingFlags.Public); FieldInfo field2 = type.GetField("m_accumulator", BindingFlags.Instance | BindingFlags.Public); if (field == null) { return false; } float num = (float)field.GetValue(skillData); float skillLossPercentage = CustomSkillLossPlugin.GetSkillLossPercentage(skillType); if (skillLossPercentage > 0f && num > 0f) { float num2 = num * skillLossPercentage; float num3 = Mathf.Max(0f, num - num2); field.SetValue(skillData, num3); field2?.SetValue(skillData, 0f); return true; } return false; } catch (Exception ex) { Debug.LogError((object)$"CustomSkillLoss: Error processing {skillType}: {ex.Message}"); return false; } } }