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 XPNotifications v1.0.2
BepInEx/plugins/XPNotifications/XPNotifications.dll
Decompiled a week agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("XPNotifications")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("XPNotifications")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e1329ce9-86b5-4966-a0ea-5ff51794d9e9")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace XPNotifications; internal sealed class ConfigurationManagerAttributes { public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput); public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public CustomHotkeyDrawerFunc CustomHotkeyDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } public enum RunXPMode { Disabled, Normal, Throttling } [BepInPlugin("com.someone15145.xpnotifications", "XP Notifications", "1.0.2")] public class Main : BaseUnityPlugin { public const string MODNAME = "XP Notifications"; public const string AUTHOR = "someone15145"; public const string GUID = "com.someone15145.xpnotifications"; public const string VERSION = "1.0.2"; internal static ManualLogSource Log; public static ConfigEntry<bool> ShowXPNotifications; public static ConfigEntry<MessageType> NotificationPosition; public static ConfigEntry<string> NotificationFormat; public static ConfigEntry<int> NotificationTextSizeXP; public static ConfigEntry<RunXPMode> RunXPBehavior; public static ConfigEntry<int> RunXPTimeout; private readonly Harmony _harmony = new Harmony("com.someone15145.xpnotifications"); private void Awake() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ShowXPNotifications = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowXPNotifications", true, new ConfigDescription("Enable/disable all XP notifications.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); NotificationFormat = ((BaseUnityPlugin)this).Config.Bind<string>("General", "NotificationFormat", "{0}% ({2}/{3}) [+{1}] Lv.{4}", new ConfigDescription("Format string placeholders:\n{0}: % | {1}: Gained | {2}: Current | {3}: Next Level | {4}: Level", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 4 } })); NotificationPosition = ((BaseUnityPlugin)this).Config.Bind<MessageType>("General", "NotificationPosition", (MessageType)1, new ConfigDescription("Screen position: TopLeft or Center.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); NotificationTextSizeXP = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NotificationTextSizeXP", 14, new ConfigDescription("Notification font size.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 40), new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); RunXPBehavior = ((BaseUnityPlugin)this).Config.Bind<RunXPMode>("General", "RunXPBehavior", RunXPMode.Throttling, new ConfigDescription("Running skill behavior:\nDisabled: Off\nNormal: Every gain\nThrottling: Once per X seconds", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); RunXPTimeout = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RunXPTimeout", 2, new ConfigDescription("Cooldown (seconds) for Throttling mode.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 20), new object[1] { new ConfigurationManagerAttributes { Order = 0 } })); _harmony.PatchAll(typeof(Patches)); Log.LogInfo((object)"[XP Notifications] v1.0.2 loaded successfully"); } } internal static class Patches { [HarmonyPatch(typeof(Skills), "RaiseSkill")] [HarmonyPostfix] private static void RaiseSkill_Postfix(Skills __instance, SkillType skillType, float factor = 1f) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if ((int)skillType != 0 && Main.ShowXPNotifications.Value) { object? obj = AccessTools.Method(typeof(Skills), "GetSkill", new Type[1] { typeof(SkillType) }, (Type[])null).Invoke(__instance, new object[1] { skillType }); Skill val = (Skill)((obj is Skill) ? obj : null); if (val != null) { XPNotification.Show(val, factor); } } } } internal static class XPNotification { private static float _lastRunXPTime; public static void Show(Skill skill, float factor) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_0171: Unknown result type (might be due to invalid IL or missing references) if (skill.m_level >= 100f) { return; } if ((int)skill.m_info.m_skill == 102) { switch (Main.RunXPBehavior.Value) { case RunXPMode.Disabled: return; case RunXPMode.Throttling: if (Time.time - _lastRunXPTime < (float)Main.RunXPTimeout.Value) { return; } _lastRunXPTime = Time.time; break; } } string text = Localization.instance.Localize("$skill_" + ((object)(SkillType)(ref skill.m_info.m_skill)).ToString().ToLower()); float num = (float)Math.Round(skill.GetLevelPercentage() * 100f, 1); float num2 = Mathf.Pow(skill.m_level + 1f, 1.5f) * 0.5f + 0.5f; float num3 = (float)Math.Round(skill.m_accumulator, 2); float num4 = (float)Math.Round(num2, 2); float num5 = (float)Math.Round(skill.m_info.m_increseStep * factor, 2); int num6 = Mathf.FloorToInt(skill.m_level); string text2; try { text2 = string.Format(Main.NotificationFormat.Value, num, num5, num3, num4, num6); } catch { text2 = $"{num}%"; } string arg = text + ": " + text2; MessageHud.instance.ShowMessage(Main.NotificationPosition.Value, $"<size={Main.NotificationTextSizeXP.Value}>{arg}</size>", 0, (Sprite)null, false); } }