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 SkillEXPBoost v1.3.0
plugins/SkillEXPBoost.dll
Decompiled 5 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("1.3.0.0")] [assembly: AssemblyTitle("SkillEXPBoost - Skill XP and progress display for Valheim")] [assembly: AssemblyDescription("Client-side Valheim mod for configurable skill XP and HUD progress display.")] [assembly: AssemblyCompany("Rollstuhltreter")] [assembly: AssemblyProduct("SkillEXPBoost")] [assembly: AssemblyCopyright("Copyright (c) Rollstuhltreter")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.3.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [BepInPlugin("kann.valheim.skillmultiplier", "SkillEXPBoost", "1.3.0")] public sealed class SkillExperiencePlugin : BaseUnityPlugin { public const string PluginGuid = "kann.valheim.skillmultiplier"; public const string PluginName = "SkillEXPBoost"; public const string PluginVersion = "1.3.0"; internal static ConfigEntry<bool> Enable; internal static ConfigEntry<float> CombatSkillsMultiplier; internal static ConfigEntry<float> NormalSkillsMultiplier; internal static ConfigEntry<float> FarmSkillsMultiplier; internal static ConfigEntry<bool> ShowSkillProgress; internal static ConfigEntry<float> SkillProgressAggregationWindow; internal static ConfigEntry<float> SkillProgressDuration; private static SkillExperiencePlugin Instance; private readonly Dictionary<SkillType, float> _pendingSkillXp = new Dictionary<SkillType, float>(); private Skills _pendingSkills; private float _nextProgressFlush; private float _progressVisibleUntil; private string _progressText; private void Awake() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) Instance = this; Enable = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable", true, "Enable the skill experience multiplier for the local player. Changes apply immediately."); CombatSkillsMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "CombatSkillsMultiplier", 2f, "Combat skills: Swords, Knives, Clubs, Polearms, Spears, Blocking, Axes, Bows, Crossbows, Unarmed, ElementalMagic and BloodMagic."); NormalSkillsMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "NormalSkillsMultiplier", 2f, "Normal skills: Jump, Sneak, Run, Swim, Dodge, Ride, Cooking and Crafting."); FarmSkillsMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "FarmSkillsMultiplier", 2f, "Farm and gathering skills: Pickaxes, WoodCutting, Fishing and Farming."); ShowSkillProgress = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowSkillProgress", false, "Show a compact custom XP display. XP gains are combined instead of being queued with loot messages. Disabled by default."); SkillProgressAggregationWindow = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "SkillProgressAggregationWindow", 0.75f, "Seconds used to combine repeated XP gains for the same skill into one display update."); SkillProgressDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "SkillProgressDuration", 1.25f, "Seconds the combined skill progress display stays visible."); new Harmony("kann.valheim.skillmultiplier").PatchAll(); } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { if (ShowSkillProgress == null || !ShowSkillProgress.Value) { _pendingSkillXp.Clear(); _progressText = null; } else if (_pendingSkillXp.Count != 0 && !(Time.unscaledTime < _nextProgressFlush)) { _progressText = BuildProgressText(); _pendingSkillXp.Clear(); _progressVisibleUntil = Time.unscaledTime + SanitizeDisplayTime(SkillProgressDuration.Value, 1.25f); } } private void OnGUI() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_004e: 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) if (!string.IsNullOrEmpty(_progressText) && !(Time.unscaledTime >= _progressVisibleUntil)) { GUIStyle val = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)0, fontSize = 16, fontStyle = (FontStyle)1, wordWrap = true }; val.normal.textColor = Color.white; GUI.Label(new Rect(24f, 64f, 520f, 160f), _progressText, val); } } internal static void RecordSkillGain(Skills skills, SkillType skillType, float amount) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance != (Object)null) { Instance.QueueSkillGain(skills, skillType, amount); } } private void QueueSkillGain(Skills skills, SkillType skillType, float amount) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (!(amount <= 0f) && !float.IsNaN(amount) && !float.IsInfinity(amount)) { if (_pendingSkillXp.Count == 0) { _nextProgressFlush = Time.unscaledTime + SanitizeDisplayTime(SkillProgressAggregationWindow.Value, 0.75f); } _pendingSkills = skills; _pendingSkillXp.TryGetValue(skillType, out var value); _pendingSkillXp[skillType] = value + amount; } } private string BuildProgressText() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_pendingSkills == (Object)null) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder("XP gained"); foreach (KeyValuePair<SkillType, float> item in _pendingSkillXp) { int num = (int)Math.Floor(_pendingSkills.GetSkillLevel(item.Key)); float skillProgressPercent = GetSkillProgressPercent(_pendingSkills, item.Key); stringBuilder.Append('\n'); stringBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}: +{1:0.##} XP | Level {2} ({3:0.##}%)", item.Key, item.Value, num, skillProgressPercent); } return stringBuilder.ToString(); } private static float GetSkillProgressPercent(Skills skills, SkillType skillType) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) foreach (Skill skill in skills.GetSkillList()) { if (skill != null && skill.m_info != null && skill.m_info.m_skill == skillType) { return Math.Max(0f, Math.Min(100f, skill.GetLevelPercentage() * 100f)); } } return 0f; } private static float SanitizeDisplayTime(float value, float fallback) { if (float.IsNaN(value) || float.IsInfinity(value)) { return fallback; } return Math.Max(0.1f, Math.Min(10f, value)); } internal static float GetMultiplier(SkillType skillType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected I4, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected I4, but got Unknown if ((int)skillType == 0 || (int)skillType == 999) { return 1f; } switch (skillType - 1) { default: switch (skillType - 100) { case 0: case 1: case 2: case 3: case 5: case 7: case 8: case 10: return Sanitize(NormalSkillsMultiplier.Value); case 4: case 6: break; default: return 1f; } break; case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 13: return Sanitize(CombatSkillsMultiplier.Value); case 11: case 12: break; } return Sanitize(FarmSkillsMultiplier.Value); } private static float Sanitize(float value) { if (float.IsNaN(value) || float.IsInfinity(value)) { return 1f; } return Math.Max(0f, value); } } [HarmonyPatch(typeof(Skills), "RaiseSkill")] internal static class SkillsRaiseSkillMultiplierPatch { private static void Prefix(Skills __instance, SkillType __0, ref float __1) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (SkillExperiencePlugin.Enable != null && SkillExperiencePlugin.Enable.Value && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)((Character)Player.m_localPlayer).GetSkills() != (Object)(object)__instance)) { __1 *= SkillExperiencePlugin.GetMultiplier(__0); } } } [HarmonyPatch(typeof(Skills), "RaiseSkill")] internal static class SkillsRaiseSkillDisplayPatch { private static void Postfix(Skills __instance, SkillType __0, float __1) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (SkillExperiencePlugin.ShowSkillProgress != null && SkillExperiencePlugin.ShowSkillProgress.Value && !(__1 <= 0f) && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)((Character)Player.m_localPlayer).GetSkills() != (Object)(object)__instance)) { SkillExperiencePlugin.RecordSkillGain(__instance, __0, __1); } } }