using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BOMBANANA.Library.Game;
using BOMBANANA.Library.Reflection;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Microsoft.CodeAnalysis;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BombananaEndlessEasy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+bf9eb965b2715eabe915f08d9a4d4ec309238ae2")]
[assembly: AssemblyProduct("BombananaEndlessEasy")]
[assembly: AssemblyTitle("BombananaEndlessEasy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BombananaEndlessEasy
{
internal static class EndlessTuner
{
private const int MissClearEveryNPolls = 20;
private static readonly string[] ConfigTypeNames = new string[2] { "EndlessModeConfig", "BombGame.EndlessModeConfig" };
private static readonly string[] InstanceMemberNames = new string[2] { "Instance", "cached" };
private static int _missClears;
private static bool? _lastConfigPresent;
private static bool _baselinesCaptured;
private static uint _baseStartTimeSeconds;
private static ushort _baseStrikesPerWave;
private static int _baseEasyTimeBonus;
private static int _baseMediumTimeBonus;
private static int _baseHardTimeBonus;
internal static void Poll()
{
if (Plugin.Enabled.Value)
{
RefObj val = ResolveConfig();
ReportConfigState(val != null);
if (val != null && (!Plugin.OnlyApplyAsHost.Value || NetworkApi.IsServer || NetworkApi.IsHost))
{
Apply(val);
}
}
}
private static void ReportConfigState(bool present)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
if (!_lastConfigPresent.HasValue || _lastConfigPresent.Value != present)
{
_lastConfigPresent = present;
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EndlessTuner: EndlessModeConfig.Instance present = ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(present);
}
log.LogInfo(val);
}
}
internal static RefObj ResolveConfig()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Expected O, but got Unknown
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Expected O, but got Unknown
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Expected O, but got Unknown
bool flag = false;
string[] configTypeNames = ConfigTypeNames;
bool flag2 = default(bool);
foreach (string text in configTypeNames)
{
Type type = null;
try
{
TypeResolver obj = TypeResolver.Default;
type = ((obj != null) ? obj.Resolve(text) : null);
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(33, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EndlessTuner: resolving ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogWarning(val);
}
if (type == null)
{
continue;
}
flag = true;
RefType val2 = new RefType(type);
string[] instanceMemberNames = InstanceMemberNames;
foreach (string text2 in instanceMemberNames)
{
object obj2 = null;
try
{
obj2 = val2.GetStaticProperty(text2);
}
catch
{
try
{
obj2 = val2.GetStaticField(text2);
}
catch
{
}
}
if (obj2 != null)
{
return new RefObj(obj2);
}
}
}
if (!flag && ++_missClears % 20 == 0)
{
try
{
TypeResolver obj5 = TypeResolver.Default;
if (obj5 != null)
{
obj5.Clear();
}
}
catch (Exception ex2)
{
ManualLogSource log2 = Plugin.Log;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EndlessTuner: resolver clear failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex2.Message);
}
log2.LogWarning(val);
}
}
return null;
}
private static void Apply(RefObj config)
{
if (!TryReadUInt(config, "StartTimeSeconds", out var value))
{
return;
}
TryReadUShort(config, "StrikesPerWave", out var value2);
TryReadInt(config, "EasyTimeBonus", out var value3);
TryReadInt(config, "MediumTimeBonus", out var value4);
TryReadInt(config, "HardTimeBonus", out var value5);
if (!_baselinesCaptured)
{
_baseStartTimeSeconds = value;
_baseStrikesPerWave = value2;
_baseEasyTimeBonus = value3;
_baseMediumTimeBonus = value4;
_baseHardTimeBonus = value5;
_baselinesCaptured = true;
Plugin.Log.LogInfo((object)("EndlessTuner: vanilla endless baseline captured -- " + $"StartTimeSeconds={_baseStartTimeSeconds}, StrikesPerWave={_baseStrikesPerWave}, " + $"timeBonus Easy/Medium/Hard={_baseEasyTimeBonus}/{_baseMediumTimeBonus}/{_baseHardTimeBonus}"));
}
float value6 = Plugin.TimeMultiplier.Value;
uint num = ScaleToUInt(_baseStartTimeSeconds, value6, Plugin.MaxStartTimeSeconds.Value);
if (value != num && TryWrite(config, "StartTimeSeconds", num))
{
LogVerbose($"EndlessTuner: StartTimeSeconds {value} -> {num} (x{value6}).");
}
if (Plugin.ScaleTimeBonuses.Value)
{
WriteScaledInt(config, "EasyTimeBonus", _baseEasyTimeBonus, value3, value6);
WriteScaledInt(config, "MediumTimeBonus", _baseMediumTimeBonus, value4, value6);
WriteScaledInt(config, "HardTimeBonus", _baseHardTimeBonus, value5, value6);
}
int value7 = Plugin.HealthBonus.Value;
if (value7 != 0)
{
int num2 = _baseStrikesPerWave + value7;
if (num2 < 1)
{
num2 = 1;
}
if (num2 > 65535)
{
num2 = 65535;
}
if (value2 != num2 && TryWrite(config, "StrikesPerWave", (ushort)num2))
{
LogVerbose($"EndlessTuner: StrikesPerWave {value2} -> {num2}.");
}
}
}
private static void WriteScaledInt(RefObj config, string name, int baseline, int current, float mult)
{
int num = ScaleToInt(baseline, mult);
if (current != num && TryWrite(config, name, num))
{
LogVerbose($"EndlessTuner: {name} {current} -> {num} (x{mult}).");
}
}
private static void LogVerbose(string message)
{
if (Plugin.VerboseLogging.Value)
{
Plugin.Log.LogInfo((object)message);
}
}
private static uint ScaleToUInt(uint baseline, float mult, int cap)
{
double num = Math.Round((double)baseline * (double)mult);
if (num < 1.0)
{
num = 1.0;
}
if (cap > 0 && num > (double)cap)
{
num = cap;
}
return (uint)num;
}
private static int ScaleToInt(int baseline, float mult)
{
double num = Math.Round((double)baseline * (double)mult);
if (baseline > 0 && num < 1.0)
{
num = 1.0;
}
if (baseline < 0 && num > -1.0)
{
num = -1.0;
}
return (int)num;
}
private static bool TryReadUInt(RefObj config, string name, out uint value)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
value = 0u;
object obj = TryRead(config, name);
if (obj == null)
{
return false;
}
try
{
value = Convert.ToUInt32(obj);
return true;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EndlessTuner: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not convertible: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogWarning(val);
return false;
}
}
private static void TryReadUShort(RefObj config, string name, out ushort value)
{
value = 0;
object obj = TryRead(config, name);
if (obj == null)
{
return;
}
try
{
value = Convert.ToUInt16(obj);
}
catch
{
}
}
private static void TryReadInt(RefObj config, string name, out int value)
{
value = 0;
object obj = TryRead(config, name);
if (obj == null)
{
return;
}
try
{
value = Convert.ToInt32(obj);
}
catch
{
}
}
private static object TryRead(RefObj config, string name)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
try
{
return config.GetProperty(name);
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(31, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EndlessTuner: reading ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogWarning(val);
return null;
}
}
private static bool TryWrite(RefObj config, string name, object value)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
try
{
config.SetProperty(name, value);
return true;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EndlessTuner: writing ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
return false;
}
}
}
internal static class GameHooks
{
private const int MinIntervalMs = 400;
private static readonly string[] CandidateTypes = new string[3] { "Bombanana.UI.NewLobbyUI", "MissionHandler", "GameManager" };
private static int _lastPollTicks = int.MinValue;
private static int _installed;
internal static void Install(Harmony harmony)
{
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Expected O, but got Unknown
string[] candidateTypes = CandidateTypes;
foreach (string typeName in candidateTypes)
{
if (TryHookUpdate(harmony, typeName))
{
_installed++;
}
}
if (_installed == 0)
{
Plugin.Log.LogError((object)("GameHooks: could not patch any Update method; the plugin has no heartbeat and will not act. Candidates tried: " + string.Join(", ", CandidateTypes)));
return;
}
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(52, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("GameHooks: heartbeat installed on ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_installed);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Update method(s).");
}
log.LogInfo(val);
}
private static bool TryHookUpdate(Harmony harmony, string typeName)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Expected O, but got Unknown
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Expected O, but got Unknown
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Expected O, but got Unknown
Type type = null;
bool flag = default(bool);
try
{
TypeResolver obj = TypeResolver.Default;
type = ((obj != null) ? obj.Resolve(typeName) : null);
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("GameHooks: resolving ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogWarning(val);
}
if (type == null)
{
ManualLogSource log2 = Plugin.Log;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("GameHooks: type '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' not found.");
}
log2.LogWarning(val);
return false;
}
MethodInfo method = type.GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
if (method == null)
{
ManualLogSource log3 = Plugin.Log;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("GameHooks: '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".Update()' not found.");
}
log3.LogWarning(val);
return false;
}
MethodInfo method2 = typeof(GameHooks).GetMethod("OnUpdate", BindingFlags.Static | BindingFlags.NonPublic);
try
{
harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
ManualLogSource log4 = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(29, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("GameHooks: patched ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(type.FullName);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".Update().");
}
log4.LogInfo(val2);
return true;
}
catch (Exception ex2)
{
ManualLogSource log5 = Plugin.Log;
bool flag2 = default(bool);
BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(38, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("GameHooks: patching ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(type.FullName);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(".Update() failed: ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex2);
}
log5.LogError(val3);
return false;
}
}
private static void OnUpdate()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Expected O, but got Unknown
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Expected O, but got Unknown
int tickCount = Environment.TickCount;
if (_lastPollTicks != int.MinValue && tickCount - _lastPollTicks < 400)
{
return;
}
_lastPollTicks = tickCount;
bool flag = default(bool);
try
{
EndlessTuner.Poll();
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EndlessTuner poll failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log.LogError(val);
}
try
{
LobbyDiagnostics.Poll();
}
catch (Exception ex2)
{
ManualLogSource log2 = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(30, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LobbyDiagnostics poll failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex2);
}
log2.LogError(val);
}
try
{
ModuleFilter.Poll();
}
catch (Exception ex3)
{
ManualLogSource log3 = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleFilter poll failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex3);
}
log3.LogError(val);
}
try
{
ModuleWhitelist.Poll();
}
catch (Exception ex4)
{
ManualLogSource log4 = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleWhitelist poll failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex4);
}
log4.LogError(val);
}
}
}
internal static class LobbyDiagnostics
{
private static readonly string[] LobbyTypeNames = new string[2] { "LobbyHandler", "BombGame.LobbyHandler" };
private static readonly string[] HandlerMemberNames = new string[1] { "Handler" };
private static bool _typeFound;
private static string _resolveState;
private static string _lastGateReport;
internal static void Poll()
{
if (Plugin.VerboseLogging.Value)
{
RefObj val = ResolveLobby();
ReportResolveState((val != null) ? "lobby-found" : (_typeFound ? "type-ok-but-no-lobby-instance" : "type-not-found"));
if (val == null)
{
_lastGateReport = null;
}
else
{
ReportStartGates(val);
}
}
}
private static void ReportResolveState(string state)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
if (!(state == _resolveState))
{
_resolveState = state;
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(40, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LobbyDiagnostics: lobby resolve state = ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(state);
}
log.LogInfo(val);
}
}
private static void ReportStartGates(RefObj lobby)
{
int num = ReadInt(lobby, "MinPlayerCount");
int value = ReadInt(lobby, "MaxPlayerCount");
string text = CallBool(lobby, "AreLobbyRolesValidForStart");
string value2 = CallBool(lobby, "CanLobbyBeStarted");
string text2 = $"min={num} max={value} locked={ReadBool(lobby, "IsMissionStartLocked")} rolesValid={text} canStart={value2} canOffer={CallBool(lobby, "CanOfferLobbyStart")}";
if (!(text2 == _lastGateReport))
{
_lastGateReport = text2;
Plugin.Log.LogInfo((object)("LobbyDiagnostics: " + text2));
if (num > 1 && text == "False")
{
Plugin.Log.LogInfo((object)($"LobbyDiagnostics: this lobby needs {num} players. BOMBANANA! requires three " + "players in every mode, which no mod setting can waive -- the start gate checks the lobby roles themselves."));
}
}
}
private static RefObj ResolveLobby()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Expected O, but got Unknown
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Expected O, but got Unknown
_typeFound = false;
string[] lobbyTypeNames = LobbyTypeNames;
bool flag = default(bool);
foreach (string text in lobbyTypeNames)
{
Type type = null;
try
{
TypeResolver obj = TypeResolver.Default;
type = ((obj != null) ? obj.Resolve(text) : null);
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(37, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LobbyDiagnostics: resolving ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogWarning(val);
}
if (type == null)
{
continue;
}
_typeFound = true;
RefType val2 = new RefType(type);
string[] handlerMemberNames = HandlerMemberNames;
foreach (string text2 in handlerMemberNames)
{
object obj2 = null;
try
{
obj2 = val2.GetStaticProperty(text2);
}
catch
{
}
if (obj2 == null)
{
try
{
obj2 = val2.GetStaticField(text2);
}
catch
{
}
}
if (obj2 == null)
{
try
{
RefObj obj5 = val2.Singleton(text2);
obj2 = ((obj5 != null) ? obj5.Instance : null);
}
catch
{
}
}
if (obj2 != null)
{
return new RefObj(obj2);
}
}
}
return null;
}
private static int ReadInt(RefObj target, string name)
{
try
{
object property = target.GetProperty(name);
return (property == null) ? (-1) : Convert.ToInt32(property);
}
catch
{
return -1;
}
}
private static bool ReadBool(RefObj target, string name)
{
try
{
object property = target.GetProperty(name);
return property != null && Convert.ToBoolean(property);
}
catch
{
return false;
}
}
private static string CallBool(RefObj target, string name)
{
try
{
object obj = target.Call(name, Array.Empty<object>());
return (obj == null) ? "null" : Convert.ToBoolean(obj).ToString();
}
catch (Exception ex)
{
return "err:" + ex.GetType().Name;
}
}
}
internal static class ModuleFilter
{
private static readonly string[] RegistryTypeNames = new string[2] { "ModuleRegistry", "BombGame.ModuleRegistry" };
private static readonly string[] MorseFlagMethods = new string[2] { "TryPickRandomPuzzleAtDifficulty", "TryBuildPuzzleCandidates" };
private static int _calls;
private static int _forced;
private static bool _firstCallLogged;
private static bool _entriesLogged;
private static int _entriesAttempts;
private const int MaxEntryAttempts = 60;
internal static void Install(Harmony harmony)
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
if (!Plugin.DisableMorse.Value)
{
Plugin.Log.LogInfo((object)"ModuleFilter: DisableMorse is off; the game keeps the Morse module.");
return;
}
int num = 0;
string[] morseFlagMethods = MorseFlagMethods;
foreach (string methodName in morseFlagMethods)
{
if (ForceAllowMorseFalse(harmony, methodName))
{
num++;
}
}
if (num == 0)
{
Plugin.Log.LogError((object)("ModuleFilter: could not patch any Morse selector; the Morse module will still appear. Tried: " + string.Join(", ", MorseFlagMethods)));
}
else
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(53, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleFilter: Morse disabled via ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" selector patch(es).");
}
log.LogInfo(val);
}
Poll();
}
internal static void Poll()
{
if (!_entriesLogged && Plugin.DisableMorse.Value)
{
_entriesAttempts++;
LogRegistryEntries();
if (!_entriesLogged && _entriesAttempts >= 60)
{
_entriesLogged = true;
Plugin.Log.LogWarning((object)($"ModuleFilter: gave up listing registry modules after {_entriesAttempts} attempts; " + "the registry stayed empty. Names can still be verified with ModuleRegistry.Get."));
}
}
}
private static bool ForceAllowMorseFalse(Harmony harmony, string methodName)
{
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Expected O, but got Unknown
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Expected O, but got Unknown
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Expected O, but got Unknown
Type type = Resolve(RegistryTypeNames);
bool flag = default(bool);
if (type == null)
{
ManualLogSource log = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(49, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleFilter: type ModuleRegistry not found for ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
}
log.LogError(val);
return false;
}
MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (method == null)
{
ManualLogSource log2 = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(40, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleFilter: ModuleRegistry.");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found.");
}
log2.LogError(val);
return false;
}
MethodInfo method2 = typeof(ModuleFilter).GetMethod("NoMorsePrefix", BindingFlags.Static | BindingFlags.NonPublic);
try
{
harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
ManualLogSource log3 = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(63, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("ModuleFilter: patched ModuleRegistry.");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(methodName);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (force allowMorse=false).");
}
log3.LogInfo(val2);
return true;
}
catch (Exception ex)
{
ManualLogSource log4 = Plugin.Log;
bool flag2 = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(47, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleFilter: patching ModuleRegistry.");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log4.LogError(val);
return false;
}
}
private static void NoMorsePrefix(ref bool allowMorse)
{
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
_calls++;
if (!_firstCallLogged)
{
_firstCallLogged = true;
Plugin.Log.LogInfo((object)($"ModuleFilter: selector invoked (call #{_calls}), incoming allowMorse={allowMorse}. " + "The detour is intercepting module selection."));
}
if (!allowMorse)
{
return;
}
allowMorse = false;
_forced++;
if (_forced == 1)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(72, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleFilter: game asked for Morse (call #");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_calls);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") and was overridden to false.");
}
log.LogInfo(val);
}
}
private static void LogRegistryEntries()
{
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Expected O, but got Unknown
//IL_0287: Unknown result type (might be due to invalid IL or missing references)
//IL_028e: Expected O, but got Unknown
//IL_022a: Unknown result type (might be due to invalid IL or missing references)
//IL_0231: Expected O, but got Unknown
bool flag2 = default(bool);
try
{
Type type = Resolve(RegistryTypeNames);
if (type == null)
{
Plugin.Log.LogWarning((object)"ModuleFilter: ModuleRegistry type not found; cannot list modules.");
_entriesLogged = true;
return;
}
List<string> list = new List<string>();
bool flag = false;
string[] array = new string[2] { "instance", "Instance" };
foreach (string text in array)
{
PropertyInfo propertyInfo = FindProperty(type, text, isStatic: true);
if (propertyInfo == null)
{
continue;
}
flag = true;
object obj = null;
try
{
obj = propertyInfo.GetValue(null);
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(31, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleFilter: reading ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogWarning(val);
}
if (obj == null)
{
continue;
}
string[] array2 = new string[2] { "Data", "Entries" };
foreach (string name in array2)
{
PropertyInfo propertyInfo2 = FindProperty(type, name, isStatic: false);
if (propertyInfo2 == null)
{
continue;
}
object obj2 = null;
try
{
obj2 = propertyInfo2.GetValue(obj);
}
catch
{
}
if (!(obj2 is IEnumerable enumerable))
{
continue;
}
List<string> list2 = new List<string>();
foreach (object item in enumerable)
{
if (item != null)
{
string text2 = item.GetType().GetProperty("Name")?.GetValue(item) as string;
list2.Add(text2 ?? "?");
}
}
if (list2.Count > list.Count)
{
list = list2;
}
}
}
if (!flag)
{
Plugin.Log.LogWarning((object)("ModuleFilter: no static instance/Instance property anywhere on the base chain of " + type.FullName + "; cannot list modules."));
_entriesLogged = true;
}
else if (list.Count != 0)
{
ManualLogSource log2 = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(39, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("ModuleFilter: registry has ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(list.Count);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" module(s): ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(string.Join(", ", list));
}
log2.LogInfo(val2);
_entriesLogged = true;
}
}
catch (Exception ex2)
{
ManualLogSource log3 = Plugin.Log;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(47, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleFilter: listing registry entries failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex2.Message);
}
log3.LogWarning(val);
}
}
private static Type Resolve(string[] candidates)
{
foreach (string text in candidates)
{
try
{
TypeResolver obj = TypeResolver.Default;
Type type = ((obj != null) ? obj.Resolve(text) : null);
if (type != null)
{
return type;
}
}
catch
{
}
}
return null;
}
private static PropertyInfo FindProperty(Type type, string name, bool isStatic)
{
BindingFlags bindingAttr = (BindingFlags)(0x32 | (isStatic ? 8 : 4));
Type type2 = type;
while (type2 != null)
{
PropertyInfo property = type2.GetProperty(name, bindingAttr);
if (property != null)
{
return property;
}
type2 = type2.BaseType;
}
return null;
}
}
internal static class ModuleWhitelist
{
private static readonly string[] MissionDataTypeNames = new string[2] { "EndlessMissionData", "BombGame.EndlessMissionData" };
private static readonly string[] RegistryTypeNames = new string[2] { "ModuleRegistry", "BombGame.ModuleRegistry" };
private static readonly string[] PickMethodNames = new string[2] { "TryPickPuzzleModule", "TryPickAllowedPuzzleModule" };
private static readonly string[] KnownModuleNames = new string[14]
{
"Cable", "Calculator", "Direction", "ColorSlider", "Symbol", "Piano", "Switch", "MonkeySays", "Morse", "Soundboard",
"Maze", "Pressure", "Slider", "Alarm"
};
private static readonly List<string> Allowed = new List<string>();
private static readonly Random Rng = new Random();
private static bool _validated;
private static bool _togglesApplied;
private static bool _firstCallLogged;
private static int _pickCalls;
private static int _replaced;
private static int _passed;
internal static void Install(Harmony harmony)
{
if (string.IsNullOrWhiteSpace(Plugin.EnabledModules.Value))
{
Plugin.Log.LogInfo((object)("ModuleWhitelist: EnabledModules is empty; endless waves use the game's normal module pool. Available names: " + string.Join(", ", KnownModuleNames) + "."));
return;
}
int num = 0;
string[] pickMethodNames = PickMethodNames;
foreach (string methodName in pickMethodNames)
{
if (PatchPicker(harmony, methodName))
{
num++;
}
}
if (num == 0)
{
Plugin.Log.LogError((object)("ModuleWhitelist: could not patch any module picker, so the whitelist will not take effect. Tried: " + string.Join(", ", PickMethodNames)));
}
Poll();
}
internal static void Poll()
{
if (!_validated && !string.IsNullOrWhiteSpace(Plugin.EnabledModules.Value) && TryValidate())
{
_validated = true;
if (Allowed.Count != 0)
{
ApplyRepeatToggles();
Plugin.Log.LogInfo((object)($"ModuleWhitelist: active with {Allowed.Count} module(s): {string.Join(", ", Allowed)}. " + "Every other module the game picks for an endless wave is replaced."));
}
}
}
private static bool PatchPicker(Harmony harmony, string methodName)
{
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Expected O, but got Unknown
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Expected O, but got Unknown
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Expected O, but got Unknown
Type type = Resolve(MissionDataTypeNames);
bool flag = default(bool);
if (type == null)
{
ManualLogSource log = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(51, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleWhitelist: EndlessMissionData not found for ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
}
log.LogError(val);
return false;
}
MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (method == null)
{
ManualLogSource log2 = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(47, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleWhitelist: EndlessMissionData.");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found.");
}
log2.LogError(val);
return false;
}
MethodInfo method2 = typeof(ModuleWhitelist).GetMethod("RestrictPostfix", BindingFlags.Static | BindingFlags.NonPublic);
try
{
harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
ManualLogSource log3 = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(45, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("ModuleWhitelist: patched EndlessMissionData.");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(methodName);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
}
log3.LogInfo(val2);
return true;
}
catch (Exception ex)
{
ManualLogSource log4 = Plugin.Log;
bool flag2 = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(35, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleWhitelist: patching ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log4.LogError(val);
return false;
}
}
private static void RestrictPostfix(ref string moduleName)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Expected O, but got Unknown
_pickCalls++;
bool flag = default(bool);
if (!_firstCallLogged)
{
_firstCallLogged = true;
ManualLogSource log = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(63, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleWhitelist: module picker invoked (call #");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_pickCalls);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), game chose ");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(moduleName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'.");
}
log.LogInfo(val);
}
if (Allowed.Count == 0)
{
return;
}
if (IsAllowed(moduleName))
{
_passed++;
return;
}
string text = moduleName;
moduleName = Allowed[Rng.Next(Allowed.Count)];
_replaced++;
if (_replaced <= 5)
{
ManualLogSource log2 = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ModuleWhitelist: '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' -> '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(moduleName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (replacement #");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_replaced);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
}
log2.LogInfo(val);
}
}
private static bool IsAllowed(string name)
{
if (string.IsNullOrEmpty(name))
{
return false;
}
for (int i = 0; i < Allowed.Count; i++)
{
if (string.Equals(Allowed[i], name, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
private static bool TryValidate()
{
Type type = Resolve(RegistryTypeNames);
if (type == null)
{
return false;
}
MethodInfo method = type.GetMethod("Get", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null);
if (method == null)
{
Plugin.Log.LogError((object)"ModuleWhitelist: ModuleRegistry.Get(string) not found, so no configured name can be verified. No rewriting will happen.");
return true;
}
LogAvailableModules(method, type);
List<string> list = new List<string>();
List<string> list2 = new List<string>();
List<string> list3 = new List<string>();
string[] array = Plugin.EnabledModules.Value.Split(new char[4] { ',', ';', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string text in array)
{
if (TryResolveName(method, type, text, out var actualName, out var isChaos))
{
if (!ContainsIgnoreCase(list, actualName))
{
list.Add(actualName);
}
if (isChaos && !ContainsIgnoreCase(list3, actualName))
{
list3.Add(actualName);
}
}
else
{
list2.Add(text);
}
}
if (list2.Count > 0)
{
Plugin.Log.LogWarning((object)("ModuleWhitelist: these names are not in the module registry and were ignored: " + string.Join(", ", list2) + ". Valid names are: " + string.Join(", ", KnownModuleNames) + "."));
}
if (list.Count == 0)
{
Plugin.Log.LogError((object)"ModuleWhitelist: no configured module name was valid, so no rewriting will happen and endless waves keep the game's normal module mix.");
return true;
}
if (list3.Count > 0)
{
Plugin.Log.LogInfo((object)("ModuleWhitelist: the game classifies these as chaos modules, they are still used because you listed them: " + string.Join(", ", list3)));
}
Allowed.Clear();
Allowed.AddRange(list);
return true;
}
private static void LogAvailableModules(MethodInfo get, Type registryType)
{
List<string> list = new List<string>();
List<string> list2 = new List<string>();
string[] knownModuleNames = KnownModuleNames;
foreach (string text in knownModuleNames)
{
if (TryResolveName(get, registryType, text, out var actualName, out var _))
{
list.Add(actualName);
}
else
{
list2.Add(text);
}
}
Plugin.Log.LogInfo((object)($"ModuleWhitelist: {list.Count}/{KnownModuleNames.Length} known module names resolve " + "in this build: " + string.Join(", ", list)));
if (list2.Count > 0)
{
Plugin.Log.LogWarning((object)("ModuleWhitelist: listed in the mod but NOT present in this build: " + string.Join(", ", list2)));
}
}
private static bool TryResolveName(MethodInfo get, Type registryType, string name, out string actualName, out bool isChaos)
{
actualName = null;
isChaos = false;
try
{
object obj = get.Invoke(null, new object[1] { name });
if (obj == null)
{
return false;
}
string text = obj.GetType().GetProperty("Name")?.GetValue(obj) as string;
if (string.IsNullOrEmpty(text))
{
return false;
}
actualName = text;
isChaos = IsChaos(registryType, text);
return true;
}
catch
{
return false;
}
}
private static bool IsChaos(Type registryType, string name)
{
try
{
MethodInfo method = registryType.GetMethod("IsChaosModule", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null);
if (method == null)
{
return false;
}
object obj = method.Invoke(null, new object[1] { name });
bool flag = default(bool);
int num;
if (obj is bool)
{
flag = (bool)obj;
num = 1;
}
else
{
num = 0;
}
return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
}
catch
{
return false;
}
}
private static bool ContainsIgnoreCase(List<string> list, string value)
{
for (int i = 0; i < list.Count; i++)
{
if (string.Equals(list[i], value, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
private static void ApplyRepeatToggles()
{
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
if (_togglesApplied)
{
return;
}
RefObj val = EndlessTuner.ResolveConfig();
if (val == null)
{
return;
}
try
{
val.SetProperty("AvoidRepeatNormalModule", (object)false);
val.SetProperty("AvoidRepeatChaosModule", (object)false);
_togglesApplied = true;
Plugin.Log.LogInfo((object)"ModuleWhitelist: AvoidRepeatNormalModule/AvoidRepeatChaosModule set to false so a small whitelist can fill a whole wave.");
}
catch (Exception ex)
{
_togglesApplied = true;
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(52, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("ModuleWhitelist: could not clear the repeat guards: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
}
log.LogWarning(val2);
}
}
private static Type Resolve(string[] candidates)
{
foreach (string text in candidates)
{
try
{
TypeResolver obj = TypeResolver.Default;
Type type = ((obj != null) ? obj.Resolve(text) : null);
if (type != null)
{
return type;
}
}
catch
{
}
}
return null;
}
}
[BepInPlugin("BOMBANANA.EndlessEasy", "Endless Easy", "1.7.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BasePlugin
{
public const string PluginGuid = "BOMBANANA.EndlessEasy";
public const string PluginName = "Endless Easy";
public const string PluginVersion = "1.7.0";
internal static ManualLogSource Log;
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<bool> OnlyApplyAsHost;
internal static ConfigEntry<float> TimeMultiplier;
internal static ConfigEntry<int> MaxStartTimeSeconds;
internal static ConfigEntry<bool> ScaleTimeBonuses;
internal static ConfigEntry<int> HealthBonus;
internal static ConfigEntry<bool> VerboseLogging;
internal static ConfigEntry<bool> DisableMorse;
internal static ConfigEntry<string> EnabledModules;
public override void Load()
{
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Expected O, but got Unknown
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Expected O, but got Unknown
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Expected O, but got Unknown
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Expected O, but got Unknown
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Expected O, but got Unknown
//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Expected O, but got Unknown
//IL_0229: Unknown result type (might be due to invalid IL or missing references)
//IL_022f: Expected O, but got Unknown
//IL_0257: Unknown result type (might be due to invalid IL or missing references)
//IL_025e: Expected O, but got Unknown
Log = ((BasePlugin)this).Log;
Enabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. When false the plugin does nothing.");
OnlyApplyAsHost = ((BasePlugin)this).Config.Bind<bool>("General", "OnlyApplyAsHost", true, "Only the host needs this mod, so by default only the host rewrites the config. The host's values are what everyone plays with: the bomb timer is pushed to clients via Bomb.StartTickLoopClientRpc / BroadcastTimer, and Bomb.Health / MaxHealth / Outcome are NetworkVariables. A client without (or skipping) the rewrite still shows the vanilla number in the LOBBY panel, because that panel reads each client's own local config -- but the in-mission countdown and strike count come from the host. Set this to false to also rewrite clients' configs so their lobby panel matches.");
TimeMultiplier = ((BasePlugin)this).Config.Bind<float>("Time", "TimeMultiplier", 1.5f, new ConfigDescription("Multiplier for the endless bomb timer. 1.5 = 50% more time (2:30 becomes 3:45). 1 disables this lever.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
MaxStartTimeSeconds = ((BasePlugin)this).Config.Bind<int>("Time", "MaxStartTimeSeconds", 0, new ConfigDescription("Safety cap on the rewritten StartTimeSeconds, in seconds. 0 means no cap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3600), Array.Empty<object>()));
ScaleTimeBonuses = ((BasePlugin)this).Config.Bind<bool>("Time", "ScaleTimeBonuses", true, "Also scale the per-difficulty time bonuses (EasyTimeBonus / MediumTimeBonus / HardTimeBonus) by TimeMultiplier, so the multiplier holds for every difficulty.");
HealthBonus = ((BasePlugin)this).Config.Bind<int>("Difficulty", "HealthBonus", 2, new ConfigDescription("Extra mistakes tolerated per endless wave, added to EndlessModeConfig.StrikesPerWave. 0 disables this lever.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200), Array.Empty<object>()));
VerboseLogging = ((BasePlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", true, "Log the captured vanilla baseline, every value written back, and the lobby's mission-start gate state. Turn off once you are happy.");
DisableMorse = ((BasePlugin)this).Config.Bind<bool>("Modules", "DisableMorse", false, "Keep the Morse code module out of the puzzle pool. Uses the game's own allowMorse selector flag, so no module data is edited. Applies wherever the game offers the module, not only in endless mode.");
EnabledModules = ((BasePlugin)this).Config.Bind<string>("Modules", "EnabledModules", "", "Comma-separated list of the ONLY modules endless waves may use, for example 'Cable' or 'Cable, Calculator'. Every other module the game picks for a wave is replaced with one from this list. Leave EMPTY for the game's normal module pool (the default). Each name is checked against the module registry at startup and unknown names are reported and ignored, so a typo cannot break a wave. BOMBANANA ships these modules: Cable, Calculator, Direction, ColorSlider, Symbol, Piano, Switch, MonkeySays, Morse, Soundboard, Maze, Pressure, Slider, Alarm.");
Harmony val = new Harmony("BOMBANANA.EndlessEasy");
val.PatchAll(typeof(Plugin).Assembly);
bool flag = default(bool);
if (Enabled.Value)
{
try
{
GameHooks.Install(val);
}
catch (Exception ex)
{
ManualLogSource log = Log;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(30, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to install game hooks: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
}
log.LogError(val2);
}
try
{
ModuleFilter.Install(val);
}
catch (Exception ex2)
{
ManualLogSource log2 = Log;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to install module filter: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex2);
}
log2.LogError(val2);
}
try
{
ModuleWhitelist.Install(val);
}
catch (Exception ex3)
{
ManualLogSource log3 = Log;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(40, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to install the module whitelist: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex3);
}
log3.LogError(val2);
}
}
ManualLogSource log4 = Log;
BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(50, 5, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>("Endless Easy");
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>("1.7.0");
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" loaded. Enabled=");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<bool>(Enabled.Value);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", ");
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TimeMultiplier=");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(TimeMultiplier.Value);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", HealthBonus=");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(HealthBonus.Value);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(".");
}
log4.LogInfo(val3);
}
public override bool Unload()
{
return true;
}
}
}