Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of HyperMultitudes v1.0.0
R2HyperMultitudes.dll
Decompiled a year agousing System; using System.Collections; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HG.Reflection; using IL.RoR2; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using On.RoR2; using R2API.Utils; using R2HyperMultitudes.MathParser; using RoR2; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("R2HyperMultitudes")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("R2HyperMultitudes")] [assembly: AssemblyTitle("R2HyperMultitudes")] [assembly: AssemblyVersion("1.0.0.0")] namespace R2HyperMultitudes { internal static class Log { private static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } internal static void Debug(object data) { _logSource.LogDebug(data); } internal static void Error(object data) { _logSource.LogError(data); } internal static void Fatal(object data) { _logSource.LogFatal(data); } internal static void Info(object data) { _logSource.LogInfo(data); } internal static void Message(object data) { _logSource.LogMessage(data); } internal static void Warning(object data) { _logSource.LogWarning(data); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Raoul1808.R2HyperMultitudes", "R2HyperMultitudes", "1.0.0")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private delegate int RunInstanceReturnInt(Run self); [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_AdvanceStage <>9__16_0; public static Action<Run> <>9__16_1; public static Func<Instruction, bool> <>9__16_5; public static Func<int, int> <>9__16_6; public static Manipulator <>9__16_2; public static Func<Instruction, bool> <>9__16_7; public static Func<int, int> <>9__16_8; public static Manipulator <>9__16_3; internal void <Awake>b__16_0(orig_AdvanceStage orig, Run self, SceneDef nextScene) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 orig.Invoke(self, nextScene); if (_hypermultitudesEnabled.Value && (int)nextScene.sceneType == 1) { StageIndex++; } } internal void <Awake>b__16_1(Run run) { Log.Info("Resetting HyperMultitudes Multiplier"); StageIndex = 1; } internal void <Awake>b__16_2(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<Run>(i, "get_livingPlayerCount") })) { val.EmitDelegate<Func<int, int>>((Func<int, int>)((int livingPlayerCount) => _origLivingPlayerCountValue)); } } internal bool <Awake>b__16_5(Instruction i) { return ILPatternMatchingExt.MatchCallOrCallvirt<Run>(i, "get_livingPlayerCount"); } internal int <Awake>b__16_6(int livingPlayerCount) { return _origLivingPlayerCountValue; } internal void <Awake>b__16_3(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<Run>(i, "get_livingPlayerCount") })) { val.EmitDelegate<Func<int, int>>((Func<int, int>)((int livingPlayerCount) => _origLivingPlayerCountValue)); } } internal bool <Awake>b__16_7(Instruction i) { return ILPatternMatchingExt.MatchCallOrCallvirt<Run>(i, "get_livingPlayerCount"); } internal int <Awake>b__16_8(int livingPlayerCount) { return _origLivingPlayerCountValue; } } public const string Guid = "Raoul1808.R2HyperMultitudes"; public const string Author = "Raoul1808"; public const string Name = "R2HyperMultitudes"; public const string Version = "1.0.0"; private static ConfigEntry<string> _scalingExpression; private static ConfigEntry<bool> _hypermultitudesEnabled; public static Node MultitudesExpression; public static readonly ModStageContext StageContext = new ModStageContext(); private static int _stageIndex; private static RunInstanceReturnInt _origLivingPlayerCount; private static RunInstanceReturnInt _origParticipatingPlayerCount; private static int _origLivingPlayerCountValue; private static int _origParticipatingPlayerCountValue; public static double MultitudesMultiplier { get; private set; } public static int StageIndex { get { return _stageIndex; } set { _stageIndex = value; StageContext.Stage = _stageIndex; MultitudesMultiplier = Math.Max(MultitudesExpression.Eval(StageContext), 1.0); string text = "HyperMultitudes Multiplier = " + MultitudesMultiplier; Debug.Log((object)text); Log.Info(text); } } private void Awake() { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown Log.Init(((BaseUnityPlugin)this).Logger); _hypermultitudesEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("HyperMultitudes", "Enabled", true, "Whether HyperMultitudes should be enabled or not"); _scalingExpression = ((BaseUnityPlugin)this).Config.Bind<string>("HyperMultitudes", "MultiplierExpression", "2 * stage", "A mathematical expression which is calculated on every stage to determine the new multitudes multiplier to apply. Supports additions (+), subtractions (-), multiplications (*), divisions (/), parentheses and exponents (^)"); Log.Info("Loading expression: " + _scalingExpression.Value); MultitudesExpression = new ExpressionParser(_scalingExpression.Value).Parse(); MultitudesExpression.Eval(StageContext); Log.Info("Testing expression"); for (int j = 1; j < 10; j++) { StageIndex = j; } Log.Info("Test ended"); StageIndex = 1; object obj = <>c.<>9__16_0; if (obj == null) { hook_AdvanceStage val = delegate(orig_AdvanceStage orig, Run self, SceneDef nextScene) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 orig.Invoke(self, nextScene); if (_hypermultitudesEnabled.Value && (int)nextScene.sceneType == 1) { StageIndex++; } }; <>c.<>9__16_0 = val; obj = (object)val; } Run.AdvanceStage += (hook_AdvanceStage)obj; Run.onRunStartGlobal += delegate { Log.Info("Resetting HyperMultitudes Multiplier"); StageIndex = 1; }; _origLivingPlayerCount = new Hook((MethodBase)Reflection.GetMethodCached(typeof(Run), "get_livingPlayerCount"), Reflection.GetMethodCached(typeof(Plugin), "GetLivingPlayerCountHook")).GenerateTrampoline<RunInstanceReturnInt>(); _origParticipatingPlayerCount = new Hook((MethodBase)Reflection.GetMethodCached(typeof(Run), "get_participatingPlayerCount"), Reflection.GetMethodCached(typeof(Plugin), "GetParticipatingPlayerCountHook")).GenerateTrampoline<RunInstanceReturnInt>(); object obj2 = <>c.<>9__16_2; if (obj2 == null) { Manipulator val2 = delegate(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val5 = new ILCursor(il); if (val5.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<Run>(i, "get_livingPlayerCount") })) { val5.EmitDelegate<Func<int, int>>((Func<int, int>)((int livingPlayerCount) => _origLivingPlayerCountValue)); } }; <>c.<>9__16_2 = val2; obj2 = (object)val2; } AllPlayersTrigger.FixedUpdate += (Manipulator)obj2; object obj3 = <>c.<>9__16_3; if (obj3 == null) { Manipulator val3 = delegate(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val4 = new ILCursor(il); if (val4.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<Run>(i, "get_livingPlayerCount") })) { val4.EmitDelegate<Func<int, int>>((Func<int, int>)((int livingPlayerCount) => _origLivingPlayerCountValue)); } }; <>c.<>9__16_3 = val3; obj3 = (object)val3; } MultiBodyTrigger.FixedUpdate += (Manipulator)obj3; Stage.onStageStartGlobal += delegate { if (_hypermultitudesEnabled.Value) { ((MonoBehaviour)this).StartCoroutine(SendChatScalingDelayed()); } }; } private IEnumerator SendChatScalingDelayed() { yield return (object)new WaitForSeconds(2f); SendChatScaling(); } private static void SendChatScaling() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown if (NetworkServer.active) { SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "HyperMultitudes Multiplier now at: {0}"; val.paramTokens = new string[1] { MultitudesMultiplier.ToString(CultureInfo.InvariantCulture) }; Chat.SendBroadcastChat((ChatMessageBase)(object)val); } } private static void SendChatExpression() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown if (NetworkServer.active) { SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "HyperMultitudes Expression set to: {0}"; val.paramTokens = new string[1] { _scalingExpression.Value }; Chat.SendBroadcastChat((ChatMessageBase)(object)val); } } private static int GetLivingPlayerCountHook(Run self) { _origLivingPlayerCountValue = _origLivingPlayerCount(self); return (int)((double)_origLivingPlayerCountValue * MultitudesMultiplier); } private static int GetParticipatingPlayerCountHook(Run self) { _origParticipatingPlayerCountValue = _origParticipatingPlayerCount(self); return (int)((double)_origParticipatingPlayerCountValue * MultitudesMultiplier); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CCEnable(ConCommandArgs args) { if (((ConCommandArgs)(ref args)).Count != 0) { Debug.LogError((object)"Invalid arguments. Did you mean mod_hm_set_expression or mod_hm_test_expression?"); return; } if (_hypermultitudesEnabled.Value) { Debug.LogWarning((object)"HyperMultitudes is already enabled."); return; } _hypermultitudesEnabled.Value = true; Debug.Log((object)"HyperMultitudes enabled. Good luck"); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CCDisable(ConCommandArgs args) { if (((ConCommandArgs)(ref args)).Count != 0) { Debug.LogError((object)"Invalid arguments. Did you mean mod_hm_set_expression or mod_hm_test_expression?"); return; } if (!_hypermultitudesEnabled.Value) { Debug.LogWarning((object)"HyperMultitudes is already disabled."); return; } _hypermultitudesEnabled.Value = false; Debug.Log((object)"HyperMultitudes disabled."); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CCSetExpression(ConCommandArgs args) { ((ConCommandArgs)(ref args)).CheckArgumentCount(1); try { string text = ((ConCommandArgs)(ref args))[0]; Node node = new ExpressionParser(text).Parse(); ModStageContext modStageContext = new ModStageContext { Stage = 1.0 }; node.Eval(new ModStageContext { Stage = 1.0 }); MultitudesExpression = node; _scalingExpression.Value = text; Debug.Log((object)("New HyperMultitudes expression set to: " + text)); Debug.Log((object)"Testing new expression..."); for (int i = 1; i <= 10; i++) { modStageContext.Stage = i; double num = node.Eval(modStageContext); Debug.Log((object)$"Stage = {i}, Result = {num}"); } Debug.Log((object)"Testing done. If these results don't look right to you, double-check your expression and make sure it is properly wrapped between quotation marks (e.g: \"2 * stage\")"); SendChatExpression(); } catch (Exception arg) { Debug.LogError((object)"Invalid expression given. Make sure the expression is put in quotes! (e.g: \"2 * stage\")"); Debug.LogError((object)"Check the logs for (potentially) more details"); Log.Error($"Caught exception when setting new expression: {arg}"); } } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CCGetExpression(ConCommandArgs args) { Debug.LogWarning((object)((((ConCommandArgs)(ref args)).Count == 0) ? ("Current Expression: " + _scalingExpression.Value) : "Invalid arguments. Did you mean mod_hm_set_expression or mod_hm_test_expression?")); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CCTestExpression(ConCommandArgs args) { ((ConCommandArgs)(ref args)).CheckArgumentCount(1); if (double.TryParse(((ConCommandArgs)(ref args))[0], out var result)) { try { double num = new ExpressionParser(_scalingExpression.Value).Parse().Eval(new ModStageContext { Stage = result }); Debug.Log((object)$"Result = {num}"); return; } catch (Exception arg) { Log.Error($"Caught exception when testing existing expression: {arg}"); return; } } Debug.LogError((object)"Invalid Argument. Correct usage is `mod_hm_test_expression <number>`"); } } public class ModStageContext : IContext { public double Stage { get; set; } public double ResolveVariable(string name) { if (name.ToLower() == "stage" || name.ToLower() == "x") { return Stage; } throw new InvalidDataException("Unknown variable: " + name); } } } namespace R2HyperMultitudes.MathParser { public class ExpressionParser { private Tokenizer _tokenizer; public ExpressionParser(string expression) { _tokenizer = new Tokenizer(new StringReader(expression)); } public Node Parse() { Node result = ParseAddSubtract(); if (_tokenizer.Token != 0) { throw new InvalidDataException("Unexpected characters at end of expression"); } return result; } private Node ParseAddSubtract() { Node node = ParseMultiplyDivide(); while (true) { Func<double, double, double> func = null; switch (_tokenizer.Token) { case Token.Add: func = (double a, double b) => a + b; break; case Token.Subtract: func = (double a, double b) => a - b; break; } if (func == null) { break; } _tokenizer.NextToken(); Node rhs = ParseMultiplyDivide(); node = new NodeBinary(node, rhs, func); } return node; } private Node ParseMultiplyDivide() { Node node = ParseUnary(); while (true) { Func<double, double, double> func = null; switch (_tokenizer.Token) { case Token.Multiply: func = (double a, double b) => a * b; break; case Token.Divide: func = (double a, double b) => a / b; break; } if (func == null) { break; } _tokenizer.NextToken(); Node rhs = ParseUnary(); node = new NodeBinary(node, rhs, func); } return node; } private Node ParseUnary() { if (_tokenizer.Token == Token.Add) { _tokenizer.NextToken(); return ParseUnary(); } if (_tokenizer.Token == Token.Subtract) { _tokenizer.NextToken(); return new NodeUnary(ParseUnary(), (double a) => 0.0 - a); } return ParsePow(); } private Node ParsePow() { Node node = ParseLeaf(); if (_tokenizer.Token == Token.Pow) { _tokenizer.NextToken(); Node rhs = ParseLeaf(); node = new NodeBinary(node, rhs, Math.Pow); } return node; } private Node ParseLeaf() { if (_tokenizer.Token == Token.Variable) { NodeVariable result = new NodeVariable(_tokenizer.Variable); _tokenizer.NextToken(); return result; } if (_tokenizer.Token == Token.Number) { NodeNumber result2 = new NodeNumber(_tokenizer.Number); _tokenizer.NextToken(); return result2; } if (_tokenizer.Token == Token.OpenParens) { _tokenizer.NextToken(); Node result3 = ParseAddSubtract(); if (_tokenizer.Token != Token.CloseParens) { throw new InvalidDataException("Missing close parenthesis"); } _tokenizer.NextToken(); return result3; } throw new InvalidDataException($"Unexpected token: {_tokenizer.Token}"); } } public interface IContext { double ResolveVariable(string name); } public abstract class Node { public abstract double Eval(IContext ctx); } public class NodeNumber : Node { private double _number; public NodeNumber(double number) { _number = number; } public override double Eval(IContext ctx) { return _number; } } public class NodeBinary : Node { private Node _lhs; private Node _rhs; private Func<double, double, double> _op; public NodeBinary(Node lhs, Node rhs, Func<double, double, double> op) { _lhs = lhs; _rhs = rhs; _op = op; } public override double Eval(IContext ctx) { return _op(_lhs.Eval(ctx), _rhs.Eval(ctx)); } } public class NodeUnary : Node { private Node _rhs; private Func<double, double> _op; public NodeUnary(Node rhs, Func<double, double> op) { _rhs = rhs; _op = op; } public override double Eval(IContext ctx) { return _op(_rhs.Eval(ctx)); } } public class NodeVariable : Node { private string _variableName; public NodeVariable(string variable) { _variableName = variable; } public override double Eval(IContext ctx) { return ctx.ResolveVariable(_variableName); } } public enum Token { None, Number, Add, Subtract, Multiply, Divide, Pow, OpenParens, CloseParens, Variable } public class Tokenizer { private StringReader _reader; private char _currentChar; public double Number { get; private set; } public string Variable { get; private set; } public Token Token { get; private set; } public Tokenizer(StringReader reader) { _reader = reader; NextChar(); NextToken(); } private void NextChar() { int num = _reader.Read(); _currentChar = ((num >= 0) ? ((char)num) : '\0'); } public void NextToken() { while (char.IsWhiteSpace(_currentChar)) { NextChar(); } switch (_currentChar) { case '\0': Token = Token.None; return; case '+': NextChar(); Token = Token.Add; return; case '-': NextChar(); Token = Token.Subtract; return; case '*': NextChar(); Token = Token.Multiply; return; case '/': NextChar(); Token = Token.Divide; return; case '(': NextChar(); Token = Token.OpenParens; return; case ')': NextChar(); Token = Token.CloseParens; return; case '^': NextChar(); Token = Token.Pow; return; } if (char.IsLetter(_currentChar) || _currentChar == '_') { StringBuilder stringBuilder = new StringBuilder(); while (char.IsLetterOrDigit(_currentChar) || _currentChar == '_') { stringBuilder.Append(_currentChar); NextChar(); } Variable = stringBuilder.ToString(); Token = Token.Variable; return; } if (char.IsDigit(_currentChar) || _currentChar == '.') { StringBuilder stringBuilder2 = new StringBuilder(); bool flag = false; while (char.IsDigit(_currentChar) || (!flag && _currentChar == '.')) { stringBuilder2.Append(_currentChar); flag = flag || _currentChar == '.'; NextChar(); } Number = double.Parse(stringBuilder2.ToString(), CultureInfo.InvariantCulture); Token = Token.Number; return; } throw new InvalidDataException($"Unexpected character: {_currentChar}"); } } }