using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using SpongePEAK.Cheats.Features;
using SpongePEAK.Cheats.Spawning;
using SpongePEAK.Cheats.UI;
using SpongePEAK.Core.Logging;
using SpongePEAK.Core.Patching;
using SpongePEAK.Lib.Features;
using SpongePEAK.Lib.Items;
using SpongePEAK.Lib.Plugin;
using SpongePEAK.Lib.UI;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Zorro.Core;
[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("sponge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) sponge")]
[assembly: AssemblyDescription("Item spawner and testing tools. Off by default.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ddcbf023fcb4c2065ad9b038910633cd4a3a93b0")]
[assembly: AssemblyProduct("SpongePEAKCheats")]
[assembly: AssemblyTitle("com.sponge.peakcheats")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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 SpongePEAK.Cheats
{
[BepInPlugin("com.sponge.peakcheats", "SpongePEAKCheats", "1.0.0")]
public sealed class CheatsPlugin : SpongePlugin
{
public const string Guid = "com.sponge.peakcheats";
private FeatureRegistry _registry;
private ItemSpawnerFeature _spawner;
protected override string DisplayName => "SpongePEAKCheats";
protected override void OnLoad()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
_registry = new FeatureRegistry(((BaseUnityPlugin)this).Config, ((SpongePlugin)this).Log);
_spawner = new ItemSpawnerFeature();
_spawner.Configure(((BaseUnityPlugin)this).Config);
_registry.Register((ModFeature)(object)_spawner);
_registry.EnableAll(((SpongePlugin)this).Patches);
}
private void Update()
{
if (_spawner != null && ((ModFeature)_spawner).IsActive)
{
_spawner.Tick();
}
}
protected override void OnUnload()
{
_spawner?.Cleanup();
}
}
}
namespace SpongePEAK.Cheats.UI
{
public sealed class SpawnerWindow
{
private readonly ItemSpawner _spawner;
private readonly ModLog _log;
private GameObject _root;
private RectTransform _content;
private ScrollRect _scroll;
private TMP_InputField _search;
private TextMeshProUGUI _status;
private ModalCursorWindow _modal;
private readonly List<GameObject> _rows = new List<GameObject>();
private IReadOnlyList<SpawnableItem> _results = Array.Empty<SpawnableItem>();
private string _lastQuery;
public bool IsOpen { get; private set; }
public SpawnerWindow(ItemSpawner spawner, ModLog log)
{
_spawner = spawner;
_log = log;
}
public void Toggle()
{
if (IsOpen)
{
Close();
}
else if (!((Object)(object)_root == (Object)null) || Build())
{
IsOpen = true;
_root.SetActive(true);
Refilter(force: true);
ApplyCursor();
if ((Object)(object)_search != (Object)null)
{
_search.text = string.Empty;
_search.ActivateInputField();
}
}
}
public void Close()
{
if (IsOpen)
{
IsOpen = false;
if ((Object)(object)_root != (Object)null)
{
_root.SetActive(false);
}
ApplyCursor();
}
}
public void Tick()
{
if (IsOpen && (Object)(object)_search != (Object)null && _search.text != _lastQuery)
{
Refilter();
}
}
private bool Build()
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Expected O, but got Unknown
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
try
{
_root = new GameObject("SpongeUI_Spawner", new Type[3]
{
typeof(Canvas),
typeof(CanvasScaler),
typeof(GraphicRaycaster)
});
Object.DontDestroyOnLoad((Object)(object)_root);
Canvas component = _root.GetComponent<Canvas>();
component.renderMode = (RenderMode)0;
component.sortingOrder = 500;
CanvasScaler component2 = _root.GetComponent<CanvasScaler>();
component2.uiScaleMode = (ScaleMode)1;
component2.referenceResolution = new Vector2(1920f, 1080f);
component2.matchWidthOrHeight = 0.5f;
RectTransform val = NewRect("Panel", _root.transform);
val.anchorMin = new Vector2(0.5f, 0.5f);
val.anchorMax = new Vector2(0.5f, 0.5f);
val.pivot = new Vector2(0.5f, 0.5f);
val.sizeDelta = new Vector2(620f, 760f);
val.anchoredPosition = Vector2.zero;
((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0.13f, 0.1f, 0.07f, 0.96f);
AddTitle(val);
AddSearch(val);
AddList(val);
AddFooter(val);
_modal = _root.AddComponent<ModalCursorWindow>();
_modal.SetLogger(_log);
_modal.Closed = delegate
{
IsOpen = false;
if ((Object)(object)_root != (Object)null)
{
_root.SetActive(false);
}
};
_root.SetActive(false);
return true;
}
catch (Exception ex)
{
ModLog log = _log;
if (log != null)
{
log.Exception("Could not build the spawner window", ex);
}
_root = null;
return false;
}
}
private void AddTitle(RectTransform panel)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
RectTransform obj = NewRect("Title", (Transform)(object)panel);
obj.anchorMin = new Vector2(0f, 1f);
obj.anchorMax = new Vector2(1f, 1f);
obj.pivot = new Vector2(0.5f, 1f);
obj.sizeDelta = new Vector2(-40f, 44f);
obj.anchoredPosition = new Vector2(0f, -14f);
TextMeshProUGUI obj2 = ((Component)obj).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)obj2).text = "ITEM SPAWNER";
((TMP_Text)obj2).fontSize = 28f;
((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
((Graphic)obj2).color = new Color(0.98f, 0.86f, 0.55f);
Inherit(obj2);
}
private void AddSearch(RectTransform panel)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
RectTransform val = NewRect("Search", (Transform)(object)panel);
val.anchorMin = new Vector2(0f, 1f);
val.anchorMax = new Vector2(1f, 1f);
val.pivot = new Vector2(0.5f, 1f);
val.sizeDelta = new Vector2(-48f, 46f);
val.anchoredPosition = new Vector2(0f, -66f);
((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0.05f, 0.04f, 0.03f, 0.95f);
RectTransform val2 = NewRect("TextArea", (Transform)(object)val, typeof(RectMask2D));
Fill(val2, 10f);
RectTransform obj = NewRect("Text", (Transform)(object)val2);
Fill(obj, 0f);
TextMeshProUGUI val3 = ((Component)obj).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)val3).fontSize = 20f;
((TMP_Text)val3).alignment = (TextAlignmentOptions)4097;
((Graphic)val3).color = Color.white;
Inherit(val3);
RectTransform obj2 = NewRect("Placeholder", (Transform)(object)val2);
Fill(obj2, 0f);
TextMeshProUGUI val4 = ((Component)obj2).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)val4).text = "Search items...";
((TMP_Text)val4).fontSize = 20f;
((TMP_Text)val4).alignment = (TextAlignmentOptions)4097;
((Graphic)val4).color = new Color(1f, 1f, 1f, 0.35f);
Inherit(val4);
_search = ((Component)val).gameObject.AddComponent<TMP_InputField>();
_search.textViewport = val2;
_search.textComponent = (TMP_Text)(object)val3;
_search.placeholder = (Graphic)(object)val4;
_search.caretColor = Color.white;
}
private void AddList(RectTransform panel)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
RectTransform val = NewRect("List", (Transform)(object)panel);
val.anchorMin = new Vector2(0f, 0f);
val.anchorMax = new Vector2(1f, 1f);
val.offsetMin = new Vector2(24f, 64f);
val.offsetMax = new Vector2(-24f, -122f);
_content = val;
_scroll = ScrollableList.Ensure((Transform)(object)_content, _log, 3f);
}
private void AddFooter(RectTransform panel)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
RectTransform val = NewRect("Status", (Transform)(object)panel);
val.anchorMin = new Vector2(0f, 0f);
val.anchorMax = new Vector2(1f, 0f);
val.pivot = new Vector2(0.5f, 0f);
val.sizeDelta = new Vector2(-40f, 28f);
val.anchoredPosition = new Vector2(0f, 30f);
_status = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)_status).fontSize = 16f;
((TMP_Text)_status).alignment = (TextAlignmentOptions)514;
((Graphic)_status).color = new Color(1f, 1f, 1f, 0.5f);
Inherit(_status);
RectTransform val2 = NewRect("Close", (Transform)(object)panel);
val2.anchorMin = new Vector2(1f, 0f);
val2.anchorMax = new Vector2(1f, 0f);
val2.pivot = new Vector2(1f, 0f);
val2.sizeDelta = new Vector2(120f, 34f);
val2.anchoredPosition = new Vector2(-24f, -2f);
PeakStyle.CreateButton("CLOSE", (Transform)(object)val2, (Action)Close);
}
private void Refilter(bool force = false)
{
string text = (((Object)(object)_search != (Object)null) ? _search.text : string.Empty);
if (!force && text == _lastQuery)
{
return;
}
_lastQuery = text;
_results = _spawner.Search(text);
for (int i = 0; i < _results.Count; i++)
{
GameObject val = ((i < _rows.Count) ? _rows[i] : CreateRow());
if (!((Object)(object)val == (Object)null))
{
int index = i;
SpawnableItem item = _results[i];
val.SetActive(true);
SetRowLabel(val, item);
Rebind(val, delegate
{
OnSpawn(index);
});
}
}
for (int num = _results.Count; num < _rows.Count; num++)
{
_rows[num].SetActive(false);
}
UpdateStatus();
ScrollableList.Refresh(_scroll);
}
private GameObject CreateRow()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
try
{
RectTransform val = NewRect($"Row{_rows.Count}", (Transform)(object)_content);
val.sizeDelta = new Vector2(0f, 34f);
LayoutElement obj = ((Component)val).gameObject.AddComponent<LayoutElement>();
obj.preferredHeight = 34f;
obj.minHeight = 34f;
Button val2 = PeakStyle.CreateButton("item", (Transform)(object)val, (Action)null);
if ((Object)(object)val2 != (Object)null)
{
RectTransform component = ((Component)val2).GetComponent<RectTransform>();
if ((Object)(object)component != (Object)null)
{
Fill(component, 0f);
}
}
_rows.Add(((Component)val).gameObject);
return ((Component)val).gameObject;
}
catch (Exception ex)
{
ModLog log = _log;
if (log != null)
{
log.Exception("Could not create a spawner row", ex);
}
return null;
}
}
private static void SetRowLabel(GameObject row, SpawnableItem item)
{
TextMeshProUGUI componentInChildren = row.GetComponentInChildren<TextMeshProUGUI>(true);
if (!((Object)(object)componentInChildren == (Object)null))
{
((TMP_Text)componentInChildren).text = (item.DisplayName.Equals(item.PrefabName, StringComparison.OrdinalIgnoreCase) ? item.DisplayName : (item.DisplayName + " <color=#FFFFFF60>" + item.PrefabName + "</color>"));
((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)4097;
((TMP_Text)componentInChildren).fontSize = 17f;
}
}
private static void Rebind(GameObject row, Action onClick)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
Button componentInChildren = row.GetComponentInChildren<Button>(true);
if (!((Object)(object)componentInChildren == (Object)null))
{
((UnityEventBase)componentInChildren.onClick).RemoveAllListeners();
((UnityEvent)componentInChildren.onClick).AddListener((UnityAction)delegate
{
onClick();
});
}
}
private void OnSpawn(int index)
{
if (index >= 0 && index < _results.Count)
{
SpawnableItem spawnableItem = _results[index];
if (!_spawner.IsAvailable)
{
SetStatus("Cannot spawn right now: not in a run.");
}
else
{
SetStatus(_spawner.Spawn(spawnableItem.PrefabName) ? ("Spawned " + spawnableItem.DisplayName) : ("Failed to spawn " + spawnableItem.DisplayName));
}
}
}
private void UpdateStatus()
{
if ((Object)(object)_status == (Object)null)
{
return;
}
int count = _spawner.All().Count;
if (count == 0)
{
SetStatus("No items found. Start a run first; the database loads with the level.");
return;
}
if (_results.Count == 0)
{
SetStatus($"Nothing matches that. {count} items available.");
return;
}
int count2 = ItemCloner.BuiltItems.Count;
int pendingCount = ItemCloner.PendingCount;
if (count2 > 0)
{
SetStatus($"{_results.Count} of {count} items ({count2} custom)");
}
else if (pendingCount > 0)
{
SetStatus($"{_results.Count} of {count} items ({pendingCount} custom registered but not built yet)");
}
else
{
SetStatus($"{_results.Count} of {count} items (no custom items registered)");
}
}
private void SetStatus(string message)
{
if ((Object)(object)_status != (Object)null)
{
((TMP_Text)_status).text = message;
}
}
private void ApplyCursor()
{
ModalCursorWindow modal = _modal;
if (modal != null)
{
modal.SetOpen(IsOpen);
}
}
private static RectTransform NewRect(string name, Transform parent, params Type[] extra)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
List<Type> list = new List<Type> { typeof(RectTransform) };
list.AddRange(extra);
RectTransform component = new GameObject(name, list.ToArray()).GetComponent<RectTransform>();
((Transform)component).SetParent(parent, false);
return component;
}
private static void Fill(RectTransform rect, float padding)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.offsetMin = new Vector2(padding, padding);
rect.offsetMax = new Vector2(0f - padding, 0f - padding);
}
private static void Inherit(TextMeshProUGUI text)
{
GameObject buttonTemplate = PeakStyle.ButtonTemplate;
if (!((Object)(object)buttonTemplate == (Object)null))
{
TextMeshProUGUI componentInChildren = buttonTemplate.GetComponentInChildren<TextMeshProUGUI>(true);
if ((Object)(object)((componentInChildren != null) ? ((TMP_Text)componentInChildren).font : null) != (Object)null)
{
((TMP_Text)text).font = ((TMP_Text)componentInChildren).font;
}
}
}
}
}
namespace SpongePEAK.Cheats.Spawning
{
public sealed class ItemSpawner
{
private readonly ModLog _log;
private static readonly MethodInfo SpawnInHand = typeof(CharacterItems).GetMethod("SpawnItemInHand", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
public bool IsAvailable
{
get
{
if (SpawnInHand != null && (Object)(object)Character.localCharacter != (Object)null)
{
return PhotonNetwork.InRoom;
}
return false;
}
}
public ItemSpawner(ModLog log)
{
_log = log;
}
public IReadOnlyList<SpawnableItem> All()
{
ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
if (instance?.itemLookup == null)
{
return Array.Empty<SpawnableItem>();
}
return (from item in instance.itemLookup.Values
where (Object)(object)item != (Object)null
select new SpawnableItem(((Object)item).name, item.UIData?.itemName ?? ((Object)item).name, item.itemID)).OrderBy<SpawnableItem, string>((SpawnableItem entry) => entry.DisplayName, StringComparer.OrdinalIgnoreCase).ThenBy<SpawnableItem, string>((SpawnableItem entry) => entry.PrefabName, StringComparer.OrdinalIgnoreCase).ToList();
}
public IReadOnlyList<SpawnableItem> Search(string query)
{
IReadOnlyList<SpawnableItem> readOnlyList = All();
if (string.IsNullOrWhiteSpace(query))
{
return readOnlyList;
}
return readOnlyList.Where((SpawnableItem entry) => entry.DisplayName.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0 || entry.PrefabName.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
}
public bool Spawn(string prefabName)
{
if (string.IsNullOrWhiteSpace(prefabName))
{
return false;
}
if (SpawnInHand == null)
{
ModLog log = _log;
if (log != null)
{
log.Warning((object)"CharacterItems.SpawnItemInHand not found; the game may have changed.");
}
return false;
}
Character localCharacter = Character.localCharacter;
if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.refs?.items == (Object)null)
{
ModLog log2 = _log;
if (log2 != null)
{
log2.Warning((object)"Cannot spawn: no local character.");
}
return false;
}
if (!PhotonNetwork.InRoom)
{
ModLog log3 = _log;
if (log3 != null)
{
log3.Warning((object)"Cannot spawn: not in a room.");
}
return false;
}
try
{
SpawnInHand.Invoke(localCharacter.refs.items, new object[1] { prefabName });
ModLog log4 = _log;
if (log4 != null)
{
log4.Info((object)("Spawned '" + prefabName + "'."));
}
return true;
}
catch (Exception ex)
{
ModLog log5 = _log;
if (log5 != null)
{
log5.Exception("Failed to spawn '" + prefabName + "'", ex);
}
return false;
}
}
}
public readonly struct SpawnableItem
{
public string PrefabName { get; }
public string DisplayName { get; }
public ushort Id { get; }
public SpawnableItem(string prefabName, string displayName, ushort id)
{
PrefabName = prefabName;
DisplayName = displayName;
Id = id;
}
}
}
namespace SpongePEAK.Cheats.Features
{
public sealed class ItemSpawnerFeature : ModFeature
{
private ConfigEntry<KeyCode> _hotkey;
private SpawnerWindow _window;
private ModLog _log;
public override string Name => "ItemSpawner";
public override string Description => "Opens a searchable list of every item, vanilla and custom, and spawns them into your hands.";
public override string Replaces => "ItemSpawnerEnhanced";
public override bool DefaultEnabled => true;
public override string Section => "Cheats";
public void Configure(ConfigFile config)
{
_hotkey = config.Bind<KeyCode>("Cheats", "SpawnerHotkey", (KeyCode)284, "Key that opens the item spawner.");
}
protected override void OnEnable(PatchHost patches, ModLog log)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
_log = log;
_window = new SpawnerWindow(new ItemSpawner(log), log);
ConfigEntry<KeyCode> hotkey = _hotkey;
log.Info((object)$"Item spawner ready; press {(object)(KeyCode)((hotkey == null) ? 284 : ((int)hotkey.Value))} to open it.");
}
public void Tick()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
if (_window != null)
{
ConfigEntry<KeyCode> hotkey = _hotkey;
if (Input.GetKeyDown((KeyCode)((hotkey == null) ? 284 : ((int)hotkey.Value))))
{
_window.Toggle();
}
_window.Tick();
}
}
public void Cleanup()
{
_window?.Close();
}
}
}