using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameConsole;
using GameConsole.CommandTree;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using plog;
using plog.Models;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CyberSeedSetter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+7b2a14acc58900f012365f438b8953c91793e7da")]
[assembly: AssemblyProduct("CyberSeedSetter")]
[assembly: AssemblyTitle("CyberSeedSetter")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 CyberSeedSetter
{
[HarmonyPatch(typeof(EndlessGrid))]
public static class EndlessGridPatcher
{
[CompilerGenerated]
private sealed class <Random_Range_Replacer>d__7 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
{
private int <>1__state;
private CodeInstruction <>2__current;
private int <>l__initialThreadId;
private IEnumerable<CodeInstruction> instructions;
public IEnumerable<CodeInstruction> <>3__instructions;
private MethodBase method;
public MethodBase <>3__method;
private IEnumerator<CodeInstruction> <>7__wrap1;
private CodeInstruction <inst>5__3;
CodeInstruction IEnumerator<CodeInstruction>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <Random_Range_Replacer>d__7(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || (uint)(num - 1) <= 2u)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<>7__wrap1 = null;
<inst>5__3 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Expected O, but got Unknown
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>7__wrap1 = instructions.GetEnumerator();
<>1__state = -3;
goto IL_0125;
case 1:
<>1__state = -3;
<inst>5__3.operand = m_EndlessGridPatcher_Random_Range_Int;
goto IL_00ff;
case 2:
<>1__state = -3;
<inst>5__3.operand = m_EndlessGridPatcher_Random_Range_Float;
goto IL_00ff;
case 3:
{
<>1__state = -3;
<inst>5__3 = null;
goto IL_0125;
}
IL_0125:
if (<>7__wrap1.MoveNext())
{
<inst>5__3 = <>7__wrap1.Current;
if (CodeInstructionExtensions.Calls(<inst>5__3, m_Random_Range_Int))
{
<>2__current = new CodeInstruction(OpCodes.Ldstr, (object)method.Name);
<>1__state = 1;
return true;
}
if (CodeInstructionExtensions.Calls(<inst>5__3, m_Random_Range_Float))
{
<>2__current = new CodeInstruction(OpCodes.Ldstr, (object)method.Name);
<>1__state = 2;
return true;
}
goto IL_00ff;
}
<>m__Finally1();
<>7__wrap1 = null;
return false;
IL_00ff:
<>2__current = <inst>5__3;
<>1__state = 3;
return true;
}
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<>7__wrap1 != null)
{
<>7__wrap1.Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
{
<Random_Range_Replacer>d__7 <Random_Range_Replacer>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<Random_Range_Replacer>d__ = this;
}
else
{
<Random_Range_Replacer>d__ = new <Random_Range_Replacer>d__7(0);
}
<Random_Range_Replacer>d__.instructions = <>3__instructions;
<Random_Range_Replacer>d__.method = <>3__method;
return <Random_Range_Replacer>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
}
}
private static readonly MethodInfo m_Random_Range_Int = AccessTools.Method(typeof(Random), "Range", new Type[2]
{
typeof(int),
typeof(int)
}, (Type[])null);
private static readonly MethodInfo m_Random_Range_Float = AccessTools.Method(typeof(Random), "Range", new Type[2]
{
typeof(float),
typeof(float)
}, (Type[])null);
private static readonly MethodInfo m_EndlessGridPatcher_Random_Range_Int = new Func<int, int, string, int>(Random_Range_Int).Method;
private static readonly MethodInfo m_EndlessGridPatcher_Random_Range_Float = new Func<float, float, string, float>(Random_Range_Float).Method;
[HarmonyPrefix]
[HarmonyPatch("Start")]
private static void InitRandom()
{
RandomManager.Initialize(CheatsManager.KeepCheatsEnabled && MonoSingleton<PrefsManager>.Instance.GetBool("cheat.cyberseedsetter.seed-override", false));
}
private static int Random_Range_Int(int min, int max, string methodName)
{
return RandomManager.RandomInstance.Range(min, max);
}
private static float Random_Range_Float(float min, float max, string methodName)
{
return RandomManager.RandomInstance.Range(min, max);
}
[IteratorStateMachine(typeof(<Random_Range_Replacer>d__7))]
public static IEnumerable<CodeInstruction> Random_Range_Replacer(IEnumerable<CodeInstruction> instructions, MethodBase method)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <Random_Range_Replacer>d__7(-2)
{
<>3__instructions = instructions,
<>3__method = method
};
}
}
[BepInPlugin("com.10-days-till-xmas.cyberseedsetter", "CyberSeedSetter", "1.1.0")]
public sealed class Plugin : BaseUnityPlugin
{
public sealed class PluginConfigs
{
public readonly ConfigEntry<int> rngSeed = config.Bind<int>("general", "RNG Seed", 0, "sets the seed for the random number generator, leave null for a random seed");
public PluginConfigs(ConfigFile config)
{
}
}
internal static ManualLogSource Logger { get; private set; }
internal static PluginConfigs Configs { get; private set; }
private void Awake()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Plugin com.10-days-till-xmas.cyberseedsetter is loaded!");
((Object)((Component)this).gameObject).hideFlags = (HideFlags)4;
Configs = new PluginConfigs(((BaseUnityPlugin)this).Config);
Harmony harmony = new Harmony("com.10-days-till-xmas.cyberseedsetter");
harmony.PatchAll();
MethodInfo m_EndlessGridPatcher_Random = new Func<IEnumerable<CodeInstruction>, MethodBase, IEnumerable<CodeInstruction>>(EndlessGridPatcher.Random_Range_Replacer).Method;
CollectionExtensions.Do<MethodInfo>(from m in AccessTools.GetDeclaredMethods(typeof(EndlessGrid))
where MethodBaseExtensions.HasMethodBody((MethodBase)m) && m.MemberType == MemberTypes.Method && !m.IsSpecialName
select m, (Action<MethodInfo>)delegate(MethodInfo method)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
harmony.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(m_EndlessGridPatcher_Random), (HarmonyMethod)null, (HarmonyMethod)null);
});
}
}
public static class RandomManager
{
public static SeededRandom RandomInstance { get; private set; }
public static void Initialize(bool seeded)
{
RandomInstance = (seeded ? new SeededRandom(Plugin.Configs.rngSeed.Value) : new SeededRandom());
Plugin.Logger.LogInfo((object)$"Initializing RandomManager with seed = {RandomInstance.Seed}");
}
}
public sealed class SeededRandom
{
private readonly Random random;
public int Seed { get; }
public SeededRandom(int seed)
{
Seed = seed;
random = new Random(seed);
base..ctor();
}
public SeededRandom()
: this(Random.Range(int.MinValue, int.MaxValue))
{
}
public int Range(int minValue, int maxValue)
{
return random.Next(minValue, maxValue);
}
public float Range(float minValue, float maxValue)
{
return (float)random.NextDouble() * (maxValue - minValue) + minValue;
}
}
internal static class MyPluginInfo
{
public const string PLUGIN_GUID = "com.10-days-till-xmas.cyberseedsetter";
public const string PLUGIN_NAME = "CyberSeedSetter";
public const string PLUGIN_VERSION = "1.1.0";
}
}
namespace CyberSeedSetter.ConsoleCommands
{
[HarmonyPatch(typeof(Console))]
public class ConsolePatcher
{
[HarmonyPostfix]
[HarmonyPatch("Awake")]
private static void AwakePostfix(Console __instance)
{
Plugin.Logger.LogInfo((object)"Registering SeedCommands");
__instance.RegisterCommand((ICommand)(object)new SeedCommands(__instance));
}
}
public sealed class SeedCommands : CommandRoot, IConsoleLogger
{
public override string Name => "Set Seed Command";
public override string Description => "Commands for setting/getting the RNG seed for Cybergrind wave creation.";
public Logger Log => new Logger(((CommandRoot)this).Name);
private Node[] SetterNodes => (Node[])(object)new Node[3]
{
(Node)CommandRoot.Leaf<int>("set", (Action<int>)Set, false),
(Node)CommandRoot.Leaf<string>("set-str", (Action<string>)SetStr, false),
(Node)CommandRoot.Leaf("paste", (Action)Paste, false)
};
private Node[] GetterNodes => (Node[])(object)new Node[2]
{
(Node)CommandRoot.Leaf("get", (Action)Get, false),
(Node)CommandRoot.Leaf("copy", (Action)Copy, false)
};
public SeedCommands(Console con)
: base(con)
{
}
protected override Branch BuildTree(Console con)
{
if (!(SceneHelper.CurrentScene != "Endless"))
{
return CommandRoot.Branch("cybergrind-seed", SetterNodes);
}
Node[] setterNodes = SetterNodes;
Node[] getterNodes = GetterNodes;
int num = 0;
Node[] array = (Node[])(object)new Node[setterNodes.Length + getterNodes.Length];
ReadOnlySpan<Node> readOnlySpan = new ReadOnlySpan<Node>(setterNodes);
readOnlySpan.CopyTo(new Span<Node>(array).Slice(num, readOnlySpan.Length));
num += readOnlySpan.Length;
ReadOnlySpan<Node> readOnlySpan2 = new ReadOnlySpan<Node>(getterNodes);
readOnlySpan2.CopyTo(new Span<Node>(array).Slice(num, readOnlySpan2.Length));
num += readOnlySpan2.Length;
return CommandRoot.Branch("cybergrind-seed", array);
}
private static void Set(int seed)
{
Plugin.Configs.rngSeed.Value = seed;
}
private void SetStr(string seed)
{
Set(ParseSeed(seed, delegate(string s, int v)
{
Log.Info($"Parsed seed value: \"{s}\" -> {v}", (IEnumerable<Tag>)null, (string)null, (object)null);
}, delegate(string s, int v)
{
Log.Info($"Hashed seed value: \"{s}\" -> {v}", (IEnumerable<Tag>)null, (string)null, (object)null);
}));
}
private void Get()
{
Log.Info($"Current seed value: {RandomManager.RandomInstance.Seed}", (IEnumerable<Tag>)null, (string)null, (object)null);
}
private void Copy()
{
Log.Info($"Copied seed value to clipboard: ({RandomManager.RandomInstance.Seed})", (IEnumerable<Tag>)null, (string)null, (object)null);
GUIUtility.systemCopyBuffer = RandomManager.RandomInstance.Seed.ToString(CultureInfo.CurrentCulture);
}
private void Paste()
{
SetStr(GUIUtility.systemCopyBuffer);
}
private static int ParseSeed(string seed, Action<string, int>? onParsed = null, Action<string, int>? onFailed = null)
{
if (int.TryParse(seed, NumberStyles.Number, CultureInfo.CurrentCulture, out var result))
{
onParsed?.Invoke(seed, result);
}
else
{
result = seed.GetHashCode();
onFailed?.Invoke(seed, result);
}
return result;
}
}
}
namespace CyberSeedSetter.Cheats
{
[HarmonyPatch(typeof(CheatsManager))]
public static class CheatsManagerPatcher
{
[HarmonyTranspiler]
[HarmonyPatch("Start")]
private static IEnumerable<CodeInstruction> StartTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
val.Start().MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
{
new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"meta", (string)null),
new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(CheatsManager), "RegisterCheat", (Type[])null, (Type[])null), (string)null)
}).Insert((CodeInstruction[])(object)new CodeInstruction[2]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
CodeInstruction.Call((Expression<Action>)(() => RegisterCheats(null)))
});
return val.InstructionEnumeration();
}
private static void RegisterCheats(CheatsManager __instance)
{
if (!(SceneHelper.CurrentScene != "Endless"))
{
Plugin.Logger.LogInfo((object)"Registering SeedOverrideCheat");
__instance.RegisterCheat((ICheat)(object)new SeedOverrideCheat(), "meta");
}
}
}
public sealed class SeedOverrideCheat : ICheat
{
public const string IDENTIFIER = "cyberseedsetter.seed-override";
public string LongName => "Cybergrind Seed Override";
public string Identifier => "cyberseedsetter.seed-override";
public string ButtonEnabledOverride => null;
public string ButtonDisabledOverride => null;
public string Icon => "warning";
public bool DefaultState => false;
public StatePersistenceMode PersistenceMode => (StatePersistenceMode)1;
public bool IsActive { get; private set; }
public void Enable(CheatsManager manager)
{
IsActive = true;
MonoSingleton<PrefsManager>.Instance.SetBool("cheat.ultrakill.keep-enabled", true);
MonoSingleton<SubtitleController>.Instance.DisplaySubtitle("Restart the level with keep cheats enabled to apply the seed", (AudioSource)null, false);
}
public void Disable()
{
IsActive = false;
MonoSingleton<SubtitleController>.Instance.DisplaySubtitle("Restart the level to play without the seed", (AudioSource)null, false);
}
}
}