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 VenganceSwarmRedux v1.0.0
VenganceSwarmRedux.dll
Decompiled 13 hours agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using On.RoR2; using On.RoR2.Artifacts; using RiskOfOptions; using RiskOfOptions.Options; using RoR2; using RoR2.Artifacts; using RoR2.ContentManagement; using UnityEngine; using UnityEngine.Networking; [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("VenganceSwarmRedux")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+5386fc89406137ecc94121205261f577ee3b131d")] [assembly: AssemblyProduct("VenganceSwarmRedux")] [assembly: AssemblyTitle("VenganceSwarmRedux")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 VengeanceSwarmRedux { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.FortressForce.VengeanceSwarmRedux", "VengeanceSwarmRedux", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "com.FortressForce.VengeanceSwarmRedux"; public const string PluginName = "VengeanceSwarmRedux"; public const string PluginVersion = "1.0.0"; private static readonly FieldInfo FieldSrcItemStacks = typeof(MasterCopySpawnCard).GetField("srcItemStacks", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldSrcTempItemRawValues = typeof(MasterCopySpawnCard).GetField("srcTempItemRawValues", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldSrcEquipment = typeof(MasterCopySpawnCard).GetField("srcEquipment", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldOnPreSpawnSetup = typeof(MasterCopySpawnCard).GetField("onPreSpawnSetup", BindingFlags.Instance | BindingFlags.NonPublic); private static int _lastInvasionCycleDropped = -1; public static ManualLogSource InstanceLogger { get; private set; } = null; public static Plugin Instance { get; private set; } = null; public static ConfigEntry<bool> IsEnabled { get; private set; } = null; public static ConfigEntry<bool> AllowBothDrops { get; private set; } = null; public static ConfigEntry<bool> EnableHighPopFix { get; private set; } = null; public static ConfigEntry<bool> EnableDebugLogging { get; private set; } = null; public void Awake() { Instance = this; InstanceLogger = ((BaseUnityPlugin)this).Logger; InitConfig(); RiskOfOptionsIntegration.Init(IsEnabled, AllowBothDrops, EnableHighPopFix, EnableDebugLogging); RegisterHooks(); InstanceLogger.LogInfo((object)"VengeanceSwarmRedux v1.0.0 initialized successfully."); } private void InitConfig() { IsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Enabled", true, "Enables or disables the mod entirely."); AllowBothDrops = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Gameplay", "Allow Both Swarm Drops", true, "If true, both Doppelgangers spawned under Artifact of Swarms will drop an item when defeated. If false, only one drop is awarded per invasion wave."); EnableHighPopFix = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Gameplay", "High Population Fix", true, "Ensures Swarms Doppelganger clones ignore team member limits so they always spawn even when the map has high enemy population."); EnableDebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Debug", "Enable Debug Logging", false, "Enables detailed console logging for spawn events, item copies, and skin applications."); } private void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown MasterCopySpawnCard.GetPreSpawnSetupCallback += new hook_GetPreSpawnSetupCallback(OnMasterCopySpawnCardGetPreSpawnSetupCallback); SwarmsArtifactManager.OnSpawnCardOnSpawnedServerGlobal += new hook_OnSpawnCardOnSpawnedServerGlobal(OnSwarmsArtifactManagerOnSpawnCardOnSpawnedServerGlobal); CharacterBody.SetLoadoutServer += new hook_SetLoadoutServer(OnCharacterBodySetLoadoutServer); CharacterBody.UpdateMasterLink += new hook_UpdateMasterLink(OnCharacterBodyUpdateMasterLink); ModelSkinController.Start += new hook_Start(OnModelSkinControllerStart); CharacterMaster.OnDeserialize += new hook_OnDeserialize(OnCharacterMasterOnDeserialize); DoppelgangerInvasionManager.OnCharacterDeathGlobal += new hook_OnCharacterDeathGlobal(OnDoppelgangerDeathGlobal); } private Action<CharacterMaster> OnMasterCopySpawnCardGetPreSpawnSetupCallback(orig_GetPreSpawnSetupCallback orig, MasterCopySpawnCard self) { if (!IsEnabled.Value) { return orig.Invoke(self); } return delegate(CharacterMaster spawnedMaster) { if (!Object.op_Implicit((Object)(object)spawnedMaster) || !Object.op_Implicit((Object)(object)spawnedMaster.inventory)) { return; } try { if (FieldSrcItemStacks?.GetValue(self) is int[] array) { spawnedMaster.inventory.AddItemsFrom(array, (Func<ItemIndex, bool>)((ItemIndex _) => true)); } if (FieldSrcTempItemRawValues?.GetValue(self) is float[] array2) { for (int num = 0; num < array2.Length; num++) { if (array2[num] > 0f) { spawnedMaster.inventory.GiveItemTemp((ItemIndex)num, array2[num]); } } } if (FieldSrcEquipment?.GetValue(self) is EquipmentIndex[][] array3) { for (uint num2 = 0u; num2 < array3.Length; num2++) { if (array3[num2] != null) { for (uint num3 = 0u; num3 < array3[num2].Length; num3++) { spawnedMaster.inventory.SetEquipmentIndexForSlot(array3[num2][num3], num2, num3); } } } } if (self is DoppelgangerSpawnCard && spawnedMaster.inventory.GetItemCountEffective(Items.InvadingDoppelganger) == 0) { spawnedMaster.inventory.GiveItemPermanent(Items.InvadingDoppelganger, 1); } (FieldOnPreSpawnSetup?.GetValue(self) as Action<CharacterMaster>)?.Invoke(spawnedMaster); if (EnableDebugLogging.Value) { InstanceLogger.LogInfo((object)("[ItemSync] Successfully applied inventory snapshot to spawned master: " + ((Object)spawnedMaster).name)); } } catch (Exception arg) { InstanceLogger.LogError((object)$"[ItemSync] Error in pre-spawn setup callback: {arg}"); } }; } private void OnSwarmsArtifactManagerOnSpawnCardOnSpawnedServerGlobal(orig_OnSpawnCardOnSpawnedServerGlobal orig, SpawnResult result) { //IL_009b: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_0042: Unknown result type (might be due to invalid IL or missing references) if (IsEnabled.Value && EnableHighPopFix.Value && result.spawnRequest != null) { if (result.spawnRequest.spawnCard is DoppelgangerSpawnCard) { goto IL_008e; } if (Object.op_Implicit((Object)(object)result.spawnedInstance)) { CharacterMaster component = result.spawnedInstance.GetComponent<CharacterMaster>(); if (component != null) { Inventory inventory = component.inventory; if (((inventory != null) ? new int?(inventory.GetItemCountEffective(Items.InvadingDoppelganger)) : ((int?)null)) > 0) { goto IL_008e; } } } } goto IL_009a; IL_009a: orig.Invoke(result); return; IL_008e: result.spawnRequest.ignoreTeamMemberLimit = true; goto IL_009a; } private void OnCharacterBodySetLoadoutServer(orig_SetLoadoutServer orig, CharacterBody self, Loadout loadout) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, loadout); if (!IsEnabled.Value || !Object.op_Implicit((Object)(object)self) || loadout == null) { return; } try { uint num = (self.skinIndex = loadout.bodyLoadoutManager.GetSkinIndex(self.bodyIndex)); if (EnableDebugLogging.Value) { InstanceLogger.LogInfo((object)$"[SkinSync] SetLoadoutServer: Body {((Object)self).name} assigned skinIndex {num}"); } } catch (Exception arg) { InstanceLogger.LogError((object)$"[SkinSync] Error in SetLoadoutServer hook: {arg}"); } } private void OnCharacterBodyUpdateMasterLink(orig_UpdateMasterLink orig, CharacterBody self) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); if (!IsEnabled.Value || !Object.op_Implicit((Object)(object)self) || !Object.op_Implicit((Object)(object)self.master) || self.master.loadout == null) { return; } try { uint skinIndex = self.master.loadout.bodyLoadoutManager.GetSkinIndex(self.bodyIndex); ApplySkinToBody(self, skinIndex); } catch (Exception arg) { InstanceLogger.LogError((object)$"[SkinSync] Error in UpdateMasterLink hook: {arg}"); } } private void OnModelSkinControllerStart(orig_Start orig, ModelSkinController self) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (IsEnabled.Value && Object.op_Implicit((Object)(object)self)) { try { CharacterModel component = ((Component)self).GetComponent<CharacterModel>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.body) && Object.op_Implicit((Object)(object)component.body.master) && component.body.master.loadout != null) { uint skinIndex = component.body.master.loadout.bodyLoadoutManager.GetSkinIndex(component.body.bodyIndex); if (skinIndex != 0) { component.body.skinIndex = skinIndex; } } } catch (Exception arg) { InstanceLogger.LogError((object)$"[SkinSync] Error in ModelSkinController.Start hook: {arg}"); } } orig.Invoke(self); } private void OnCharacterMasterOnDeserialize(orig_OnDeserialize orig, CharacterMaster self, NetworkReader reader, bool initialState) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, reader, initialState); if (!IsEnabled.Value || !Object.op_Implicit((Object)(object)self) || NetworkServer.active || self.loadout == null) { return; } try { CharacterBody body = self.GetBody(); if (Object.op_Implicit((Object)(object)body)) { uint skinIndex = self.loadout.bodyLoadoutManager.GetSkinIndex(body.bodyIndex); ApplySkinToBody(body, skinIndex); } } catch (Exception arg) { InstanceLogger.LogError((object)$"[SkinSync] Error in CharacterMaster.OnDeserialize hook: {arg}"); } } private static void ApplySkinToBody(CharacterBody body, uint skinIndex) { if (!Object.op_Implicit((Object)(object)body)) { return; } body.skinIndex = skinIndex; if (!Object.op_Implicit((Object)(object)body.modelLocator) || !Object.op_Implicit((Object)(object)body.modelLocator.modelTransform)) { return; } ModelSkinController component = ((Component)body.modelLocator.modelTransform).GetComponent<ModelSkinController>(); if (Object.op_Implicit((Object)(object)component) && component.skins != null && skinIndex < (uint)component.skins.Length && component.currentSkinIndex != (int)skinIndex) { if (EnableDebugLogging.Value) { InstanceLogger.LogInfo((object)$"[SkinSync] Applying skinIndex {skinIndex} to ModelSkinController on body {((Object)body).name}"); } ((MonoBehaviour)component).StartCoroutine(component.ApplySkinAsync((int)skinIndex, (AsyncReferenceHandleUnloadType)2)); } } private void OnDoppelgangerDeathGlobal(orig_OnCharacterDeathGlobal orig, DoppelgangerInvasionManager self, DamageReport damageReport) { if (!IsEnabled.Value || AllowBothDrops.Value || !Object.op_Implicit((Object)(object)self)) { orig.Invoke(self, damageReport); return; } int num = -1; try { MethodInfo method = typeof(DoppelgangerInvasionManager).GetMethod("GetCurrentInvasionCycle", BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { num = (int)method.Invoke(self, null); } } catch { num = (Object.op_Implicit((Object)(object)Run.instance) ? Mathf.FloorToInt(Run.instance.GetRunStopwatch() / 600f) : (-1)); } if (_lastInvasionCycleDropped == num && num != -1) { if (EnableDebugLogging.Value) { InstanceLogger.LogInfo((object)$"[LootDrop] Suppressing second swarm doppelganger drop for cycle {num} (AllowBothDrops is disabled)."); } } else { _lastInvasionCycleDropped = num; orig.Invoke(self, damageReport); } } } public static class RiskOfOptionsIntegration { public const string GUID = "com.rune580.riskofoptions"; public static bool IsLoaded => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); public static void Init(ConfigEntry<bool> isEnabled, ConfigEntry<bool> allowBothDrops, ConfigEntry<bool> enableHighPopFix, ConfigEntry<bool> enableDebugLogging) { if (!IsLoaded) { return; } try { InitInternal(isEnabled, allowBothDrops, enableHighPopFix, enableDebugLogging); } catch (Exception ex) { ManualLogSource instanceLogger = Plugin.InstanceLogger; if (instanceLogger != null) { instanceLogger.LogWarning((object)("RiskOfOptions integration failed to initialize: " + ex.Message)); } } } [MethodImpl(MethodImplOptions.NoInlining)] private static void InitInternal(ConfigEntry<bool> isEnabled, ConfigEntry<bool> allowBothDrops, ConfigEntry<bool> enableHighPopFix, ConfigEntry<bool> enableDebugLogging) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown ModSettingsManager.SetModDescription("Fixes Doppelgangers (Umbras) skin synchronization and item/drop distribution when using Artifact of Vengeance and Artifact of Swarms."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(isEnabled)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(allowBothDrops)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(enableHighPopFix)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(enableDebugLogging)); } } }