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 LicenseToSkill v1.5.0
LicenseToSkill.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using ComfyLib; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LicenseToSkill")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LicenseToSkill")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("1.5.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LicenseToSkill { public static class PluginConfig { public static ConfigEntry<bool> IsModEnabled { get; private set; } public static ConfigEntry<float> HardDeathCooldownOverride { get; private set; } public static ConfigEntry<float> SkillLossPercentOverride { get; private set; } public static void BindConfig(ConfigFile config) { IsModEnabled = config.BindInOrder("_Global", "isModEnabled", defaultValue: true, "Globally enable or disable this mod."); HardDeathCooldownOverride = config.BindInOrder("OnDeath", "hardDeathCooldownOverride", 20f, "Duration (in minutes) of the 'no skill loss' status effect after death.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 20f)); SkillLossPercentOverride = config.BindInOrder("OnDeath", "skillLossPercentOverride", 1f, "Percentage of the skill's current level to lose on death.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f)); IsModEnabled.OnSettingChanged<bool>(StatusEffectUtils.SetHardDeathCoolDown); HardDeathCooldownOverride.OnSettingChanged<float>(StatusEffectUtils.SetHardDeathCoolDown); } } public static class StatusEffectUtils { public const float DefaultHardDeathCooldown = 600f; public static float GetConfigHardDeathCooldown() { return PluginConfig.HardDeathCooldownOverride.Value * 60f; } public static void SetHardDeathCoolDown() { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { UpdateHardDeathCooldownTimer(Player.m_localPlayer); } } public static void UpdateHardDeathCooldownTimer(Player player) { if (player.TryGetStatusEffect(SEMan.s_statusEffectSoftDeath, out var statusEffect)) { statusEffect.m_ttl = GetConfigHardDeathCooldown() - player.m_timeSinceDeath; } player.m_hardDeathCooldown = (PluginConfig.IsModEnabled.Value ? GetConfigHardDeathCooldown() : 600f); } public static bool TryGetStatusEffect(this Player player, int nameHash, out StatusEffect statusEffect) { foreach (StatusEffect statusEffect2 in ((Character)player).m_seman.m_statusEffects) { if (Object.op_Implicit((Object)(object)statusEffect2) && statusEffect2.NameHash() == nameHash) { statusEffect = statusEffect2; return true; } } statusEffect = null; return false; } public static float GetSkillLossFactor() { return Mathf.Min(PluginConfig.SkillLossPercentOverride.Value * 0.01f, Game.m_skillReductionRate); } } [BepInPlugin("redseiko.valheim.comfytools.licensetoskill", "LicenseToSkill", "1.5.0")] public sealed class LicenseToSkill : BaseUnityPlugin { public const string PluginGUID = "redseiko.valheim.comfytools.licensetoskill"; public const string PluginName = "LicenseToSkill"; public const string PluginVersion = "1.5.0"; private void Awake() { PluginConfig.BindConfig(((BaseUnityPlugin)this).Config); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "redseiko.valheim.comfytools.licensetoskill"); } } [HarmonyPatch(typeof(Player))] internal static class PlayerPatch { [HarmonyPostfix] [HarmonyPatch("OnSpawned")] private static void OnSpawnedPostfix(ref Player __instance) { if (PluginConfig.IsModEnabled.Value && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { __instance.m_hardDeathCooldown = StatusEffectUtils.GetConfigHardDeathCooldown(); } } [HarmonyPostfix] [HarmonyPatch("HardDeath")] private static void HardDeathPostfix(Player __instance, ref bool __result) { if (PluginConfig.IsModEnabled.Value && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { __result = __instance.m_timeSinceDeath > StatusEffectUtils.GetConfigHardDeathCooldown(); } } } [HarmonyPatch(typeof(SEMan))] internal static class SEManPatch { [HarmonyPostfix] [HarmonyPatch("AddStatusEffect", new Type[] { typeof(int), typeof(bool), typeof(int), typeof(float) })] private static void AddStatusEffectPostfix(SEMan __instance, ref StatusEffect __result) { if (PluginConfig.IsModEnabled.Value && (Object)(object)Player.m_localPlayer == (Object)(object)__instance.m_character && Object.op_Implicit((Object)(object)__result) && __result.NameHash() == SEMan.s_statusEffectSoftDeath) { __result.m_ttl = StatusEffectUtils.GetConfigHardDeathCooldown(); } } } [HarmonyPatch(typeof(Skills))] internal static class SkillsPatch { [HarmonyPrefix] [HarmonyPatch("LowerAllSkills")] private static void LowerAllSkillsPrefix(Skills __instance, ref float factor) { if (PluginConfig.IsModEnabled.Value && (Object)(object)__instance.m_player == (Object)(object)Player.m_localPlayer) { factor = Mathf.Min(PluginConfig.SkillLossPercentOverride.Value * 0.01f, factor); } } } } namespace ComfyLib { public static class ConfigFileExtensions { internal sealed class ConfigurationManagerAttributes { public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public bool? HideDefaultButton; public bool? HideSettingName; public bool? IsAdvanced; public int? Order; public bool? ReadOnly; } private static readonly Dictionary<string, int> _sectionToSettingOrder = new Dictionary<string, int>(); private static int GetSettingOrder(string section) { if (!_sectionToSettingOrder.TryGetValue(section, out var value)) { value = 0; } _sectionToSettingOrder[section] = value - 1; return value; } public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, new object[1] { new ConfigurationManagerAttributes { Order = GetSettingOrder(section) } })); } public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, Action<ConfigEntryBase> customDrawer = null, bool browsable = true, bool hideDefaultButton = false, bool hideSettingName = false, bool isAdvanced = false, bool readOnly = false) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = browsable, CustomDrawer = customDrawer, HideDefaultButton = hideDefaultButton, HideSettingName = hideSettingName, IsAdvanced = isAdvanced, Order = GetSettingOrder(section), ReadOnly = readOnly } })); } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action settingChangedHandler) { configEntry.SettingChanged += delegate { settingChangedHandler(); }; } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<T> settingChangedHandler) { configEntry.SettingChanged += delegate(object _, EventArgs eventArgs) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) settingChangedHandler((T)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue); }; } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<ConfigEntry<T>> settingChangedHandler) { configEntry.SettingChanged += delegate(object _, EventArgs eventArgs) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) settingChangedHandler((ConfigEntry<T>)(object)((SettingChangedEventArgs)eventArgs).ChangedSetting); }; } } }