Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of SacrificeChanges v1.0.2
plugins/SacrificeChanges.dll
Decompiled a week agousing System; 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 BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dolso; using HG.Reflection; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Artifacts; using TMPro; using UnityEngine; using UnityEngine.Networking; [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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.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 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 SacrificeChanges { [BepInPlugin("dolso.sacrificechanges", "SacrificeChanges", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Sacrifice : BaseUnityPlugin { private static ConfigEntry<bool> timeless_disable; private static ConfigEntry<bool> drop_rework_enabled; private static ConfigEntry<float> drop_multiplier; private static ConfigEntry<float> drop_variance; private static ConfigEntry<bool> log_dropchance; private static float stored_chance; private void Awake() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown DoConfig(); Run.onRunStartGlobal += delegate { stored_chance = 0f + Random.Range(0f - drop_variance.Value, drop_variance.Value); if (drop_rework_enabled.Value && log_dropchance.Value) { log.message("Initial pool = " + stored_chance); } }; HookManager.Hook(typeof(SacrificeArtifactManager), "OnServerCharacterDeath", new Manipulator(Modify_IL_SacrificeArtifactManager_OnServerCharacterDeath)); } private static void Modify_IL_SacrificeArtifactManager_OnServerCharacterDeath(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002e: 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_0089: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.EmitDelegate<Func<bool>>((Func<bool>)(() => !timeless_disable.Value || (int)SceneCatalog.mostRecentSceneDef.sceneType != 2)); val.Emit(OpCodes.Brtrue, val.Next); val.Emit(OpCodes.Ret); if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCall(a, typeof(Util), "GetExpAdjustedDropChancePercent") })) { val.LogErrorCaller("drop rework percent"); return; } val.Emit<Sacrifice>(OpCodes.Ldsfld, "drop_rework_enabled"); val.Emit<ConfigEntry<bool>>(OpCodes.Call, "get_Value"); val.Emit(OpCodes.Brfalse, val.Next); val.EmitDelegate<Func<float, bool>>((Func<float, bool>)delegate(float drop_chance) { stored_chance += drop_chance * drop_multiplier.Value; if (log_dropchance.Value) { log.info("Stored drop chance: " + stored_chance.ToString("0")); } if (stored_chance < 100f) { return false; } stored_chance -= 100f + Random.Range(0f - drop_variance.Value, drop_variance.Value); if (log_dropchance.Value) { log.message("Pool reset to: " + stored_chance.ToString("0")); } return true; }); ILLabel val2 = val.DefineLabel(); val.Emit(OpCodes.Br, (object)val2); if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCall(a, typeof(Util), "CheckRoll") })) { val.LogErrorCaller("drop rework roll"); } else { val.MarkLabel(val2); } } private static void DoConfig() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown ConfigFile val = new ConfigFile(Paths.ConfigPath + "//SacrificeChanges.cfg", true); timeless_disable = val.Bind<bool>("Sacrifice", "Timeless drop toggle", true, "If timeless areas such as Bulwark's Ambry and Gilded Coast should have sacrifice drops disable"); drop_rework_enabled = val.Bind<bool>("Sacrifice", "Drop Rework toggle", true, "If drop rework should be enabled"); drop_multiplier = val.Bind<float>("Sacrifice", "Drop Chance Multiplier", 1f, "Drop chance multiplier"); drop_variance = val.Bind<float>("Sacrifice", "Drop pool reset variance", 20f, new ConfigDescription("When pool reaches 100%, substract -100 +-reset_variance", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); log_dropchance = val.Bind<bool>("Sacrifice", "Log drop progress", false, "If should log drop chance growth and resets"); if (RiskofOptions.enabled) { DoRoO(); } } private static void DoRoO() { RiskofOptions.SetSpriteDefaultIcon(); RiskofOptions.AddOption((ConfigEntryBase)(object)timeless_disable); RiskofOptions.AddOption((ConfigEntryBase)(object)drop_rework_enabled); RiskofOptions.AddOption((ConfigEntryBase)(object)drop_multiplier); RiskofOptions.AddOption((ConfigEntryBase)(object)drop_variance); RiskofOptions.AddOption((ConfigEntryBase)(object)log_dropchance); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CcVariance(ConCommandArgs args) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)args.sender).isLocalPlayer) { Debug.LogWarning((object)"Only Host may change this value"); return; } if (((ConCommandArgs)(ref args)).Count == 0) { Debug.Log((object)("Reset Variance = " + drop_variance.Value)); return; } if (!float.TryParse(((ConCommandArgs)(ref args))[0], out var result)) { Debug.LogWarning((object)("Could not parse: " + ((ConCommandArgs)(ref args))[0])); return; } if (result < 0f || result > 100f) { Debug.LogWarning((object)"Number must be between 0 and 100"); return; } drop_variance.Value = result; Debug.Log((object)("Set reset variance to: " + drop_variance.Value)); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CcMultipler(ConCommandArgs args) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)args.sender).isLocalPlayer) { Debug.LogWarning((object)"Only Host may change this value"); return; } if (((ConCommandArgs)(ref args)).Count == 0) { Debug.Log((object)("Drop Multiplier = " + drop_multiplier.Value)); return; } if (!float.TryParse(((ConCommandArgs)(ref args))[0], out var result)) { Debug.LogWarning((object)("Could not parse: " + ((ConCommandArgs)(ref args))[0])); return; } drop_multiplier.Value = result; Debug.Log((object)("Set drop chance multiplier to: " + drop_multiplier.Value)); } } }