using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using CustomWaveCheat.Assets;
using CustomWaveCheat.Cheats;
using CustomWaveCheat.Utils;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("CustomWaveCheat")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CustomWaveCheat")]
[assembly: AssemblyCopyright("Flazhik © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("C2834228-C714-4C19-AE9B-C71DFE57C2D0")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace CustomWaveCheat
{
[BepInProcess("ULTRAKILL.exe")]
[BepInPlugin("dev.flazhik.customwavecheat", "CustomWaveCheat", "1.0.1")]
public class CustomWaveCheat : BaseUnityPlugin
{
private static Harmony _harmony;
private void Awake()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
MonoSingleton<AssetsManager>.Instance.LoadAssets();
MonoSingleton<AssetsManager>.Instance.RegisterAssets();
_harmony = new Harmony("dev.flazhik.customwavecheat");
_harmony.PatchAll();
SceneManager.sceneLoaded += delegate
{
if (!(SceneHelper.CurrentScene != "Endless"))
{
MonoSingleton<CheatsManager>.Instance.RegisterCheat((ICheat)(object)new CybergrindWaveOverride(), "cybergrind");
}
};
}
}
internal static class PluginInfo
{
public const string GUID = "dev.flazhik.customwavecheat";
public const string NAME = "CustomWaveCheat";
public const string VERSION = "1.0.1";
}
[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[DebuggerNonUserCode]
[CompilerGenerated]
internal class Resources
{
private static ResourceManager resourceMan;
private static CultureInfo resourceCulture;
[EditorBrowsable(EditorBrowsableState.Advanced)]
internal static ResourceManager ResourceManager
{
get
{
if (resourceMan == null)
{
resourceMan = new ResourceManager("CustomWaveCheat.Resources", typeof(Resources).Assembly);
}
return resourceMan;
}
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
internal static CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
internal static byte[] CgWaveOverride => (byte[])ResourceManager.GetObject("CgWaveOverride", resourceCulture);
internal Resources()
{
}
}
}
namespace CustomWaveCheat.Utils
{
public static class ReflectionUtils
{
private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
public static void CallPrivate<T>(T instance, Type classType, string methodName, object[] args)
{
classType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(instance, args);
}
}
}
namespace CustomWaveCheat.Patches
{
[HarmonyPatch(typeof(CheatsManager))]
public class CheatsManagerPatch
{
[ExternalAsset("Assets/CGWaveOverride/wave-override-icon.png", typeof(Sprite))]
private static Sprite _waveOverrideIcon;
[HarmonyPostfix]
[HarmonyPatch(typeof(CheatsManager), "RebuildIcons")]
public static void CheatsManager_RebuildIcons_Postfix(Dictionary<string, Sprite> ___spriteIcons)
{
if (!((Object)(object)MonoSingleton<IconManager>.Instance == (Object)null) && !((Object)(object)MonoSingleton<IconManager>.Instance.CurrentIcons == (Object)null))
{
___spriteIcons.Add("infinite-wave", _waveOverrideIcon);
}
}
}
[HarmonyPatch(typeof(EndlessGrid))]
public class EndlessGridPatch
{
[HarmonyPrefix]
[HarmonyPatch(typeof(EndlessGrid), "OnTriggerEnter")]
public static void EndlessGrid_OnTriggerEnter_Prefix(EndlessGrid __instance)
{
if (MonoSingleton<CheatsManager>.Instance.GetCheatState("customwave.wave-override"))
{
__instance.startWave = MonoSingleton<PrefsManager>.Instance.GetInt("cyberGrind.startingWave", 0);
}
}
}
[HarmonyPatch(typeof(WaveMenu))]
public class WaveMenuPatch
{
[HarmonyPrefix]
[HarmonyPatch(typeof(WaveMenu), "Start")]
public static void WaveMenu_Start_Postfix(WaveMenu __instance)
{
bool cheatState = MonoSingleton<CheatsManager>.Instance.GetCheatState("customwave.wave-override");
((Component)__instance.customSetter).gameObject.SetActive(__instance.highestWave >= 60 || cheatState);
}
}
[HarmonyPatch(typeof(WaveUtils))]
public class WaveUtilsPatch
{
private static bool OverrideWaveCheatIsActive => MonoSingleton<CheatsManager>.Instance.GetCheatState("customwave.wave-override");
[HarmonyPrefix]
[HarmonyPatch(typeof(WaveUtils), "GetHighestWaveForDifficulty")]
public static bool WaveUtils_GetHighestWaveForDifficulty_Prefix(ref int? __result)
{
if (!OverrideWaveCheatIsActive)
{
return true;
}
__result = int.MaxValue;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(WaveUtils), "IsWaveSelectable")]
public static bool WaveUtils_IsWaveSelectable_Prefix(ref bool __result)
{
if (!OverrideWaveCheatIsActive)
{
return true;
}
__result = true;
return false;
}
}
}
namespace CustomWaveCheat.Cheats
{
public class CybergrindWaveOverride : ICheat
{
public const string Id = "customwave.wave-override";
public string LongName => "Override Cybergrind Wave";
public string Identifier => "customwave.wave-override";
public string ButtonEnabledOverride => null;
public string ButtonDisabledOverride => null;
public string Icon => "infinite-wave";
public bool DefaultState => false;
public StatePersistenceMode PersistenceMode => (StatePersistenceMode)1;
public bool IsActive { get; private set; }
public void Enable(CheatsManager manager)
{
IsActive = true;
ToggleCheat();
}
public void Disable()
{
IsActive = false;
ToggleCheat();
}
public IEnumerator Coroutine(CheatsManager manager)
{
while (IsActive)
{
yield return null;
}
}
private static void ToggleCheat()
{
WaveMenu val = Object.FindObjectOfType<WaveMenu>();
if ((Object)(object)val != (Object)null)
{
ReflectionUtils.CallPrivate<WaveMenu>(val, typeof(WaveMenu), "Start", new object[0]);
}
}
}
}
namespace CustomWaveCheat.Assets
{
public class AssetsManager : MonoSingleton<AssetsManager>
{
private const BindingFlags Flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
private AssetBundle bundle;
public void LoadAssets()
{
bundle = AssetBundle.LoadFromMemory(Resources.CgWaveOverride);
}
public void RegisterAssets()
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
foreach (Type type in types)
{
CheckType(type);
}
}
private void CheckType(IReflect type)
{
type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).ToList().ForEach(ProcessField);
}
private void ProcessField(FieldInfo field)
{
if (!field.FieldType.IsArray && typeof(Object).IsAssignableFrom(field.FieldType) && field.IsStatic)
{
ExternalAsset customAttribute = field.GetCustomAttribute<ExternalAsset>();
if (customAttribute != null)
{
field.SetValue(null, bundle.LoadAsset(customAttribute.Path, customAttribute.Type));
}
}
}
}
[AttributeUsage(AttributeTargets.Field)]
public class ExternalAsset : Attribute
{
public string Path { get; }
public Type Type { get; }
public ExternalAsset(string path, Type type)
{
Path = path;
Type = type;
}
}
}