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 PillarRevive v1.1.2
plugins/PillarRevive.dll
Decompiled 7 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dolso; using HG.Reflection; using MonoMod.Cil; using MonoMod.RuntimeDetour; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PillarRevive")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e0a590a2904280d8ee202d3d354040d1e2002cba")] [assembly: AssemblyProduct("PillarRevive")] [assembly: AssemblyTitle("PillarRevive")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Dolso { internal static class log { private static readonly ManualLogSource logger = Logger.CreateLogSource(Assembly.GetExecutingAssembly().GetName().Name); [Conditional("DEBUG")] internal static void debug(object data) { logger.LogDebug(data); } internal static void info(object data) { logger.LogInfo(data); } internal static void message(object data) { logger.LogMessage(data); } internal static void warning(object data) { logger.LogWarning(data); } internal static void error(object data) { logger.LogError(data); } internal static void fatal(object data) { logger.LogFatal(data); } internal static void LogError(this ILCursor c, object data) { logger.LogError((object)$"ILCursor failure, skipping: {data}\n{c}"); } internal static void LogErrorCaller(this ILCursor c, object data) { logger.LogError((object)$"ILCursor failed in {new StackFrame(1).GetMethod().Name}, skipping: {data}\n{c}"); } } internal static class HookManager { internal delegate bool ConfigEnabled<T>(T configValue); private class HookedConfig<T> { private readonly ConfigEnabled<T> enabled; private readonly IDetour detour; internal HookedConfig(ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, IDetour detour) { this.enabled = enabled; this.detour = detour; if (configEntry != null) { configEntry.SettingChanged += ConfigChanged; ConfigChanged(configEntry, null); } else { detour.Apply(); } } private void ConfigChanged(object sender, EventArgs args) { if (enabled(((ConfigEntry<T>)sender).Value)) { if (!detour.IsApplied) { detour.Apply(); } } else if (detour.IsApplied) { detour.Undo(); } } } internal const BindingFlags allFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly ConfigEnabled<bool> boolConfigEnabled = BoolEnabled; private static ILHookConfig ilHookConfig = new ILHookConfig { ManualApply = true }; private static HookConfig onHookConfig = new HookConfig { ManualApply = true }; internal static void Hook(Type typeFrom, string fromMethod, Manipulator ilHook) { Hook(GetMethod(typeFrom, fromMethod), ilHook); } internal static void Hook(Delegate fromMethod, Manipulator ilHook) { Hook(fromMethod.Method, ilHook); } internal static void Hook(MethodBase fromMethod, Manipulator ilHook) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) try { new ILHook(fromMethod, ilHook, ref ilHookConfig).Apply(); } catch (Exception e) { e.LogHookError(fromMethod, ((Delegate)(object)ilHook).Method); } } internal static void Hook(Type typeFrom, string fromMethod, Delegate onHook) { Hook(GetMethod(typeFrom, fromMethod), onHook.Method, onHook.Target); } internal static void Hook(Delegate fromMethod, Delegate onHook) { Hook(fromMethod.Method, onHook.Method, onHook.Target); } internal static void Hook(MethodBase fromMethod, Delegate onHook) { Hook(fromMethod, onHook.Method, onHook.Target); } internal static void Hook(MethodBase fromMethod, MethodInfo onHook, object target = null) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) try { new Hook(fromMethod, onHook, target, ref onHookConfig).Apply(); } catch (Exception e) { e.LogHookError(fromMethod, onHook); } } internal static void HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string fromMethod, Delegate hook) { configEntry.HookConfig(boolConfigEnabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, Delegate hook) { configEntry.HookConfig(boolConfigEnabled, fromMethod, hook.Method, hook.Target); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, MethodInfo hook) { configEntry.HookConfig(boolConfigEnabled, fromMethod, hook); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string fromMethod, Delegate hook) { configEntry.HookConfig(enabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, Delegate hook) { configEntry.HookConfig(enabled, fromMethod, hook.Method, hook.Target); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, MethodInfo hook, object target = null) { try { new HookedConfig<T>(configEntry, enabled, ManualDetour(fromMethod, hook, target)); } catch (Exception e) { e.LogHookError(fromMethod, hook); } } internal static IDetour ManualDetour(Type typeFrom, string fromMethod, Delegate hook) { return ManualDetour(GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static IDetour ManualDetour(MethodBase fromMethod, Delegate hook) { return ManualDetour(fromMethod, hook.Method, hook.Target); } internal static IDetour ManualDetour(MethodBase fromMethod, MethodInfo hook, object target = null) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown try { ParameterInfo[] parameters = hook.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ILContext)) { return (IDetour)new ILHook(fromMethod, (Manipulator)hook.CreateDelegate(typeof(Manipulator)), ref ilHookConfig); } return (IDetour)new Hook(fromMethod, hook, target, ref onHookConfig); } catch (Exception e) { e.LogHookError(fromMethod, hook); return null; } } internal static MethodInfo GetMethod(Type typeFrom, string methodName) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo[] array = (from a in typeFrom.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where a.Name == methodName select a).ToArray(); switch (array.Length) { case 1: return array[0]; case 0: log.error($"Failed to find method: {typeFrom}::{methodName}"); return null; default: { string text = $"{array.Length} ambiguous matches found for: {typeFrom}::{methodName}, may be incorrect"; MethodInfo[] array2 = array; for (int i = 0; i < array2.Length; i++) { text = text + "\n" + array2[i]; } log.warning(text); return array[0]; } } } internal static MethodInfo GetMethod(Type typeFrom, string methodName, params Type[] parameters) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo? method = typeFrom.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null); if (method == null) { log.error($"Failed to find method: {typeFrom}::{methodName}_{parameters.Length}"); } return method; } internal static void SetPriority(string[] before_il = null, string[] before_on = null, string[] after_il = null, string[] after_on = null) { ilHookConfig.Before = before_il; onHookConfig.Before = before_on; ilHookConfig.After = after_il; onHookConfig.After = after_on; } internal static void LogHookError(this Exception e, MethodBase fromMethod, MethodInfo hook) { log.error((fromMethod == null) ? $"null from-method for hook: {hook.Name}\n{e}" : $"Failed to hook: {fromMethod.DeclaringType}::{fromMethod.Name} - {hook.Name}\n{e}"); } private static bool BoolEnabled(bool configValue) { return configValue; } } internal static class Utilities { internal struct AsyncHandle<T> : IDisposable { private AsyncOperationHandle<T> handle; public T result => handle.Result; public Task<T> task => handle.Task; internal AsyncHandle(AsyncOperationHandle<T> handle) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) this.handle = handle; } public TaskAwaiter<T> GetAwaiter() { return handle.Task.GetAwaiter(); } public void Dispose() { handle.Release(); } public static implicit operator AsyncOperationHandle<T>(AsyncHandle<T> handle) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return handle.handle; } } private static GameObject _prefabParent; internal static GameObject CreatePrefab(GameObject gameObject, string name = null) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)_prefabParent)) { _prefabParent = new GameObject("DolsoPrefabs"); Object.DontDestroyOnLoad((Object)(object)_prefabParent); ((Object)_prefabParent).hideFlags = (HideFlags)61; _prefabParent.SetActive(false); } GameObject val = Object.Instantiate<GameObject>(gameObject, _prefabParent.transform); if (name != null) { ((Object)val).name = name; } return val; } internal static AsyncHandle<T> GetAddressableAsync<T>(string addressable) where T : Object { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new AsyncHandle<T>(Addressables.LoadAssetAsync<T>((object)addressable)); } internal static AsyncHandle<GameObject> GetAddressableAsync(string addressable) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new AsyncHandle<GameObject>(Addressables.LoadAssetAsync<GameObject>((object)addressable)); } internal static void DoAddressable<T>(string addressable, Action<T> callback, bool release = false) where T : Object { //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) AsyncOperationHandle<T> handle = Addressables.LoadAssetAsync<T>((object)addressable); handle.Completed += delegate(AsyncOperationHandle<T> a) { callback(a.Result); if (release) { handle.Release(); } }; } internal static void DoAddressable(string addressable, Action<GameObject> callback, bool release = false) { //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) AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>((object)addressable); handle.Completed += delegate(AsyncOperationHandle<GameObject> a) { callback(a.Result); if (release) { handle.Release(); } }; } internal static void AddressableAddComp<TComp>(string addressable, Action<TComp> callback = null) where TComp : Component { //IL_000e: 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) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { TComp obj = a.Result.AddComponent<TComp>(); callback?.Invoke(obj); }; } internal static void AddressableAddCompSingle<Comp>(string addressable) where Comp : Component { //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) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { if (!Object.op_Implicit((Object)(object)a.Result.GetComponent<Comp>())) { a.Result.AddComponent<Comp>(); } }; } } internal static class RiskofOptions { internal const string RooGuid = "com.rune580.riskofoptions"; internal static bool enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining)] internal static void SetSprite(Sprite sprite) { ModSettingsManager.SetModIcon(sprite); } internal static void SetSpriteDefaultIcon() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) try { string fullName = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).FullName; Texture2D val = new Texture2D(256, 256); if (ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(fullName, "icon.png")))) { ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f))); } else { log.error("Failed to load icon.png"); } } catch (Exception ex) { log.error("Failed to load icon.png\n" + ex); } } internal static void AddOption(ConfigEntryBase entry) { AddOption(entry, string.Empty, string.Empty); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddOption(ConfigEntryBase entry, string categoryName = "", string name = "", bool restartRequired = false) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00ba: 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) //IL_00aa: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) Type settingType = entry.SettingType; object obj; if (!(settingType == typeof(float))) { obj = ((!(settingType == typeof(string))) ? ((!(settingType == typeof(bool))) ? ((!(settingType == typeof(int))) ? ((!(settingType == typeof(Color))) ? ((!(settingType == typeof(KeyboardShortcut))) ? ((object)((!settingType.IsEnum) ? ((ChoiceOption)null) : new ChoiceOption(entry, new ChoiceConfig()))) : ((object)new KeyBindOption((ConfigEntry<KeyboardShortcut>)(object)entry, new KeyBindConfig()))) : ((object)new ColorOption((ConfigEntry<Color>)(object)entry, new ColorOptionConfig()))) : ((object)new IntFieldOption((ConfigEntry<int>)(object)entry, new IntFieldConfig()))) : ((object)new CheckBoxOption((ConfigEntry<bool>)(object)entry, new CheckBoxConfig()))) : ((object)new StringInputFieldOption((ConfigEntry<string>)(object)entry, new InputFieldConfig { submitOn = (SubmitEnum)6, lineType = (LineType)0 }))); } else if (entry.Description.AcceptableValues is AcceptableValueRange<float>) { obj = (object)new SliderOption((ConfigEntry<float>)(object)entry, new SliderConfig { min = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MinValue, max = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MaxValue, FormatString = "{0:f2}", description = entry.DescWithDefault("{0:f2}") }); } else { ConfigEntry<float> obj2 = (ConfigEntry<float>)(object)entry; FloatFieldConfig val = new FloatFieldConfig(); ((NumericFieldConfig<float>)val).FormatString = "{0:f2}"; ((BaseOptionConfig)val).description = entry.DescWithDefault("{0:f2}"); obj = (object)new FloatFieldOption(obj2, val); } BaseOption val2 = (BaseOption)obj; if (val2 == null) { return; } BaseOptionConfig config = val2.GetConfig(); config.category = categoryName; config.name = name; config.restartRequired = restartRequired; if (config.description == "") { config.description = entry.DescWithDefault(); } try { ModSettingsManager.AddOption(val2); } catch (Exception arg) { log.error($"AddOption {entry.Definition} failed\n{arg}"); } } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddOption(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}", string categoryName = "") { //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_000d: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new SliderOption(entry, new SliderConfig { min = min, max = max, FormatString = format, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault(format) })); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddIntSlider(ConfigEntry<int> entry, int min, int max, string categoryName = "") { //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_000d: 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_0031: 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.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig { min = min, max = max, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } private static string DescWithDefault(this ConfigEntryBase entry, string format = "{0}") { return string.Format("{1}\n[Default: " + format + "]", entry.DefaultValue, entry.Description.Description); } } } namespace PillarRevive { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("dolso.pillarrevive", "PillarRevive", "1.1.2")] [DefaultExecutionOrder(1)] public class Main : BaseUnityPlugin { private static readonly Queue<(NetworkUser, float)> event_list = new Queue<(NetworkUser, float)>(0); private void Awake() { PRConfig.DoConfig(((BaseUnityPlugin)this).Config); Prefab.CreatePillarPrefabs(); TeleporterInteraction.onTeleporterChargedGlobal += OnTeleporterChargedGlobal_RevivePlayers; HookManager.Hook(typeof(GlobalEventManager), "OnPlayerCharacterDeath", (Delegate)new Action<Action<GlobalEventManager, DamageReport, NetworkUser>, GlobalEventManager, DamageReport, NetworkUser>(On_GlobalEventManager_OnPlayerDeath)); } private void Update() { if (event_list.Count == 0) { return; } while (event_list.Count > 0) { if (event_list.Peek().Item2 > Time.time) { return; } TrySpawnPillar(event_list.Dequeue().Item1); } event_list.TrimExcess(); } private static void On_GlobalEventManager_OnPlayerDeath(Action<GlobalEventManager, DamageReport, NetworkUser> orig, GlobalEventManager self, DamageReport damagereport, NetworkUser networkuser) { orig(self, damagereport, networkuser); if (PRConfig.enabled.Value) { event_list.Enqueue((networkuser, Time.time + 2.2f)); } } private static void OnTeleporterChargedGlobal_RevivePlayers(TeleporterInteraction obj) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (!PRConfig.onTeleRespawn.Value || !NetworkServer.active) { return; } foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { if (instance.isConnected && instance.master.IsDeadAndOutOfLivesServer()) { CharacterBody val = instance.master.Respawn(instance.master.deathFootPosition, default(Quaternion), false); for (int i = 0; i < PRConfig.curseStacks.Value; i++) { val.AddBuff(Buffs.PermanentCurse); } } } } private static void TrySpawnPillar(NetworkUser networkuser) { if (!Object.op_Implicit((Object)(object)networkuser) || !Object.op_Implicit((Object)(object)networkuser.master) || !networkuser.master.IsDeadAndOutOfLivesServer()) { return; } Run instance = Run.instance; if (instance == null || instance.isGameOverServer || RoR2Application.isInSinglePlayer) { return; } GameObject val = SpawnPillar(networkuser.master); PlayerRevive component = val.GetComponent<PlayerRevive>(); component.SetNetworkUser(networkuser); if (Object.op_Implicit((Object)(object)TeleporterInteraction.instance)) { if (Run.instance.stageClearCount == 0 && TeleporterInteraction.instance.currentState is IdleState) { HoldoutZoneController component2 = val.GetComponent<HoldoutZoneController>(); component2.baseChargeDuration *= PRConfig.earlyGameDivider.Value; CombatDirector component3 = val.GetComponent<CombatDirector>(); component3.monsterCredit *= PRConfig.earlyGameDivider.Value; log.info("Applied early game boost"); } else if (TeleporterInteraction.instance.currentState is ChargedState) { HoldoutZoneController component4 = val.GetComponent<HoldoutZoneController>(); component4.baseChargeDuration *= PRConfig.postTeleDivider.Value; CombatDirector component5 = val.GetComponent<CombatDirector>(); component5.monsterCredit *= PRConfig.postTeleDivider.Value; component.setTeleFinished = true; log.info("Applied post teleporter boost"); } } } private static GameObject SpawnPillar(CharacterMaster master) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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) Vector3 val = (Vector3)(((??)TeleportHelper.FindSafeTeleportDestination(master.deathFootPosition, master.bodyPrefab.GetComponent<CharacterBody>(), RoR2Application.rng)) ?? master.deathFootPosition); GameObject obj = Object.Instantiate<GameObject>(Prefab.pillarSelection.Evaluate(Run.instance.stageRng.nextNormalizedFloat), val, default(Quaternion)); NetworkServer.Spawn(obj); return obj; } } internal class PlayerRevive : MonoBehaviour { private static readonly List<PlayerRevive> instances = new List<PlayerRevive>(); public Pillar pillarIndex; private NetworkUser networkUser; private bool didRespawn; public bool setTeleFinished; public void SetNetworkUser(NetworkUser networkUser) { this.networkUser = networkUser; PurchaseInteraction component = ((Component)this).GetComponent<PurchaseInteraction>(); component.NetworkdisplayNameToken = $"{networkUser.userName}'s {Prefab.pillarNames[(int)pillarIndex]}"; component.NetworkcontextToken = "Reform " + networkUser.userName; if (PRConfig.autoPing.Value) { ((MonoBehaviour)this).Invoke("PingPillar", 3f); } } private void OnEnable() { if (NetworkServer.active) { ((UnityEvent<HoldoutZoneController>)(object)((Component)this).GetComponent<HoldoutZoneController>().onCharged).AddListener((UnityAction<HoldoutZoneController>)OnCharged); instances.Add(this); } } private void OnDisable() { if (NetworkServer.active) { instances.Remove(this); } } private void OnCharged(HoldoutZoneController holdout) { //IL_001f: 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_0034: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_00a7: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)networkUser) || !Object.op_Implicit((Object)(object)networkUser.master)) { Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = "<color=red>Player not found</color>" }); return; } CharacterMaster master = networkUser.master; CharacterBody val = master.Respawn(master.deathFootPosition, default(Quaternion), false); for (int i = 0; i < PRConfig.curseStacks.Value; i++) { val.AddBuff(Buffs.PermanentCurse); } didRespawn = true; Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = "<style=cLunarObjective>Reformed " + networkUser.userName + "</style>" }); ((MonoBehaviour)this).Invoke("DestroySelf", 60f); } private void FixedUpdate() { if (!NetworkServer.active) { return; } bool flag = !Object.op_Implicit((Object)(object)networkUser) || !Object.op_Implicit((Object)(object)networkUser.master); if (!flag) { if (!didRespawn) { CharacterBody currentBody = networkUser.GetCurrentBody(); if (currentBody != null && currentBody.healthComponent.alive) { goto IL_0055; } } if (!setTeleFinished && Object.op_Implicit((Object)(object)TeleporterInteraction.instance) && TeleporterInteraction.instance.currentState is ChargedState) { HoldoutZoneController component = ((Component)this).GetComponent<HoldoutZoneController>(); component.baseChargeDuration *= PRConfig.postTeleDivider.Value; CombatDirector component2 = ((Component)this).GetComponent<CombatDirector>(); component2.monsterCredit *= PRConfig.postTeleDivider.Value; setTeleFinished = true; log.info("Applied post teleporter boost"); } return; } goto IL_0055; IL_0055: if (flag) { log.info("Pillar detected player missing, removing self"); } Object.Destroy((Object)(object)((Component)this).gameObject); } private void PingPillar() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) PingInfo val = default(PingInfo); val.active = true; val.origin = ((Component)this).transform.position; val.normal = Vector3.zero; val.targetNetworkIdentity = ((Component)this).GetComponent<NetworkIdentity>(); PingInfo currentPing = val; LocalUserManager.GetFirstLocalUser().cachedMasterObject.GetComponent<PingerController>().SetCurrentPing(currentPing); } private void DestroySelf() { Object.Destroy((Object)(object)((Component)this).gameObject); } internal static void DestroyAll() { for (int num = instances.Count - 1; num >= 0; num--) { instances[num].DestroySelf(); } } } internal static class PRConfig { internal class PillarConfig { public ConfigEntry<float> weight; public ConfigEntry<float> chargeDuration; public ConfigEntry<float> monsterCredits; private int index; public PillarConfig(int index) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown this.index = index; string text = Prefab.pillarNames[index]; weight = configFile.Bind<float>(text, "Weight", 1f, new ConfigDescription("Spawn weighting of " + text + " Pillar", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); chargeDuration = configFile.Bind<float>(text, "Charge duration", (float)((Pillar)index switch { Pillar.Blood => 10, Pillar.Mass => 60, _ => 30, }), "Charge duration of " + text + " Pillar"); monsterCredits = configFile.Bind<float>(text, "Monster Credits", (float)((index != 3) ? 700 : 0), "How many monsters to spawn on pillar activation"); weight.SettingChanged += delegate { Prefab.pillarSelection.ModifyChoiceWeight(this.index, weight.Value); }; chargeDuration.SettingChanged += delegate { Prefab.pillarSelection.choices[this.index].value.GetComponent<HoldoutZoneController>().baseChargeDuration = chargeDuration.Value; }; monsterCredits.SettingChanged += delegate { Prefab.pillarSelection.choices[this.index].value.GetComponent<CombatDirector>().monsterCredit = monsterCredits.Value; }; } } public static ConfigFile configFile; public static ConfigEntry<bool> enabled; public static ConfigEntry<int> curseStacks; public static ConfigEntry<bool> healingNova; public static ConfigEntry<float> earlyGameDivider; public static ConfigEntry<float> postTeleDivider; public static ConfigEntry<bool> autoPing; public static ConfigEntry<bool> onTeleRespawn; public static PillarConfig[] pillars; public static void DoConfig(ConfigFile bepConfigFile) { configFile = bepConfigFile; enabled = configFile.Bind<bool>("_Main", "Enable Mod", true, "Enables mod. Toggle in-game with pillarrevive_toggle command"); onTeleRespawn = configFile.Bind<bool>("_Main", "On Teleporter Completion Revive", false, "If should automatically revive dead players on teleporter completion"); curseStacks = configFile.Bind<int>("_Main", "Curse Stacks", 25, "Give n stacks of curse to the revived player, set to 0 to disable"); earlyGameDivider = configFile.Bind<float>("_Main", "Early game pillar difficulty", 0.3f, "On stage 1 and teleporter has not been hit, multiply monster credits and charge duration by this number"); postTeleDivider = configFile.Bind<float>("_Main", "Tele finished pillar difficulty", 0.1f, "After teleporter has been fully completed, spawn this many less monsters and charge pillar faster"); autoPing = configFile.Bind<bool>("_Main", "Auto ping pillars", true, "Have host automatically ping pillars when they spawn. This is so that they can be highlighted for everyone"); healingNova = configFile.Bind<bool>("_Main", "Use Lepton Daisy", true, "If revive pillars should use Lepton Daisies"); pillars = new PillarConfig[Prefab.pillarNames.Length]; for (int i = 0; i < pillars.Length; i++) { pillars[i] = new PillarConfig(i); } if (RiskofOptions.enabled) { DoRiskOfOptions(); } enabled.SettingChanged += delegate { if (!enabled.Value) { PlayerRevive.DestroyAll(); } }; healingNova.SettingChanged += delegate { //IL_0011: Unknown result type (might be due to invalid IL or missing references) ChoiceInfo<GameObject>[] choices = Prefab.pillarSelection.choices; for (int j = 0; j < choices.Length; j++) { choices[j].value.GetComponent<HoldoutZoneController>().applyHealingNova = healingNova.Value; } }; } private static void DoRiskOfOptions() { RiskofOptions.SetSpriteDefaultIcon(); RiskofOptions.AddOption((ConfigEntryBase)(object)enabled); RiskofOptions.AddOption((ConfigEntryBase)(object)onTeleRespawn); RiskofOptions.AddIntSlider(curseStacks, 0, 100); RiskofOptions.AddOption(earlyGameDivider, 0f, 1f); RiskofOptions.AddOption(postTeleDivider, 0f, 1f); RiskofOptions.AddOption((ConfigEntryBase)(object)autoPing); RiskofOptions.AddOption((ConfigEntryBase)(object)healingNova); for (int i = 0; i < pillars.Length; i++) { RiskofOptions.AddOption((ConfigEntryBase)(object)pillars[i].monsterCredits); RiskofOptions.AddOption(pillars[i].chargeDuration, 0f, 120f, "{0:0.0}"); RiskofOptions.AddOption(pillars[i].weight, 0f, 10f, "{0:0.0}"); } } [ConCommand(/*Could not decode attribute arguments.*/)] private static void PRPillarConfigReload(ConCommandArgs args) { configFile.Reload(); Debug.Log((object)"Reloaded PillarRevive's config"); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void PRPillarToggle(ConCommandArgs args) { if (enabled.Value) { Debug.Log((object)"Disabled new pillars from spawning"); } else { Debug.Log((object)"Enabled PillarRevive"); } enabled.Value = !enabled.Value; } } public static class Prefab { public static readonly string[] pillarNames = new string[4] { "Blood", "Design", "Mass", "Soul" }; public static WeightedSelection<GameObject> pillarSelection; public static async void CreatePillarPrefabs() { if (pillarSelection == null) { Utilities.AsyncHandle<GameObject>[] pillarTasks = new Utilities.AsyncHandle<GameObject>[pillarNames.Length]; for (int i = 0; i < pillarNames.Length; i++) { pillarTasks[i] = Utilities.GetAddressableAsync("RoR2/Base/moon2/MoonBattery" + pillarNames[i] + ".prefab"); } await Task.WhenAll(pillarTasks.Select((Utilities.AsyncHandle<GameObject> a) => a.task)); pillarSelection = new WeightedSelection<GameObject>(8); for (int j = 0; j < pillarNames.Length; j++) { GameObject val = Utilities.CreatePrefab(pillarTasks[j].result); ((Object)val).name = pillarNames[j] + "Pillar"; val.AddComponent<PlayerRevive>().pillarIndex = (Pillar)j; pillarSelection.AddChoice(val, 1f); pillarTasks[j].Dispose(); } } for (int k = 0; k < pillarSelection.Count; k++) { ModifyPillar(k); } } private static void ModifyPillar(int index) { pillarSelection.ModifyChoiceWeight(index, PRConfig.pillars[index].weight.Value); GameObject value = pillarSelection.choices[index].value; HoldoutZoneController component = value.GetComponent<HoldoutZoneController>(); component.applyHealingNova = PRConfig.healingNova.Value; component.baseChargeDuration = PRConfig.pillars[index].chargeDuration.Value; CombatDirector component2 = value.GetComponent<CombatDirector>(); component2.expRewardCoefficient = 0f; component2.goldRewardCoefficient = 0f; component2.monsterCredit = PRConfig.pillars[index].monsterCredits.Value; } } internal enum Pillar { Blood, Desgin, Mass, Soul } }