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 MultitudesDifficulty v1.1.0
MultitudesDifficulty.dll
Decompiled 3 weeks agousing System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using EntityStates.AurelioniteHeart; using EntityStates.Croco; using EntityStates.FalseSonBoss; using EntityStates.Geode; using EntityStates.Missions.GeodeSecretMission; using EntityStates.VoidCamp; using HarmonyLib; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.Utils; using MultitudesDifficulty.Properties; using R2API; using RoR2; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.Networking; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.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; } } } namespace Local.Difficulty.Multitudes { public static class Session { public static decimal players; public static decimal interactableScale; public static bool multiply; public static bool extraRewards; public static decimal incomePenalty; public static decimal bonusHealth; public static decimal teleporterChargeRate; private static Harmony instance; private static bool broadcast; [Obsolete("If needed, refer to `GetAdditionalPlayers` instead.")] public static readonly decimal additionalPlayers; internal static void Begin(Run thisRun) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (instance == null && NetworkServer.active && (Setup.forceEnable || thisRun.selectedDifficulty == Setup.index)) { instance = Harmony.CreateAndPatchAll(typeof(Settings), (string)null); instance.PatchAll(typeof(Session)); } } internal static void End(object _) { broadcast = false; Harmony obj = instance; if (obj != null) { obj.UnpatchSelf(); } instance = null; } public static decimal GetAdditionalPlayers(decimal limit = 1m) { Setup.GetPlayerCount(out var __result); if (multiply) { return (decimal)__result * (players - 1m) * limit; } if (__result > 0) { return players * limit; } return 0m; } [HarmonyPatch(typeof(SurvivorPodController), "OnPassengerExit")] [HarmonyPatch(typeof(WakeUp), "OnExit")] [HarmonyPatch(typeof(InfiniteTowerRun), "OnSafeWardActivated")] [HarmonyPostfix] private static void GreetUser() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown if (broadcast) { return; } string text = "Multitudes Enabled\n"; broadcast = true; if (RoR2Application.isInMultiPlayer) { text += Settings.BuildDescription(verbose: false); } else { if (!Setup.eclipseMode || !((double)Random.value < 0.15)) { return; } text = "Good luck."; } text = "<color=#" + ColorUtility.ToHtmlStringRGB(Setup.theme) + ">" + text + "</color>"; Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = text }); } [HarmonyPatch(typeof(SceneDirector), "Start")] [HarmonyILManipulator] private static void AdjustInteractableCredits(ILContext context) { InsertHook(context, typeof(Session).GetField("interactableScale"), typeof(Run).GetProperty("participatingPlayerCount").GetMethod); } [HarmonyPatch(typeof(BossGroup), "DropRewards")] [HarmonyILManipulator] private static void AdjustBossRewards(ILContext context) { ApplyPlayerAdjustment(context); } [HarmonyPatch(typeof(TeamManager), "GiveTeamMoney", new Type[] { typeof(TeamIndex), typeof(uint) })] [HarmonyILManipulator] private static void AdjustPlayerIncome(ILContext context) { InsertHook(context, typeof(Session).GetField("incomePenalty"), typeof(Run).GetProperty("livingPlayerCount").GetMethod); } internal static void InsertHook(ILContext context, FieldInfo field, MethodInfo method) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(context); string fullName = ((MemberReference)context.Method).FullName; while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt(i, (MethodBase)method) })) { int index = int.MinValue; while (OpCodes.Conv_R4 != val.Next.OpCode) { if (index < 0) { val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchStloc(i, ref index) }); } if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, index) })) { Console.WriteLine("Unable to insert hook.\n\t" + fullName); return; } } int index2 = val.Index + 1; val.Index = index2; val.Emit(OpCodes.Ldsfld, field); val.Emit(OpCodes.Call, (MethodBase)typeof(Session).GetMethod("GetAdditionalPlayers")); val.Emit(OpCodes.Call, (MethodBase)typeof(decimal).GetMethod("ToSingle")); val.Emit(OpCodes.Add); } if (val.Index == 0) { Console.WriteLine("No match found.\n\t" + fullName); } } [HarmonyPatch(typeof(CombatDirector), "Spawn")] [HarmonyPatch(typeof(CharacterMaster), "ScaleDifficultyAsBoss")] [HarmonyILManipulator] private static void AddBonusHealth(ILContext context, MethodBase __originalMethod) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown if (__originalMethod.DeclaringType == typeof(CombatDirector)) { MethodReference target = null; MethodReference val = default(MethodReference); Func<Instruction, bool>[] array = new Func<Instruction, bool>[3] { (Instruction i) => ILPatternMatchingExt.MatchLdftn(i, ref target), (Instruction i) => ILPatternMatchingExt.MatchNewobj(i, ref val), (Instruction i) => ILPatternMatchingExt.MatchStfld<DirectorSpawnRequest>(i, "onSpawnedServer") }; if (new ILCursor(context).TryGotoNext(array)) { instance.Patch(ReflectionHelper.ResolveReflection(target), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(MethodBase.GetCurrentMethod() as MethodInfo)); return; } } InsertHook(context, typeof(Session).GetField("bonusHealth"), typeof(Run).GetProperty("livingPlayerCount").GetMethod); } [HarmonyPatch(typeof(HoldoutZoneController), "DoUpdate")] [HarmonyILManipulator] private static void AdjustChargeRate(ILContext context) { MethodInfo method = typeof(HoldoutZoneController).GetMethod("CountLivingPlayers", AccessTools.all); InsertHook(context, typeof(Session).GetField("teleporterChargeRate"), method); } [HarmonyPatch(typeof(EscapeSequenceController), "BeginEscapeSequence")] [HarmonyPrefix] private static void IncreaseCountdown(EscapeSequenceController __instance) { decimal num = GetAdditionalPlayers(teleporterChargeRate); Setup.GetPlayerCount(out var __result); if (num > 0m) { __instance.countdownDuration *= decimal.ToSingle(1m + num / (decimal)__result); } } [HarmonyPatch(typeof(Run), "RecalculateDifficultyCoefficentInternal")] [HarmonyPatch(typeof(DirectorMoneyWave), "Update")] [HarmonyPatch(typeof(OnCollisionEventController), "OnTriggerStay")] [HarmonyILManipulator] private static void IncreaseDifficultyCoefficient(ILContext context) { InsertHook(context, typeof(decimal).GetField("One"), typeof(Run).GetProperty("participatingPlayerCount").GetMethod); } [HarmonyPatch(typeof(ArenaMissionController), "EndRound")] [HarmonyPatch(typeof(InfiniteTowerWaveController), "DropRewards")] [HarmonyPatch(typeof(Deactivate), "OnEnter")] [HarmonyPatch(typeof(HalcyoniteShrineInteractable), "DropRewards")] [HarmonyPatch(typeof(SkyJumpDeathState), "GiveColossusItem")] [HarmonyPatch(typeof(AurelioniteHeartActivationState), "FixedUpdate")] [HarmonyPatch(typeof(GeodeSecretMissionRewardState), "DropRewards")] [HarmonyPatch(typeof(GeodeShatter), "OnEnter")] [HarmonyPatch(typeof(Death), "OnEnter")] [HarmonyILManipulator] private static void ApplyPlayerAdjustment(ILContext context) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(context); MethodInfo method = typeof(Run).GetProperty("participatingPlayerCount").GetMethod; while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt(i, (MethodBase)method) })) { val.Emit(OpCodes.Ldsfld, typeof(decimal).GetField("One")); val.Emit(OpCodes.Call, (MethodBase)typeof(Session).GetMethod("GetAdditionalPlayers")); val.Emit(OpCodes.Call, (MethodBase)typeof(decimal).GetMethod("ToInt32")); val.Emit(OpCodes.Ldsfld, typeof(Session).GetField("extraRewards")); val.Emit(OpCodes.Mul); val.Emit(OpCodes.Add); } if (val.Index == 0) { Console.WriteLine("No match found.\n\t" + ((MemberReference)context.Method).FullName); } } } internal static class Settings { internal static void Load(ConfigFile configuration) { Load(configuration, out var _); } internal static void Load(ConfigFile configuration, out bool eclipse) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown AcceptableValueRange<decimal> val = new AcceptableValueRange<decimal>(0m, 100m); int order = 0; try { configuration.Reload(); } catch (FileNotFoundException) { configuration.Clear(); } string title = default(string); section("General"); Session.players = configuration.Bind<decimal>(title, "Additional Player Count", 1m, new ConfigDescription("Add this many players to the game, increasing the difficulty of enemies. Also affects the other options listed below.", (AcceptableValueBase)(object)new AcceptableValueRange<decimal>(0.25m, 250m), Array.Empty<object>())).Value; eclipse = configuration.Bind<bool>(title, "Eclipse Mode", false, "Use eclipse modifiers. Please note, this requires a restart in order to take effect.").Value; Session.multiply = configuration.Bind<bool>(title, "Use Multiplicative Scaling", false, "Change this in order to multiply player count instead. Similar to the original version.").Value; section("Advanced"); Session.interactableScale = configuration.Bind<decimal>(title, "Additional Interactables", 0m, new ConfigDescription("Increase this percentage for more loot (i.e. chests, shrines, etc.) on each stage, proportional to player count.", (AcceptableValueBase)(object)val, Array.Empty<object>())).Value / val.MaxValue; Session.extraRewards = configuration.Bind<bool>(title, "Extra Item Rewards", false, "Enable to drop additional items from the teleporter event, other bosses, and hidden realms.").Value; Session.incomePenalty = configuration.Bind<decimal>(title, "Income Penalty", 75m, new ConfigDescription("Gold is typically split between all players. Lower this value to lessen this effect, increasing player income.", (AcceptableValueBase)(object)val, Array.Empty<object>())).Value / val.MaxValue; Session.bonusHealth = configuration.Bind<decimal>(title, "Bonus Health", 0m, new ConfigDescription("Certain enemies receive bonus health in multiplayer. Reduce the amount granted to teleporter bosses and unique encounters.", (AcceptableValueBase)(object)val, Array.Empty<object>())).Value / val.MaxValue; Session.teleporterChargeRate = configuration.Bind<decimal>(title, "Teleporter Duration", 0m, new ConfigDescription("The extent at which player count is considered when determining charge rate for holdout zones. Not recommended.", (AcceptableValueBase)(object)val, Array.Empty<object>())).Value / val.MaxValue; section("Other"); Setup.lobbyPlayerCount = !configuration.Bind<bool>(title, "Ignore Disconnected Players", false, "By default, players that leave a multiplayer lobby are still taken into account, until they reconnect.").Value; Setup.forceEnable = configuration.Bind<bool>(title, "Force Enable", false, "For use with other difficulty options. Apply the increase to player count regardless of selection.").Value; void section(string name) { int num = ++order; title = num + ". " + name; } } [HarmonyPatch(typeof(CurrentDifficultyIconController), "Start")] [HarmonyPrefix] private static void ShowPlayerCount(Component __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) Transform transform = __instance.transform; HGTextMeshProUGUI obj = new GameObject("PlayerText").AddComponent<HGTextMeshProUGUI>(); Transform transform2 = ((TMP_Text)obj).transform; transform2.SetParent(transform); transform2.localPosition = Vector3.zero; transform2.localRotation = new Quaternion(0f, (0f - transform.rotation.y) * 0.25f, 0f, 1f); transform2.localScale = Vector3.one; RectTransform rectTransform = ((TMP_Text)obj).rectTransform; rectTransform.anchorMin = Vector2.right; rectTransform.anchorMax = Vector2.one + Vector2.right * 1.5f; rectTransform.offsetMin = Vector2.down - Vector2.one * 0.75f; rectTransform.offsetMax = Vector2.zero; ((TMP_Text)obj).alignment = (TextAlignmentOptions)1025; ((TMP_Text)obj).fontSize = 12f; ((TMP_Text)obj).faceColor = Color32.op_Implicit(Setup.theme); ((TMP_Text)obj).outlineWidth = 0.125f; Setup.GetPlayerCount(out var __result); ((TMP_Text)obj).SetText(FormatFraction((decimal)__result + Session.GetAdditionalPlayers()) + "P", true); } internal static string BuildDescription(bool verbose = true) { string text = ""; if (verbose) { text = "For those who wish to face vast hordes of enemies alone. Multiplayer difficulty levels are in effect.\n\n<style=cStack>>Base Difficulty:</style> <style=cSub>" + (Setup.eclipseMode ? "Eclipse" : "Monsoon") + "</style>\n"; } string colorHexString = ColorCatalog.GetColorHexString((ColorIndex)4); string colorHexString2 = ColorCatalog.GetColorHexString((ColorIndex)5); text = text + "<style=cStack>>Player Count:</style> <style=cDeath>" + (Session.multiply ? "<font-weight=\"900\">×</font-weight>" : "+") + FormatFraction(Session.players) + "</style>\n<style=cStack>>Additional Interactables:</style> <style=cShrine>" + FormatPercent(Session.interactableScale, "None") + "</style>\n<style=cStack>>Extra Item Rewards:</style> " + (Session.extraRewards ? "<style=cIsHealing>Enabled</style>\n" : ("<color=#" + colorHexString2 + ">Disabled</color>\n")) + "<style=cStack>>Player Income:</style> <style=cIsUtility>+" + FormatPercent(1m - Session.incomePenalty) + " </style>\n<style=cStack>>Enemy Bonus Health:</style> <style=cIsVoid>" + FormatPercent(Session.bonusHealth - 1m, "+100%", "Off") + "</style>\n"; if (verbose || !(Session.teleporterChargeRate == 0m)) { text = text + "<style=cStack>>Teleporter Duration:</style> <sprite name=\"TP\"><color=#" + colorHexString + ">+" + FormatPercent(Session.teleporterChargeRate) + "</color>"; } return text; } private static string FormatFraction(decimal value) { decimal num = Math.Truncate(value); string text = ""; decimal num2 = value - num; if (!(num2 < 0.375m)) { text = ((!(num2 > 0.625m)) ? "½" : "¾"); } else if (num2 == 0m) { if (num == 0m) { return "0"; } } else { text = "¼"; } if (!(num != 0m)) { return text; } return num + text; } private static string FormatPercent(decimal value, string zero = null, string one = null) { string text = null; if (value == -1m) { goto IL_002f; } if (!(value == 0m)) { if (value == 1m) { goto IL_002f; } } else { text = zero; } goto IL_0031; IL_002f: text = one; goto IL_0031; IL_0031: return text ?? value.ToString("0.#%"); } } [BepInPlugin("local.difficulty.multitudes", "MultitudesDifficulty", "1.1.0")] public class Setup : BaseUnityPlugin { public const string identifier = "local.difficulty.multitudes"; public const string version = "1.1.0"; internal static DifficultyIndex index; internal static Color theme; private static DifficultyDef difficulty; private static RuleChoiceDef other; private static RuleChoiceDef choice; public static bool eclipseMode; public static bool lobbyPlayerCount; public static bool forceEnable; protected void Awake() { //IL_0023: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) Settings.Load(((BaseUnityPlugin)this).Config, out eclipseMode); SceneManager.sceneUnloaded += delegate { if (choice != null) { Settings.Load(((BaseUnityPlugin)this).Config); choice.tooltipBodyToken = (difficulty.descriptionToken = Settings.BuildDescription()); choice.excludeByDefault = forceEnable; } }; Color val = Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)15)); theme = new Color(val.r, val.b, val.g); index = (DifficultyIndex)(eclipseMode ? 127 : (-128)); difficulty = new DifficultyDef(DifficultyCatalog.GetDifficultyDef((DifficultyIndex)2).scalingValue, "Multitudes", (string)null, (string)null, theme, "mod", true); Texture2D val2 = new Texture2D(256, 256, (TextureFormat)5, 3, false); difficulty.foundIconSprite = ImageConversion.LoadImage(val2, eclipseMode ? Resources.eclipse : Resources.icon); difficulty.iconSprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), Vector2.zero); Harmony.CreateAndPatchAll(typeof(Setup), (string)null); Run.onRunStartGlobal += Session.Begin; Run.onRunDestroyGlobal += Session.End; } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] internal static bool GetPlayerCount(out int __result) { ReadOnlyCollection<PlayerCharacterMasterController> instances = PlayerCharacterMasterController.instances; __result = (lobbyPlayerCount ? instances.Count : instances.Where((PlayerCharacterMasterController player) => player.isConnected).Count()); return false; } [HarmonyPatch(typeof(RuleCatalog), "Init")] [HarmonyPostfix] private static void AddDifficulty() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Invalid comparison between Unknown and I4 RuleDef obj = RuleCatalog.allRuleDefs.First((RuleDef definition) => definition.globalName == "Difficulty"); choice = obj.AddChoice(difficulty.nameToken, (object)null, false); choice.difficultyIndex = index; choice.tooltipNameToken = difficulty.nameToken; choice.tooltipNameColor = difficulty.color; choice.serverTag = difficulty.serverTag; choice.sprite = difficulty.iconSprite; choice.globalIndex = RuleCatalog.allChoicesDefs.Count; RuleCatalog.allChoicesDefs.Add(choice); RuleCatalog.ruleChoiceDefsByGlobalName[choice.globalName] = choice; foreach (RuleChoiceDef choice in obj.choices) { if ((int)choice.difficultyIndex == (eclipseMode ? 10 : 2)) { other = choice; break; } } CheckCompatibility(Chainloader.PluginInfos); } private static void CheckCompatibility(Dictionary<string, PluginInfo> info) { PluginInfo value; if (info.ContainsKey("com.bepis.r2api.difficulty")) { SupportAPI(); } else if (info.TryGetValue("com.bepis.r2api", out value) && value.Metadata.Version <= Version.Parse("4.4.1")) { LegacySupport(); } [MethodImpl(MethodImplOptions.NoInlining)] static void LegacySupport() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (DifficultyAPI.Loaded) { DifficultyAPI.difficultyDefinitions[index] = difficulty; } } [MethodImpl(MethodImplOptions.NoInlining)] static void SupportAPI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) DifficultyAPI.difficultyDefinitions[index] = difficulty; } } [HarmonyPatch(typeof(DifficultyCatalog), "GetDifficultyDef")] [HarmonyPrefix] private static bool GetDifficulty(DifficultyIndex difficultyIndex, ref DifficultyDef __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (difficultyIndex == index) { __result = difficulty; return false; } return true; } [HarmonyPatch(typeof(NetworkRuleBook), "OnSerialize")] [HarmonyPatch(typeof(RunReport), "Write")] [HarmonyILManipulator] private static void AdjustRuleBook(ILContext context) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown ILCursor val = new ILCursor(context); MethodInfo method = typeof(NetworkExtensions).GetMethod("Write", new Type[2] { typeof(NetworkWriter), typeof(RuleBook) }); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCall(i, (MethodBase)method) })) { val.EmitDelegate<Func<RuleBook, RuleBook>>((Func<RuleBook, RuleBook>)delegate(RuleBook original) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if (original.FindDifficulty() == index) { RuleBook val2 = new RuleBook(); val2.Copy(original); val2.ApplyChoice(other); return val2; } return original; }); } else { Console.WriteLine("Unable to modify rulebook serialization."); } } [HarmonyPatch(typeof(Run), "OnSerialize")] [HarmonyILManipulator] private static void SendBaseIndex(ILContext context) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown ILCursor val = new ILCursor(context); FieldInfo field = typeof(Run).GetField("selectedDifficultyInternal", AccessTools.all); while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchLdfld(i, field) })) { val.EmitDelegate<Func<DifficultyIndex, DifficultyIndex>>((Func<DifficultyIndex, DifficultyIndex>)((DifficultyIndex value) => (value != index) ? value : other.difficultyIndex)); } if (val.Index == 0) { Console.WriteLine("Unable to map index of difficulty."); } } } } namespace MultitudesDifficulty.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { resourceMan = new ResourceManager("MultitudesDifficulty.Properties.Resources", typeof(Resources).Assembly); } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static byte[] eclipse => (byte[])ResourceManager.GetObject("eclipse", resourceCulture); internal static byte[] icon => (byte[])ResourceManager.GetObject("icon", resourceCulture); internal Resources() { } } }