using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; 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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SkillNotifier")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SkillNotifier")] [assembly: AssemblyTitle("SkillNotifier")] [assembly: AssemblyVersion("1.0.0.0")] [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 SkillNotifier { [BepInPlugin("Harchytek.SkillNotifier", "SkillNotifier", "1.1.0")] public class SkillNotifierPlugin : BaseUnityPlugin { public enum LevelPos { BeforeSkill, AfterSkill, BeforeTotal } public enum TotalPos { Start, End } public enum GainXpPos { BeforeExtended, AfterExtended } [HarmonyPatch(typeof(Skills), "RaiseSkill")] public static class Patch_RaiseSkill { private static readonly FieldInfo SkillDataField = typeof(Skills).GetField("m_skillData", BindingFlags.Instance | BindingFlags.NonPublic); private static float _xpBefore; private static float _levelBefore; private static (string start, string end) GetBrackets(string input) { if (string.IsNullOrEmpty(input)) { return ("", ""); } if (input.Length >= 2) { return (input[0].ToString(), input[1].ToString()); } return (input, ""); } [HarmonyPrefix] private static void Prefix(Skills __instance, SkillType skillType) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (SkillDataField?.GetValue(__instance) is Dictionary dictionary && dictionary.TryGetValue(skillType, out var value)) { _xpBefore = value.m_accumulator; _levelBefore = value.m_level; } } private static void Postfix(Skills __instance, SkillType skillType, float factor = 1f) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) if ((SkipRunningSkillNotifications.Value && (int)skillType == 102) || !ShowXPNotifications.Value || !(SkillDataField?.GetValue(__instance) is Dictionary dictionary) || !dictionary.TryGetValue(skillType, out var value)) { return; } float accumulator = value.m_accumulator; float num = accumulator - _xpBefore; if (num < 0f) { num = accumulator; } float num2 = (value.m_level + 1f) * 2f; float num3 = accumulator / num2 * 100f; string text = ((object)(SkillType)(ref value.m_info.m_skill)).ToString().ToLower(); string text2 = Localization.instance.Localize("$skill_" + text); string text3 = $""; string text4 = ""; if (ShowSkillLevel.Value) { (string, string) brackets = GetBrackets(SymbolsLevel.Value); string text5 = TextSkillLevel.Value; if (AutoSpaceSkillLevel.Value && !string.IsNullOrEmpty(text5)) { text5 += " "; } text4 = $"{brackets.Item1}{text5}{value.m_level:0}{brackets.Item2}"; } string text6 = ""; if (ShowCharacterXP.Value) { if (_cachedTotalLevel < 0f || value.m_level != _levelBefore) { _cachedTotalLevel = 0f; foreach (Skill value2 in dictionary.Values) { _cachedTotalLevel += value2.m_level; } } (string, string) brackets2 = GetBrackets(SymbolsTotal.Value); string text7 = TextTotalLevel.Value; if (AutoSpaceTotalLevel.Value && !string.IsNullOrEmpty(text7)) { text7 += " "; } text6 = $"{brackets2.Item1}{text7}{_cachedTotalLevel:0}{brackets2.Item2}"; } if (ShowCharacterXP.Value && CharacterXPPosition.Value == TotalPos.Start) { text3 = text3 + text6 + " "; } if (!string.IsNullOrEmpty(SkillSymbol.Value)) { text3 = text3 + SkillSymbol.Value + " "; } if (ShowSkillLevel.Value && SkillLevelPosition.Value == LevelPos.BeforeSkill) { text3 = text3 + text4 + " "; } text3 = text3 + "" + text2 + ""; if (ShowSkillLevel.Value && SkillLevelPosition.Value == LevelPos.AfterSkill) { text3 = text3 + " " + text4; } if (ShowGainPourcent.Value || ShowGainXP.Value || ShowExtendedXP.Value) { text3 += " :"; if (ShowGainPourcent.Value) { (string, string) brackets3 = GetBrackets(SymbolsPercent.Value); text3 += $" {brackets3.Item1}{num3:0.##} %{brackets3.Item2}"; } string text8 = ""; if (ShowGainXP.Value) { (string, string) brackets4 = GetBrackets(SymbolsGain.Value); text8 = $" {brackets4.Item1}+{num:0.0}{brackets4.Item2}"; } string text9 = ""; if (ShowExtendedXP.Value) { (string, string) brackets5 = GetBrackets(SymbolsExtended.Value); text9 = $" {brackets5.Item1}{accumulator:0.##}/{num2:0.##}{brackets5.Item2}"; } text3 = ((GainXPPosition.Value != 0) ? (text3 + text9 + text8) : (text3 + text8 + text9)); } else if (!string.IsNullOrEmpty(TextFallbackMessage.Value)) { text3 = text3 + " " + TextFallbackMessage.Value; } if (ShowSkillLevel.Value && SkillLevelPosition.Value == LevelPos.BeforeTotal) { text3 = text3 + " " + text4; } if (ShowCharacterXP.Value && CharacterXPPosition.Value == TotalPos.End) { text3 = text3 + " " + text6; } text3 += ""; if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)1, text3, 0, (Sprite)null, false); } } } public const string ModGUID = "Harchytek.SkillNotifier"; public const string ModName = "SkillNotifier"; public const string ModVersion = "1.1.0"; public static ConfigEntry ShowXPNotifications; public static ConfigEntry NotificationTextSizeXP; public static ConfigEntry SkipRunningSkillNotifications; public static ConfigEntry ShowSkillLevel; public static ConfigEntry ShowGainPourcent; public static ConfigEntry ShowGainXP; public static ConfigEntry ShowExtendedXP; public static ConfigEntry ShowCharacterXP; public static ConfigEntry TextSkillLevel; public static ConfigEntry AutoSpaceSkillLevel; public static ConfigEntry TextTotalLevel; public static ConfigEntry AutoSpaceTotalLevel; public static ConfigEntry TextFallbackMessage; public static ConfigEntry SkillLevelPosition; public static ConfigEntry CharacterXPPosition; public static ConfigEntry GainXPPosition; public static ConfigEntry SkillSymbol; public static ConfigEntry SymbolsLevel; public static ConfigEntry SymbolsPercent; public static ConfigEntry SymbolsGain; public static ConfigEntry SymbolsExtended; public static ConfigEntry SymbolsTotal; public static ConfigEntry ColorSkillName; public static ConfigEntry ColorSkillLevel; public static ConfigEntry ColorPercentage; public static ConfigEntry ColorXPGain; public static ConfigEntry ColorExtendedXP; public static ConfigEntry ColorTotalLevel; public static string _hexSkillName; public static string _hexSkillLevel; public static string _hexPercentage; public static string _hexXPGain; public static string _hexExtendedXP; public static string _hexTotalLevel; public static float _cachedTotalLevel = -1f; private void Awake() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Expected O, but got Unknown //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Expected O, but got Unknown //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Expected O, but got Unknown //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Expected O, but got Unknown //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Expected O, but got Unknown //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Expected O, but got Unknown //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Expected O, but got Unknown //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Expected O, but got Unknown //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Expected O, but got Unknown //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Expected O, but got Unknown //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Expected O, but got Unknown //IL_050e: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Expected O, but got Unknown //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Expected O, but got Unknown //IL_0596: Unknown result type (might be due to invalid IL or missing references) //IL_05a0: Expected O, but got Unknown //IL_05b5: Unknown result type (might be due to invalid IL or missing references) //IL_05da: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Expected O, but got Unknown //IL_0608: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Unknown result type (might be due to invalid IL or missing references) //IL_0637: Expected O, but got Unknown //IL_065b: Unknown result type (might be due to invalid IL or missing references) //IL_0680: Unknown result type (might be due to invalid IL or missing references) //IL_068a: Expected O, but got Unknown //IL_069f: Unknown result type (might be due to invalid IL or missing references) //IL_06c4: Unknown result type (might be due to invalid IL or missing references) //IL_06ce: Expected O, but got Unknown //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_0717: Unknown result type (might be due to invalid IL or missing references) //IL_0721: Expected O, but got Unknown //IL_0745: Unknown result type (might be due to invalid IL or missing references) //IL_076a: Unknown result type (might be due to invalid IL or missing references) //IL_0774: Expected O, but got Unknown //IL_0808: Unknown result type (might be due to invalid IL or missing references) ShowXPNotifications = ((BaseUnityPlugin)this).Config.Bind("1 - General", "ShowXPNotifications", true, new ConfigDescription("Enable or disable XP notifications.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); SkipRunningSkillNotifications = ((BaseUnityPlugin)this).Config.Bind("1 - General", "SkipRunningSkillNotifications", true, new ConfigDescription("Ignore notifications for the running skill.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); NotificationTextSizeXP = ((BaseUnityPlugin)this).Config.Bind("1 - General", "NotificationTextSizeXP", 18, new ConfigDescription("Text size of the notifications.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); ShowSkillLevel = ((BaseUnityPlugin)this).Config.Bind("2 - Visibility", "ShowSkillLevel", true, new ConfigDescription("Show the current skill level.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); ShowGainPourcent = ((BaseUnityPlugin)this).Config.Bind("2 - Visibility", "ShowGainPourcent", true, new ConfigDescription("Show the progress percentage.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 4 } })); ShowGainXP = ((BaseUnityPlugin)this).Config.Bind("2 - Visibility", "ShowGainXP", true, new ConfigDescription("Show the actual XP gained.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); ShowExtendedXP = ((BaseUnityPlugin)this).Config.Bind("2 - Visibility", "ShowExtendedXP", true, new ConfigDescription("Show the extended XP ratio [Current/Needed].", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); ShowCharacterXP = ((BaseUnityPlugin)this).Config.Bind("2 - Visibility", "ShowCharacterXP", true, new ConfigDescription("Show the total character level.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); TextSkillLevel = ((BaseUnityPlugin)this).Config.Bind("3 - Text", "TextSkillLevel", "Level", new ConfigDescription("Text displayed before the skill level.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); AutoSpaceSkillLevel = ((BaseUnityPlugin)this).Config.Bind("3 - Text", "AutoSpaceSkillLevel", true, new ConfigDescription("Automatically add a space after the skill level text.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 4 } })); TextTotalLevel = ((BaseUnityPlugin)this).Config.Bind("3 - Text", "TextTotalLevel", "Total:", new ConfigDescription("Text displayed before the total level.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); AutoSpaceTotalLevel = ((BaseUnityPlugin)this).Config.Bind("3 - Text", "AutoSpaceTotalLevel", true, new ConfigDescription("Automatically add a space after the total level text.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); TextFallbackMessage = ((BaseUnityPlugin)this).Config.Bind("3 - Text", "TextFallbackMessage", "you win something, but what?", new ConfigDescription("Message displayed if all XP stats are hidden. Leave empty to disable.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); SkillLevelPosition = ((BaseUnityPlugin)this).Config.Bind("4 - Position", "SkillLevelPosition", LevelPos.AfterSkill, new ConfigDescription("Position of the level: Before Skill Name, After Skill Name, or Before Total Level.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); GainXPPosition = ((BaseUnityPlugin)this).Config.Bind("4 - Position", "GainXPPosition", GainXpPos.BeforeExtended, new ConfigDescription("Position of the gained XP: Before or After the Extended XP.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); CharacterXPPosition = ((BaseUnityPlugin)this).Config.Bind("4 - Position", "CharacterXPPosition", TotalPos.End, new ConfigDescription("Position of the total level: At the start or at the end of the message.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); SkillSymbol = ((BaseUnityPlugin)this).Config.Bind("5 - Symbols", "SkillSymbol", "", new ConfigDescription("Symbol prefix before the skill name (e.g., ●, ◆, ->).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 6 } })); SymbolsLevel = ((BaseUnityPlugin)this).Config.Bind("5 - Symbols", "SymbolsLevel", "[]", new ConfigDescription("Symbols wrapping the skill level (e.g., [], (), {}).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); SymbolsPercent = ((BaseUnityPlugin)this).Config.Bind("5 - Symbols", "SymbolsPercent", "", new ConfigDescription("Symbols wrapping the percentage (e.g., [], (), {}).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 4 } })); SymbolsGain = ((BaseUnityPlugin)this).Config.Bind("5 - Symbols", "SymbolsGain", "()", new ConfigDescription("Symbols wrapping the XP gain (e.g., [], (), {}).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); SymbolsExtended = ((BaseUnityPlugin)this).Config.Bind("5 - Symbols", "SymbolsExtended", "()", new ConfigDescription("Symbols wrapping the Extended XP (e.g., [], (), {}).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); SymbolsTotal = ((BaseUnityPlugin)this).Config.Bind("5 - Symbols", "SymbolsTotal", "[]", new ConfigDescription("Symbols wrapping the Total character level (e.g., [], (), {}).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); ColorSkillName = ((BaseUnityPlugin)this).Config.Bind("6 - Colors", "ColorSkillName", Color.white, new ConfigDescription("Color of the skill name.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 6 } })); ColorSkillLevel = ((BaseUnityPlugin)this).Config.Bind("6 - Colors", "ColorSkillLevel", new Color(1f, 0.843f, 0f), new ConfigDescription("Color of the skill level.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); ColorPercentage = ((BaseUnityPlugin)this).Config.Bind("6 - Colors", "ColorPercentage", new Color(0.678f, 0.847f, 0.902f), new ConfigDescription("Color of the progress percentage.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 4 } })); ColorXPGain = ((BaseUnityPlugin)this).Config.Bind("6 - Colors", "ColorXPGain", Color.green, new ConfigDescription("Color of the XP gain.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); ColorExtendedXP = ((BaseUnityPlugin)this).Config.Bind("6 - Colors", "ColorExtendedXP", new Color(1f, 0.843f, 0f), new ConfigDescription("Color of the extended XP ratio [Current/Needed].", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); ColorTotalLevel = ((BaseUnityPlugin)this).Config.Bind("6 - Colors", "ColorTotalLevel", new Color(1f, 0.647f, 0f), new ConfigDescription("Color of the total character level.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); UpdateHexColors(); ColorSkillName.SettingChanged += delegate { UpdateHexColors(); }; ColorSkillLevel.SettingChanged += delegate { UpdateHexColors(); }; ColorPercentage.SettingChanged += delegate { UpdateHexColors(); }; ColorXPGain.SettingChanged += delegate { UpdateHexColors(); }; ColorExtendedXP.SettingChanged += delegate { UpdateHexColors(); }; ColorTotalLevel.SettingChanged += delegate { UpdateHexColors(); }; new Harmony("Harchytek.SkillNotifier").PatchAll(); } private void UpdateHexColors() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) _hexSkillName = "#" + ColorUtility.ToHtmlStringRGB(ColorSkillName.Value); _hexSkillLevel = "#" + ColorUtility.ToHtmlStringRGB(ColorSkillLevel.Value); _hexPercentage = "#" + ColorUtility.ToHtmlStringRGB(ColorPercentage.Value); _hexXPGain = "#" + ColorUtility.ToHtmlStringRGB(ColorXPGain.Value); _hexExtendedXP = "#" + ColorUtility.ToHtmlStringRGB(ColorExtendedXP.Value); _hexTotalLevel = "#" + ColorUtility.ToHtmlStringRGB(ColorTotalLevel.Value); } } public class ConfigurationManagerAttributes { public int? Order; } }