Decompiled source of CustomSkillLoss v1.1.0

plugins/NoSkillLoss.dll

Decompiled 3 days ago
using 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;
		}
	}
}