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 HyperMultitudes v1.0.0
R2HyperMultitudes.dll
Decompiled 2 years 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}"); } } }