Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ItemConjurer v2.3.1
plugins/item_conjurer/ItemConjurer.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using ItemConjurer.Core.Application.Queries; using ItemConjurer.Core.Application.Repository; using ItemConjurer.Core.Application.Services; using ItemConjurer.Core.Application.Services.Discovery; using ItemConjurer.Core.Application.Services.Discovery.Strategies; using ItemConjurer.Core.Domain.Abstractions; using ItemConjurer.Core.Domain.Adapters; using ItemConjurer.Core.Domain.Models; using ItemConjurer.Core.Infrastructure.Bootstrap; using ItemConjurer.Core.Infrastructure.Bootstrap.Modules; using ItemConjurer.Core.Infrastructure.Constants; using ItemConjurer.Core.Infrastructure.DI; using ItemConjurer.Core.Infrastructure.Game; using ItemConjurer.Core.Infrastructure.Logging; using ItemConjurer.Core.Infrastructure.Network; using ItemConjurer.Core.Infrastructure.Utils; using ItemConjurer.Data; using ItemConjurer.Features.Spawning.Services; using ItemConjurer.Features.Spawning.Spawners; using ItemConjurer.Features.UI.Components; using ItemConjurer.Features.UI.Controllers; using ItemConjurer.Features.UI.Styles; using ItemConjurer.Features.UI.Tabs; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Photon.Pun; using REPOLib; using REPOLib.Extensions; using REPOLib.Modules; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.0.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ItemConjurer.Plugin { [BepInPlugin("ItemConjurer", "Item Conjurer", "2.1.0")] public class ItemConjurerPlugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <DelayedUISetup>d__4 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedUISetup>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; ConjurerUIController conjurerUIController = Object.FindObjectOfType<ConjurerUIController>(); IServiceContainer container = ServiceBootstrapper.Instance.Container; ILogService logService = container.ResolveOrDefault<ILogService>(); if ((Object)(object)conjurerUIController != (Object)null) { logService?.Log(LogLevel.Debug, "[ItemConjurerPlugin] Found ConjurerUIController, initializing..."); container.Register(conjurerUIController); conjurerUIController.Initialize(container); logService?.Log(LogLevel.Info, "[ItemConjurerPlugin] UI controller initialized successfully"); } else { logService?.Log(LogLevel.Warning, "[ItemConjurerPlugin] ConjurerUIController not found in scene"); } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Harmony _harmony; private const string LogPrefix = "[ItemConjurerPlugin]"; private void Awake() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown try { ServiceBootstrapper.Instance.Initialize(discover: false); BundleLoader.OnAllBundlesLoaded += OnAllBundlesLoaded; ILogService logService = ServiceBootstrapper.Instance.Container.Resolve<ILogService>(); logService.Log(LogLevel.Info, "[ItemConjurerPlugin] Plugin loading..."); _harmony = new Harmony("ItemConjurer"); _harmony.PatchAll(); logService.Log(LogLevel.Info, "[ItemConjurerPlugin] Plugin loaded successfully!"); } catch (Exception ex) { Debug.LogError((object)("[ItemConjurerPlugin] Critical error during initialization: " + ex.Message)); } } private void OnAllBundlesLoaded() { BundleLoader.OnAllBundlesLoaded -= OnAllBundlesLoaded; ILogService logService = ServiceBootstrapper.Instance.Container.ResolveOrDefault<ILogService>(); logService?.Log(LogLevel.Info, "[ItemConjurerPlugin] All bundles loaded — performing discovery and UI setup"); try { ServiceBootstrapper.Instance.RunDiscovery(); CoroutineRunner.Run(DelayedUISetup()); } catch (Exception ex) { logService?.Log(LogLevel.Error, "[ItemConjurerPlugin] Critical error in OnAllBundlesLoaded: " + ex.Message); } } [IteratorStateMachine(typeof(<DelayedUISetup>d__4))] private IEnumerator DelayedUISetup() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedUISetup>d__4(0); } } public static class PluginInfo { public const string PLUGIN_GUID = "ItemConjurer"; public const string PLUGIN_NAME = "Item Conjurer"; public const string PLUGIN_VERSION = "2.1.0"; } } namespace ItemConjurer.Plugin.Patches { [HarmonyPatch(typeof(ShopManager), "Awake")] public static class ShopManagerPatch { private const string LogPrefix = "[ShopManagerPatch]"; [HarmonyPostfix] private static void Postfix(ShopManager __instance) { if ((Object)(object)__instance == (Object)null) { Debug.LogWarning((object)"[ShopManagerPatch] Skipping patch: ShopManager instance is null"); return; } if (!((Component)__instance).gameObject.activeInHierarchy) { Debug.LogWarning((object)"[ShopManagerPatch] Skipping patch: GameObject inactive in hierarchy"); return; } IServiceContainer container = ServiceBootstrapper.Instance.Container; ILogService logService = null; try { logService = container.Resolve<ILogService>(); } catch { Debug.LogWarning((object)"[ShopManagerPatch] Could not resolve ILogService from DI container"); } if ((Object)(object)((Component)__instance).gameObject.GetComponent<ConjurerUIController>() != (Object)null) { logService?.Log(LogLevel.Debug, "[ShopManagerPatch] ConjurerUIController already attached"); return; } ConjurerUIController conjurerUIController = ((Component)__instance).gameObject.AddComponent<ConjurerUIController>(); container.Register(conjurerUIController); conjurerUIController.Initialize(container); logService?.Log(LogLevel.Info, "[ShopManagerPatch] ConjurerUIController injected into ShopManager"); } } } namespace ItemConjurer.Features.UI.Tabs { public class SpawnTab { private const int QTY_BUTTON_WIDTH = 25; private const int QTY_BUTTON_HEIGHT = 25; private const int QTY_DISPLAY_WIDTH = 45; private const int SPAWN_BUTTON_WIDTH = 90; private const int LABEL_WIDTH = 35; private readonly SpawnableType _type; private readonly ISpawner _spawner; private readonly SpawnableList _spawnableList; private readonly ISpawnHistoryService _historyService; private readonly ILogService _logger; private readonly float _defaultDelay; private string _selectedItem; private int _currentAmount = 1; private readonly int _maxAmount = 10; private GUIStyle _quantityStyle; public string TabName => _type.ToString(); public SpawnTab(SpawnableType type, SpawnableFinder finder, ISpawnHistoryService historyService, ISpawnableRepository repository, ISpawner spawner, ILogService logger, int defaultAmount, float defaultDelay) { _type = type; _spawner = Guard.Against.Null(spawner, "spawner"); _historyService = Guard.Against.Null(historyService, "historyService"); _logger = Guard.Against.Null(logger, "logger"); _defaultDelay = defaultDelay; _spawnableList = new SpawnableList(Guard.Against.Null(finder, "finder"), _historyService, Guard.Against.Null(repository, "repository"), _logger, type, OnItemSelected); _currentAmount = defaultAmount; _maxAmount = ((type == SpawnableType.Enemy) ? 50 : 50); } public void Draw() { GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); DrawHeader(); _spawnableList.Draw(); DrawDivider(); if (!string.IsNullOrEmpty(_selectedItem)) { DrawControls(); } else { DrawEmptyMessage(); } GUILayout.EndVertical(); } private void DrawHeader() { GUILayout.Space(5f); GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); GUILayout.Label($"[Spawner] for {_type}", StyleProvider.GetStyle("headerLabel"), Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); GUILayout.Space(5f); } private void DrawDivider() { GUILayout.Space(10f); } private void DrawControls() { GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); DrawSelectionHeader(); GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); DrawQuantityControls(); DrawDelayInfo(); GUILayout.EndVertical(); GUILayout.EndVertical(); } private void DrawSelectionHeader() { GUILayout.Label("✓ Selected: " + _selectedItem, StyleProvider.GetStyle("headerLabel"), Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); } private void DrawQuantityControls() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Qty:", StyleProvider.GetStyle("label"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) }); GUILayout.Space(2f); if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(25f), GUILayout.Height(25f) })) { DecrementQuantity(); } DrawQuantityDisplay(); if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(25f), GUILayout.Height(25f) })) { IncrementQuantity(); } GUILayout.FlexibleSpace(); if (GUILayout.Button("Spawn", StyleProvider.GetStyle("actionButton"), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(90f), GUILayout.Height(25f) })) { OnQuickSpawn(); } GUILayout.EndHorizontal(); } private void DrawQuantityDisplay() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (_quantityStyle == null) { _quantityStyle = new GUIStyle(StyleProvider.GetStyle("label")); _quantityStyle.normal.background = CreateSingleColorTexture(new Color(0.08f, 0.08f, 0.1f)); _quantityStyle.fontSize = 14; _quantityStyle.padding = new RectOffset(12, 12, 6, 6); } GUILayout.Box(_currentAmount.ToString(), _quantityStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(45f), GUILayout.Height(23f) }); } private void DrawDelayInfo() { GUILayout.Space(4f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($"Delay: {_defaultDelay:F2}s", StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); } private void IncrementQuantity() { _currentAmount = Mathf.Min(_maxAmount, _currentAmount + 1); } private void DecrementQuantity() { _currentAmount = Mathf.Max(1, _currentAmount - 1); } private static Texture2D CreateSingleColorTexture(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, color); val.Apply(); return val; } private void DrawEmptyMessage() { GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); GUILayout.Label("Info: Select an item to access spawn options.", StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); } private void OnItemSelected(string name) { _selectedItem = name; _historyService.AddRecentItem(_type, name); SpawnSelectedItem(1); } private void OnQuickSpawn() { if (!string.IsNullOrEmpty(_selectedItem)) { SpawnSelectedItem(_currentAmount); } } private void SpawnSelectedItem(int amount) { _spawner.Spawn(_selectedItem, amount, _defaultDelay); } public void UpdateDefaults(int amount) { int currentAmount = Mathf.Clamp(amount, 1, _maxAmount); _currentAmount = currentAmount; } } } namespace ItemConjurer.Features.UI.Styles { public static class StyleProvider { private static readonly Dictionary<string, GUIStyle> _styles = new Dictionary<string, GUIStyle>(); private static readonly Dictionary<string, Texture2D> _textures = new Dictionary<string, Texture2D>(); private static bool _initialized = false; public static void Initialize() { //IL_002c: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Expected O, but got Unknown //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Expected O, but got Unknown //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Expected O, but got Unknown //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Expected O, but got Unknown //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Expected O, but got Unknown //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Expected O, but got Unknown //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Expected O, but got Unknown //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Expected O, but got Unknown //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Expected O, but got Unknown //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Expected O, but got Unknown //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Expected O, but got Unknown //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Expected O, but got Unknown //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Expected O, but got Unknown //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04c7: Expected O, but got Unknown //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Expected O, but got Unknown //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_0504: Expected O, but got Unknown //IL_051f: Unknown result type (might be due to invalid IL or missing references) //IL_0526: Expected O, but got Unknown //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_0550: Expected O, but got Unknown //IL_0563: Unknown result type (might be due to invalid IL or missing references) //IL_056a: Expected O, but got Unknown //IL_0571: Unknown result type (might be due to invalid IL or missing references) //IL_059f: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Expected O, but got Unknown //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_05f3: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Expected O, but got Unknown //IL_0621: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_0631: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Expected O, but got Unknown if (!_initialized) { _initialized = true; _textures["windowBg"] = CreateColorTexture(new Color(0.12f, 0.12f, 0.14f, 0.95f)); _textures["controlBg"] = CreateColorTexture(ConjurerConstants.Colors.ControlBackgroundColor); _textures["fieldBg"] = CreateColorTexture(ConjurerConstants.Colors.ControlFieldBackground); _textures["tabSelected"] = CreateColorTexture(ConjurerConstants.Colors.TabSelected); _textures["categoryNormal"] = CreateColorTexture(ConjurerConstants.Colors.CategoryButtonNormal); _textures["categorySelected"] = CreateColorTexture(new Color(0.15f, 0.7f, 0.25f)); _textures["itemNormal"] = CreateColorTexture(ConjurerConstants.Colors.ItemNormal); _textures["itemAlt"] = CreateColorTexture(ConjurerConstants.Colors.ItemAlternate); _textures["itemHover"] = CreateColorTexture(ConjurerConstants.Colors.ItemHover); _textures["spawnButton"] = CreateColorTexture(ConjurerConstants.Colors.SpawnButtonColor); _textures["spawnButtonHover"] = CreateColorTexture(ConjurerConstants.Colors.SpawnButtonHover); GUIStyle val = new GUIStyle(GUI.skin.window); val.normal.background = _textures["windowBg"]; val.normal.textColor = Color.white; val.fontSize = 15; val.padding = new RectOffset(10, 10, 25, 10); _styles["window"] = val; GUIStyle val2 = new GUIStyle(GUI.skin.button); val2.normal.textColor = ConjurerConstants.Colors.TextBright; val2.padding = new RectOffset(12, 12, 8, 8); val2.fixedHeight = 29f; val2.fontSize = 13; val2.margin = new RectOffset(2, 2, 0, 0); _styles["tab"] = val2; GUIStyle val3 = new GUIStyle(val2); val3.normal.background = _textures["tabSelected"]; val3.normal.textColor = Color.white; _styles["activeTab"] = val3; GUIStyle val4 = new GUIStyle(GUI.skin.button); val4.normal.background = _textures["categoryNormal"]; val4.normal.textColor = ConjurerConstants.Colors.TextBright; val4.padding = new RectOffset(6, 6, 3, 3); val4.margin = new RectOffset(2, 2, 1, 1); val4.fixedHeight = 23f; val4.fontSize = 11; val4.wordWrap = false; val4.clipping = (TextClipping)0; _styles["category"] = val4; GUIStyle val5 = new GUIStyle(val4); val5.normal.background = _textures["categorySelected"]; val5.normal.textColor = Color.white; _styles["categorySelected"] = val5; GUIStyle value = new GUIStyle(val4) { fontSize = 13 }; _styles["allCategory"] = value; GUIStyle value2 = new GUIStyle(val5) { fontSize = 13 }; _styles["allCategorySelected"] = value2; GUIStyle val6 = new GUIStyle(GUI.skin.button); val6.normal.background = _textures["itemNormal"]; val6.normal.textColor = ConjurerConstants.Colors.TextBright; val6.padding = new RectOffset(10, 10, 7, 7); val6.fixedHeight = 30f; val6.fontSize = 12; val6.margin = new RectOffset(0, 0, 1, 1); _styles["item"] = val6; GUIStyle val7 = new GUIStyle(val6); val7.normal.background = _textures["itemAlt"]; _styles["itemAlt"] = val7; GUIStyle val8 = new GUIStyle(val6); val8.normal.background = _textures["itemHover"]; _styles["itemHover"] = val8; GUIStyle val9 = new GUIStyle(GUI.skin.textField); val9.normal.background = _textures["fieldBg"]; val9.normal.textColor = Color.white; val9.padding = new RectOffset(10, 10, 6, 6); val9.fontSize = 13; _styles["search"] = val9; GUIStyle val10 = new GUIStyle(GUI.skin.box); val10.normal.background = _textures["controlBg"]; val10.padding = new RectOffset(10, 10, 8, 8); val10.margin = new RectOffset(0, 0, 5, 5); _styles["box"] = val10; GUIStyle val11 = new GUIStyle(GUI.skin.label); val11.normal.textColor = ConjurerConstants.Colors.TextBright; val11.fontSize = 12; val11.padding = new RectOffset(2, 2, 3, 3); _styles["label"] = val11; GUIStyle val12 = new GUIStyle(val11); val12.normal.textColor = ConjurerConstants.Colors.TextHighlight; val12.fontSize = 14; _styles["headerLabel"] = val12; GUIStyle val13 = new GUIStyle(GUI.skin.button); val13.normal.background = _textures["spawnButton"]; val13.hover.background = _textures["spawnButtonHover"]; val13.normal.textColor = Color.white; val13.padding = new RectOffset(8, 8, 6, 6); val13.fontSize = 13; _styles["actionButton"] = val13; GUIStyle value3 = new GUIStyle(GUI.skin.button) { fixedWidth = 25f, fontSize = 14 }; _styles["starButton"] = value3; _initialized = true; } } public static GUIStyle GetStyle(string styleName) { if (!_initialized) { Initialize(); } if (_styles.TryGetValue(styleName, out var value)) { return value; } Debug.LogWarning((object)("Style '" + styleName + "' not found, returning default")); return GUI.skin.label; } private static Texture2D CreateColorTexture(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, color); val.Apply(); return val; } } } namespace ItemConjurer.Features.UI.Controllers { public class ConjurerUIController : MonoBehaviour { private ILogService _logger; private SpawnConfigProvider _configProvider; private ISpawnableRepository _repository; private SpawnableFinder _finder; private SpawnService _spawnService; private ISpawnHistoryService _historyService; private IServiceContainer _container; private readonly Dictionary<SpawnableType, ISpawner> _spawners = new Dictionary<SpawnableType, ISpawner>(); private Rect _windowRect = new Rect(20f, 20f, 490f, 600f); private int _selectedTab; private readonly List<SpawnTab> _tabs = new List<SpawnTab>(); private ConjurerSettings _config; private bool _uiInitialized; private bool _showHelp; private bool _isCollapsed; private readonly List<string> _logMessages = new List<string>(); private readonly float _messageTimeout = 5f; private float _lastMessageTime; private Vector2 _previousScreenSize; private float _scaleFactor = 1f; public void Initialize(IServiceContainer container) { try { _container = Guard.Against.Null(container, "container"); ResolveServices(); CollectSpawners(); _config = _configProvider.GetConfig(); AdjustWindowSize(); CreateTabs(); _selectedTab = Mathf.Clamp(_config.LastTabIndex, 0, _tabs.Count - 1); _uiInitialized = true; _logger.Log(LogLevel.Info, "ItemConjurer UI initialized successfully"); } catch (Exception ex2) { Exception ex3 = ex2; Exception ex = ex3; _logger?.Log(LogLevel.Error, () => "Error initializing ItemConjurer UI: " + ex.Message); ((Behaviour)this).enabled = false; } } private void ResolveServices() { _logger = Guard.Against.Null(_container.Resolve<ILogService>(), "ILogService"); _repository = Guard.Against.Null(_container.Resolve<ISpawnableRepository>(), "ISpawnableRepository"); _configProvider = Guard.Against.Null(_container.Resolve<SpawnConfigProvider>(), "SpawnConfigProvider"); _finder = Guard.Against.Null(_container.Resolve<SpawnableFinder>(), "SpawnableFinder"); _spawnService = Guard.Against.Null(_container.Resolve<SpawnService>(), "SpawnService"); _historyService = Guard.Against.Null(_container.Resolve<ISpawnHistoryService>(), "ISpawnHistoryService"); } private void AdjustWindowSize() { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) _scaleFactor = Mathf.Clamp((float)Screen.height / 1080f, 0.8f, 1.1f); if (_isCollapsed) { ((Rect)(ref _windowRect)).height = 40f; ((Rect)(ref _windowRect)).width = 220f * _scaleFactor; } else { float num = 390f * _scaleFactor; float num2 = Mathf.Min(450f * _scaleFactor, (float)Screen.width * 0.4f); ((Rect)(ref _windowRect)).width = Mathf.Clamp(490f * _scaleFactor, num, num2); ((Rect)(ref _windowRect)).height = 600f * _scaleFactor; } ((Rect)(ref _windowRect)).x = Mathf.Clamp(((Rect)(ref _windowRect)).x, 0f, (float)Screen.width - ((Rect)(ref _windowRect)).width); ((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, 0f, (float)Screen.height - ((Rect)(ref _windowRect)).height); _previousScreenSize = new Vector2((float)Screen.width, (float)Screen.height); } private void CollectSpawners() { if (_container.TryResolve<EnemySpawner>(out var service)) { _spawners[SpawnableType.Enemy] = service; } if (_container.TryResolve<IEnumerable<ISpawner>>(out var service2)) { foreach (ISpawner item in service2) { if (item is TypedSpawner typedSpawner && !_spawners.ContainsKey(typedSpawner.SpawnableType)) { _spawners[typedSpawner.SpawnableType] = item; } } } foreach (SpawnableType value in Enum.GetValues(typeof(SpawnableType))) { if (!_spawners.ContainsKey(value)) { _spawners[value] = new TypedSpawner(_spawnService, _configProvider, _logger, value); } } } private void CreateTabs() { _tabs.Clear(); foreach (SpawnableType value in Enum.GetValues(typeof(SpawnableType))) { AddTabIfHasItems(value); } if (_tabs.Count == 0) { _logger.Log(LogLevel.Warning, "No tabs created - no spawnables available"); } } private void AddTabIfHasItems(SpawnableType type) { if (_repository.CountByType(type) <= 0 || !_spawners.TryGetValue(type, out var value)) { if (_repository.CountByType(type) > 0) { _logger.Log(LogLevel.Warning, $"No spawner found for type {type}"); } return; } bool num = type == SpawnableType.Enemy; float defaultDelay = (num ? Mathf.Max(_config.SpawnDelay, 1f) : _config.SpawnDelay); int defaultAmount = (num ? Mathf.Min(_config.SpawnAmount, 50) : _config.SpawnAmount); SpawnTab item = new SpawnTab(type, _finder, _historyService, _repository, value, _logger, defaultAmount, defaultDelay); _tabs.Add(item); _logger.Log(LogLevel.Info, () => $"Added tab for {type}"); } private void Update() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!_uiInitialized || _config == null) { return; } Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current.f1Key).wasPressedThisFrame) { _config.IsVisible = !_config.IsVisible; _configProvider.UpdateConfig(delegate(ConjurerSettings c) { c.IsVisible = _config.IsVisible; }); _logger.Log(LogLevel.Debug, () => $"UI visibility toggled to {_config.IsVisible}"); } if (_previousScreenSize != Vector2.zero && (Mathf.Abs(_previousScreenSize.x - (float)Screen.width) > 100f || Mathf.Abs(_previousScreenSize.y - (float)Screen.height) > 100f)) { AdjustWindowSize(); } } private void OnGUI() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (_uiInitialized && _config.IsVisible) { StyleProvider.Initialize(); _windowRect = GUILayout.Window(6969, _windowRect, new WindowFunction(DrawWindow), "Item Conjurer", StyleProvider.GetStyle("window"), Array.Empty<GUILayoutOption>()); if (_logMessages.Count > 0) { DrawMessages(); } } } private void DrawWindow(int windowID) { if (_isCollapsed) { if (GUILayout.Button("▼ Expand Item Conjurer", StyleProvider.GetStyle("actionButton"), Array.Empty<GUILayoutOption>())) { ToggleCollapseState(); } } else { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("▲", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) })) { ToggleCollapseState(); } GUILayout.Label("Item Conjurer", StyleProvider.GetStyle("headerLabel"), Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(5f); DrawTabs(); if (_tabs.Count > 0 && _selectedTab >= 0 && _selectedTab < _tabs.Count) { _tabs[_selectedTab].Draw(); } else { GUILayout.Label("No tabs available.", StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); } DrawStatusBar(); } HandleDrag(windowID); } private void ToggleCollapseState() { _isCollapsed = !_isCollapsed; AdjustWindowSize(); } private void DrawTabs() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); int i; for (i = 0; i < _tabs.Count; i++) { bool flag = _selectedTab == i; GUIStyle style = StyleProvider.GetStyle(flag ? "activeTab" : "tab"); if (GUILayout.Button(_tabs[i].TabName, style, Array.Empty<GUILayoutOption>()) && !flag) { _selectedTab = i; _configProvider.UpdateConfig(delegate(ConjurerSettings c) { c.LastTabIndex = _selectedTab; }); _logger.Log(LogLevel.Debug, () => "Tab changed to " + _tabs[i].TabName); } } GUILayout.EndHorizontal(); GUILayout.Space(10f); } private void DrawStatusBar() { GUILayout.Space(5f); GUILayout.BeginHorizontal(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); int num = _repository.CountByType(SpawnableType.Item); int num2 = _repository.CountByType(SpawnableType.Valuable); int num3 = _repository.CountByType(SpawnableType.Enemy); GUILayout.Label($"Loaded: {num} Items | {num2} Valuables | {num3} Enemies", StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (GUILayout.Button("?", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(25f) })) { _showHelp = !_showHelp; } GUILayout.EndHorizontal(); if (_showHelp) { GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); GUILayout.Label("• F1: Toggle UI visibility", StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); GUILayout.Label("• Star icon: Add item to favorites", StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); GUILayout.Label("• Click item: Spawn one instance", StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); GUILayout.Space(2f); GUILayout.EndVertical(); } } public void ShowMessage(string message) { _logMessages.Add(message); _lastMessageTime = Time.time; if (_logMessages.Count > 3) { _logMessages.RemoveAt(0); } _logger.Log(LogLevel.Info, message); } private void DrawMessages() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (Time.time - _lastMessageTime < _messageTimeout) { GUILayout.BeginArea(new Rect(10f, (float)(Screen.height - 100), 300f, 90f)); foreach (string logMessage in _logMessages) { GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); GUILayout.Label(logMessage, StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); } GUILayout.EndArea(); } else { _logMessages.Clear(); } } private void HandleDrag(int windowID) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) Rect lastRect = GUILayoutUtility.GetLastRect(); Rect val = default(Rect); ((Rect)(ref val))..ctor(0f, 0f, ((Rect)(ref _windowRect)).width, ((Rect)(ref _windowRect)).height); float num = ((Rect)(ref val)).height - ((Rect)(ref lastRect)).yMax; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, ((Rect)(ref lastRect)).yMax, ((Rect)(ref val)).width, num); if ((int)Event.current.type == 0 && ((Rect)(ref val2)).Contains(Event.current.mousePosition)) { GUI.FocusControl((string)null); } GUI.DragWindow(val); } private void OnDestroy() { if (_configProvider != null && _selectedTab >= 0) { _configProvider.UpdateConfig(delegate(ConjurerSettings c) { c.LastTabIndex = _selectedTab; }); _logger?.Log(LogLevel.Debug, "Configuration saved on controller destroy"); } } } } namespace ItemConjurer.Features.UI.Components { public class SpawnableList { private enum ViewMode { All, Recent, Favorites } private readonly SpawnableFinder _finder; private readonly ISpawnHistoryService _historyService; private readonly ILogService _logger; private readonly ISpawnableRepository _repository; private readonly SpawnableType _type; private readonly Action<string> _onItemSelected; private ViewMode _currentViewMode; private Vector2 _scrollPosition; private string _searchQuery = string.Empty; private string _selectedCategory = "All"; private IReadOnlyList<string> _currentItems = Array.Empty<string>(); private IReadOnlyList<string> _availableCategories = Array.Empty<string>(); private string _hoveredItem; private const string LogPrefix = "[SpawnableList]"; public SpawnableList(SpawnableFinder finder, ISpawnHistoryService historyService, ISpawnableRepository repository, ILogService logger, SpawnableType type, Action<string> onItemSelected) { _finder = Guard.Against.Null(finder, "finder"); _historyService = Guard.Against.Null(historyService, "historyService"); _repository = Guard.Against.Null(repository, "repository"); _logger = Guard.Against.Null(logger, "logger"); _type = type; _onItemSelected = onItemSelected; RefreshAvailableCategories(); RefreshItems(); } public void Draw() { DrawViewModeTabs(); if (_currentViewMode == ViewMode.All) { DrawSearchBar(); DrawCategoryFilters(); } DrawItemList(); } private void DrawViewModeTabs() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); foreach (ViewMode value in Enum.GetValues(typeof(ViewMode))) { string text = value.ToString(); switch (value) { case ViewMode.All: text = "All"; break; case ViewMode.Recent: text = "Recent"; break; case ViewMode.Favorites: text = "Favorites"; break; } bool flag = _currentViewMode == value; GUIStyle style = StyleProvider.GetStyle(flag ? "activeTab" : "tab"); if (GUILayout.Button(text, style, Array.Empty<GUILayoutOption>()) && !flag) { _currentViewMode = value; RefreshItems(); } } GUILayout.EndHorizontal(); } private void DrawSearchBar() { GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Search:", StyleProvider.GetStyle("label"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); string text = GUILayout.TextField(_searchQuery, StyleProvider.GetStyle("search"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (text != _searchQuery) { _searchQuery = text; RefreshItems(); } if (!string.IsNullOrEmpty(_searchQuery) && GUILayout.Button("X", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(25f) })) { _searchQuery = string.Empty; RefreshItems(); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private void DrawCategoryFilters() { if (_availableCategories != null && _availableCategories.Count != 0) { GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); GUILayout.Label((_type == SpawnableType.Enemy) ? "Difficulty:" : "Category:", StyleProvider.GetStyle("headerLabel"), Array.Empty<GUILayoutOption>()); DrawAllCategoryButton(); GUILayout.Space(5f); DrawCategoryGrid(); GUILayout.EndVertical(); } } private void DrawAllCategoryButton() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); bool flag = _selectedCategory == "All"; string styleName = (flag ? "allCategorySelected" : "allCategory"); if (GUILayout.Button("All", StyleProvider.GetStyle(styleName), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(100f) }) && !flag) { SetCategory("All"); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private void DrawCategoryGrid() { int count = _availableCategories.Count; int num = CalculateButtonsPerRow(); int num2 = Mathf.CeilToInt((float)count / (float)num); for (int i = 0; i < num2; i++) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); int num3 = i * num; int num4 = Mathf.Min(num, count - num3); float width = CalculateButtonWidth(num4); for (int j = 0; j < num4; j++) { int index = num3 + j; string category = _availableCategories[index]; DrawCategoryButton(category, width); } GUILayout.EndHorizontal(); } } private int CalculateButtonsPerRow() { float num = Mathf.Min((float)Screen.width * 0.3f - 40f, 390f); return Mathf.Max(3, Mathf.FloorToInt(num / 85f)); } private float CalculateButtonWidth(int buttonsInRow) { return Mathf.Min((float)Screen.width * 0.3f - 40f, 390f) / (float)buttonsInRow - 4f; } private void DrawCategoryButton(string category, float width) { bool flag = _selectedCategory == category; string styleName = (flag ? "categorySelected" : "category"); if (GUILayout.Button(category, StyleProvider.GetStyle(styleName), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(width) }) && !flag) { SetCategory(category); } } private void DrawItemList() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); DrawListHeader(); _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(400f) }); if (_currentItems.Count == 0) { DrawEmptyListMessage(); } else { DrawItemEntries(); } GUILayout.EndScrollView(); GUILayout.EndVertical(); } private void DrawListHeader() { string text = $"[List] {_currentViewMode}"; if (_currentViewMode == ViewMode.All && _selectedCategory != "All") { text = text + " > " + _selectedCategory; } text += $" ({_currentItems.Count})"; GUILayout.Label(text, StyleProvider.GetStyle("headerLabel"), Array.Empty<GUILayoutOption>()); } private void DrawEmptyListMessage() { object obj = _currentViewMode switch { ViewMode.Recent => "No recent items. Select items to add them here.", ViewMode.Favorites => "No favorite items. Click the star icon to add favorites.", _ => (_searchQuery.Length > 0) ? "No matching items found." : "No items available.", }; GUILayout.BeginVertical(StyleProvider.GetStyle("box"), Array.Empty<GUILayoutOption>()); GUILayout.Label((string)obj, StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); } private void DrawItemEntries() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Invalid comparison between Unknown and I4 //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Invalid comparison between Unknown and I4 //IL_008e: Unknown result type (might be due to invalid IL or missing references) int num = 0; Event current = Event.current; bool flag = false; foreach (string currentItem in _currentItems) { GUIStyle rowStyle = GetRowStyle(currentItem, num % 2 == 0); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); DrawFavoriteButton(currentItem); if (GUILayout.Button(currentItem, rowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) })) { _onItemSelected?.Invoke(currentItem); } GUILayout.EndHorizontal(); Rect lastRect = GUILayoutUtility.GetLastRect(); if ((int)current.type == 7 && ((Rect)(ref lastRect)).Contains(current.mousePosition)) { flag = true; if (_hoveredItem != currentItem) { _hoveredItem = currentItem; GUI.changed = true; } } num++; } if ((int)current.type == 7 && !flag) { _hoveredItem = null; } if (_currentItems.Count >= 500 && _currentViewMode == ViewMode.All) { DrawMaxResultsMessage(); } } private GUIStyle GetRowStyle(string itemName, bool isEvenRow) { if (itemName == _hoveredItem) { return StyleProvider.GetStyle("itemHover"); } return StyleProvider.GetStyle(isEvenRow ? "item" : "itemAlt"); } private void DrawFavoriteButton(string itemName) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) bool num = _historyService.IsFavorite(_type, itemName); string text = (num ? "★" : "☆"); Color color = GUI.color; if (num) { GUI.color = ConjurerConstants.Colors.StarYellow; } if (GUILayout.Button(text, StyleProvider.GetStyle("starButton"), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(25f), GUILayout.Height(28f) })) { _historyService.ToggleFavorite(_type, itemName); if (_currentViewMode == ViewMode.Favorites) { RefreshItems(); } } GUI.color = color; } private void DrawMaxResultsMessage() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.Label($"Showing first {500} results. Please refine your search.", StyleProvider.GetStyle("label"), Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private void RefreshAvailableCategories() { _availableCategories = _repository.GetCategories(_type); _logger.Log(LogLevel.Debug, () => string.Format("{0} Found {1} categories for {2}", "[SpawnableList]", _availableCategories.Count, _type)); } private void RefreshItems() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) _scrollPosition = Vector2.zero; _currentItems = _currentViewMode switch { ViewMode.Recent => _historyService.GetRecentItems(_type), ViewMode.Favorites => _historyService.GetFavorites(_type), _ => _finder.FindNames(_searchQuery, _type, (_selectedCategory != "All") ? _selectedCategory : null, 500), }; _logger.Log(LogLevel.Debug, () => string.Format("{0} Refreshed list with {1} items (Mode: {2}, Category: {3})", "[SpawnableList]", _currentItems.Count, _currentViewMode, _selectedCategory)); } public void SetCategory(string category) { if (_selectedCategory != category) { _selectedCategory = category; if (_currentViewMode == ViewMode.All) { RefreshItems(); } } } public void SetSearchQuery(string query) { if (_searchQuery != query) { _searchQuery = query; if (_currentViewMode == ViewMode.All) { RefreshItems(); } } } } public static class ToolTip { private static bool _showToolTip = false; private static string _toolTipText = string.Empty; private static Rect _toolTipRect; private static GUIStyle _toolTipStyle; private static Texture2D _backgroundTexture; public static void Draw() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (_showToolTip) { InitializeStyle(); GUI.Label(_toolTipRect, _toolTipText, _toolTipStyle); } } public static void Show(string text, Vector2 position) { //IL_0024: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) _toolTipText = text; float num = Mathf.Min(300, Mathf.Max(150, text.Length * 7)); float num2 = position.x + 15f; float num3 = position.y + 15f; if (num2 + num > (float)Screen.width) { num2 = (float)Screen.width - num - 10f; } if (num3 + 40f > (float)Screen.height) { num3 = position.y - 50f; } _toolTipRect = new Rect(num2, num3, num, 40f); _showToolTip = true; } public static void Hide() { _showToolTip = false; } private static void InitializeStyle() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (_toolTipStyle == null) { if ((Object)(object)_backgroundTexture == (Object)null) { _backgroundTexture = MakeBackgroundTexture(1, 1, new Color(0.1f, 0.1f, 0.1f, 0.9f)); } _toolTipStyle = new GUIStyle(GUI.skin.box); _toolTipStyle.normal.background = _backgroundTexture; _toolTipStyle.normal.textColor = ConjurerConstants.Colors.TextBright; _toolTipStyle.wordWrap = true; _toolTipStyle.padding = new RectOffset(8, 8, 6, 6); _toolTipStyle.fontSize = 12; } } private static Texture2D MakeBackgroundTexture(int width, int height, Color color) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < array.Length; i++) { array[i] = color; } Texture2D val = new Texture2D(width, height); val.SetPixels(array); val.Apply(); return val; } } } namespace ItemConjurer.Features.Spawning.Spawners { public class EnemySpawner : TypedSpawner { private readonly ISpawnHistoryService _historyService = Guard.Against.Null(historyService, "historyService"); private const string LogPrefix = "[EnemySpawner]"; public override string DisplayName => "Enemies"; public EnemySpawner(SpawnService spawnService, SpawnConfigProvider configProvider, ILogService logger, ISpawnHistoryService historyService) : base(spawnService, configProvider, logger, SpawnableType.Enemy) { } public override void Spawn(string name, int count = 0, float delay = 0f) { _logger.Log(LogLevel.Info, () => string.Format("{0} Request: '{1}' (x{2}, delay: {3}s)", "[EnemySpawner]", name, count, delay)); if (!SemiFunc.IsMasterClientOrSingleplayer()) { _logger.Log(LogLevel.Error, "[EnemySpawner] Denied - Only host - singleplayer may spawn enemies."); return; } if ((Object)(object)EnemyDirector.instance == (Object)null || (Object)(object)LevelGenerator.Instance == (Object)null) { _logger.Log(LogLevel.Error, "[EnemySpawner] Aborted - EnemyDirector or LevelGenerator is not initialized."); return; } WithSpawnContext(delegate { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) SpawnParameters parameters = new SpawnParameters { Position = GetSafeEnemySpawnPosition(), Rotation = Quaternion.identity, Count = ((count > 0) ? count : GetConfiguredSpawnAmount()), Delay = ((delay > 0f) ? delay : GetConfiguredSpawnDelay()), VerticalOffset = 0.5f }; _logger.Log(LogLevel.Info, () => string.Format("{0} Spawning '{1}' at {2} (x{3})", "[EnemySpawner]", name, parameters.Position, parameters.Count)); CoroutineRunner.Run(_spawnService.SpawnMultipleByName(name, parameters)); _historyService.AddRecentItem(SpawnableType.Enemy, name); }); } private void WithSpawnContext(Action action) { RunManager instance = RunManager.instance; if (instance != null) { instance.EnemiesSpawnedRemoveStart(); } try { action(); } finally { RunManager instance2 = RunManager.instance; if (instance2 != null) { instance2.EnemiesSpawnedRemoveEnd(); } } } protected Vector3 GetSafeEnemySpawnPosition() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) Vector3 defaultSpawnPosition = _spawnService.GetDefaultSpawnPosition(); List<LevelPoint> obj = LevelGenerator.Instance?.LevelPathPoints; if (obj != null && obj.Count > 0) { LevelPoint val = SemiFunc.LevelPointGetPlayerDistance(defaultSpawnPosition, 8f, 20f, false); if ((Object)(object)val != (Object)null) { return ((Component)val).transform.position; } } if ((Object)(object)Camera.main != (Object)null) { Vector3 forward = ((Component)Camera.main).transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude >= 0.001f) { ((Vector3)(ref forward)).Normalize(); return ((Component)Camera.main).transform.position + forward * 8f; } } return defaultSpawnPosition + Vector3.forward * 8f; } protected override int GetConfiguredSpawnAmount() { return Mathf.Min(_configProvider.GetConfig().SpawnAmount, 50); } protected override float GetConfiguredSpawnDelay() { return Mathf.Max(_configProvider.GetConfig().SpawnDelay, 1f); } } public interface ISpawner { string DisplayName { get; } void Spawn(string name, int count = 0, float delay = 0f); } public class TypedSpawner : ISpawner { protected readonly SpawnService _spawnService = Guard.Against.Null(spawnService, "spawnService"); protected readonly SpawnConfigProvider _configProvider = Guard.Against.Null(configProvider, "configProvider"); protected readonly ILogService _logger = Guard.Against.Null(logger, "logger"); protected readonly SpawnableType _type; private const string LogPrefix = "[TypedSpawner]"; public SpawnableType SpawnableType => _type; public virtual string DisplayName => _type.ToString(); public TypedSpawner(SpawnService spawnService, SpawnConfigProvider configProvider, ILogService logger, SpawnableType type) { _type = type; base..ctor(); } public virtual void Spawn(string name, int count = 0, float delay = 0f) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) _logger.Log(LogLevel.Info, () => string.Format("{0} '{1}' (x{2}, delay {3}s)", "[TypedSpawner]", name, count, delay)); _configProvider.GetConfig(); SpawnParameters parameters = new SpawnParameters { Position = GetDefaultSpawnPosition(), Rotation = Quaternion.identity, Count = ((count > 0) ? count : GetConfiguredSpawnAmount()), Delay = ((delay > 0f) ? delay : GetConfiguredSpawnDelay()), VerticalOffset = 0.2f }; CoroutineRunner.Run(_spawnService.SpawnMultipleByName(name, parameters)); } protected virtual Vector3 GetDefaultSpawnPosition() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return _spawnService.GetDefaultSpawnPosition(); } protected virtual int GetConfiguredSpawnAmount() { return _configProvider.GetConfig().SpawnAmount; } protected virtual float GetConfiguredSpawnDelay() { return _configProvider.GetConfig().SpawnDelay; } } } namespace ItemConjurer.Features.Spawning.Services { public class SpawnConfigProvider { private readonly ILogService _logger; private readonly string _configPath; private readonly object _lock = new object(); private ConjurerSettings _cachedConfig; private const string LogPrefix = "[SpawnConfig]"; public SpawnConfigProvider(ILogService logger) { _logger = Guard.Against.Null(logger, "logger"); _configPath = Path.Combine(Paths.ConfigPath, "ItemConjurer_settings.json"); LoadConfig(); } public ConjurerSettings GetConfig() { lock (_lock) { return _cachedConfig ?? LoadConfig(); } } public void UpdateConfig(Action<ConjurerSettings> update) { lock (_lock) { update(Guard.Against.Null(GetConfig(), "_cachedConfig")); SaveConfig(_cachedConfig); } } private ConjurerSettings LoadConfig() { try { if (File.Exists(_configPath)) { string text = File.ReadAllText(_configPath); _cachedConfig = JsonConvert.DeserializeObject<ConjurerSettings>(text) ?? CreateDefaultConfig(); } else { _cachedConfig = CreateDefaultConfig(); SaveConfig(_cachedConfig); } } catch (Exception ex2) { Exception ex3 = ex2; Exception ex = ex3; _logger.Log(LogLevel.Error, () => "[SpawnConfig] Load error: " + ex.Message); _cachedConfig = CreateDefaultConfig(); } return _cachedConfig; } private void SaveConfig(ConjurerSettings config) { try { string contents = JsonConvert.SerializeObject((object)config, (Formatting)1); File.WriteAllText(_configPath, contents); } catch (Exception ex2) { Exception ex3 = ex2; Exception ex = ex3; _logger.Log(LogLevel.Error, () => "[SpawnConfig] Save error: " + ex.Message); } } private static ConjurerSettings CreateDefaultConfig() { return new ConjurerSettings { IsVisible = false, SpawnAmount = 1, SpawnDelay = 1f }; } } public class SpawnHistoryService : ISpawnHistoryService { private readonly SpawnConfigProvider _configProvider = Guard.Against.Null(configProvider, "configProvider"); private readonly ILogService _logger = Guard.Against.Null(logger, "logger"); private readonly Dictionary<SpawnableType, List<string>> _recentCache = new Dictionary<SpawnableType, List<string>>(); private readonly Dictionary<SpawnableType, HashSet<string>> _favoritesCache = new Dictionary<SpawnableType, HashSet<string>>(); private bool _initialized; private const string LogPrefix = "[HistoryService]"; public SpawnHistoryService(SpawnConfigProvider configProvider, ILogService logger) { } private void EnsureInitialized() { if (_initialized) { return; } ConjurerSettings config = _configProvider.GetConfig(); foreach (SpawnableType value3 in Enum.GetValues(typeof(SpawnableType))) { string key2 = value3.ToString(); _recentCache[value3] = (config.RecentItemsByType.TryGetValue(key2, out var value) ? new List<string>(value) : new List<string>()); _favoritesCache[value3] = (config.FavoritesByType.TryGetValue(key2, out var value2) ? new HashSet<string>(value2, StringComparer.OrdinalIgnoreCase) : new HashSet<string>(StringComparer.OrdinalIgnoreCase)); } _initialized = true; } private void SaveChanges() { _configProvider.UpdateConfig(delegate(ConjurerSettings config) { config.RecentItemsByType.Clear(); foreach (KeyValuePair<SpawnableType, List<string>> item in _recentCache) { config.RecentItemsByType[item.Key.ToString()] = new List<string>(item.Value); } config.FavoritesByType.Clear(); foreach (KeyValuePair<SpawnableType, HashSet<string>> item2 in _favoritesCache) { config.FavoritesByType[item2.Key.ToString()] = item2.Value.ToList(); } }); } public IReadOnlyList<string> GetRecentItems(SpawnableType type) { EnsureInitialized(); if (!_recentCache.TryGetValue(type, out var value)) { return new List<string>(); } return value.ToList(); } public IReadOnlyList<string> GetFavorites(SpawnableType type) { EnsureInitialized(); if (!_favoritesCache.TryGetValue(type, out var value)) { return new List<string>(); } return value.ToList(); } public void AddRecentItem(SpawnableType type, string itemName) { if (!string.IsNullOrWhiteSpace(itemName)) { EnsureInitialized(); if (!_recentCache.TryGetValue(type, out var value)) { value = new List<string>(); _recentCache[type] = value; } value.Remove(itemName); value.Insert(0, itemName); if (value.Count > 10) { value.RemoveRange(10, value.Count - 10); } SaveChanges(); _logger.Log(LogLevel.Debug, () => string.Format("{0} Added '{1}' to recent {2} items", "[HistoryService]", itemName, type)); } } public bool IsFavorite(SpawnableType type, string itemName) { if (string.IsNullOrWhiteSpace(itemName)) { return false; } EnsureInitialized(); if (_favoritesCache.TryGetValue(type, out var value)) { return value.Contains(itemName); } return false; } public void ToggleFavorite(SpawnableType type, string itemName) { if (string.IsNullOrWhiteSpace(itemName)) { return; } EnsureInitialized(); if (!_favoritesCache.TryGetValue(type, out var value)) { value = new HashSet<string>(StringComparer.OrdinalIgnoreCase); _favoritesCache[type] = value; } if (!value.Remove(itemName)) { value.Add(itemName); _logger.Log(LogLevel.Debug, () => string.Format("{0} Added '{1}' to {2} favorites", "[HistoryService]", itemName, type)); } else { _logger.Log(LogLevel.Debug, () => string.Format("{0} Removed '{1}' from {2} favorites", "[HistoryService]", itemName, type)); } SaveChanges(); } } } namespace ItemConjurer.Data { [Serializable] public class ConjurerSettings { public bool IsVisible { get; set; } public int SpawnAmount { get; set; } = 1; public float SpawnDelay { get; set; } = 1f; public int LastTabIndex { get; set; } public Dictionary<string, List<string>> RecentItemsByType { get; set; } = new Dictionary<string, List<string>>(); public Dictionary<string, List<string>> FavoritesByType { get; set; } = new Dictionary<string, List<string>>(); } } namespace ItemConjurer.Core.Infrastructure.Utils { public static class CoroutineRunner { private class MonoBehaviourRunner : MonoBehaviour { } private static MonoBehaviourRunner _runner; public static Coroutine Run(IEnumerator coroutine) { EnsureInitialized(); return ((MonoBehaviour)_runner).StartCoroutine(coroutine); } public static void Stop(Coroutine coroutine) { if ((Object)(object)_runner != (Object)null) { ((MonoBehaviour)_runner).StopCoroutine(coroutine); } } public static void Cleanup() { if ((Object)(object)_runner != (Object)null) { Object.Destroy((Object)(object)((Component)_runner).gameObject); _runner = null; } } private static void EnsureInitialized() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if ((Object)(object)_runner == (Object)null) { GameObject val = new GameObject("ItemConjurer_CoroutineRunner"); Object.DontDestroyOnLoad((Object)val); _runner = val.AddComponent<MonoBehaviourRunner>(); } } } public static class Guard { public static class Against { public static T Null<T>(T value, string paramName) where T : class { if (value == null) { throw new ArgumentNullException(paramName); } return value; } public static string NullOrEmpty(string value, string paramName) { if (string.IsNullOrEmpty(value)) { throw new ArgumentException("String cannot be null or empty", paramName); } return value; } public static string NullOrWhiteSpace(string value, string paramName) { if (string.IsNullOrWhiteSpace(value)) { throw new ArgumentException("String cannot be null, empty or whitespace", paramName); } return value; } public static void Condition(bool condition, string message) { if (!condition) { throw new ArgumentException(message); } } } } } namespace ItemConjurer.Core.Infrastructure.Network { public class NetworkingService { private readonly ILogService _logger = Guard.Against.Null(logger, "logger"); private readonly Dictionary<string, GameObject> _prefabCache = new Dictionary<string, GameObject>(); private const string LogPrefix = "[NetworkingService]"; public NetworkingService(ILogService logger) { } public void RegisterPrefab(string prefabId, GameObject prefab) { if (string.IsNullOrWhiteSpace(prefabId) || (Object)(object)prefab == (Object)null) { _logger.Log(LogLevel.Debug, "[NetworkingService] Cannot register null prefab or prefab without ID"); return; } if (NetworkPrefabs.HasNetworkPrefab(prefabId)) { _logger.Log(LogLevel.Debug, () => "[NetworkingService] Prefab already registered: " + prefabId); return; } GameObject val = Resources.Load<GameObject>(prefabId) ?? prefab; try { NetworkPrefabs.RegisterNetworkPrefab(prefabId, val); _prefabCache[prefabId] = val; _logger.Log(LogLevel.Debug, () => "[NetworkingService] Prefab registered: " + prefabId); } catch (Exception ex2) { Exception ex3 = ex2; Exception ex = ex3; _logger.Log(LogLevel.Error, () => "[NetworkingService] Error registering prefab " + prefabId + ": " + ex.Message); } } public GameObject SpawnNetworkObject(string prefabId, Vector3 position, Quaternion rotation) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if (!CanSpawn()) { _logger.Log(LogLevel.Warning, "[NetworkingService] Only the host can spawn objects in multiplayer"); return null; } if (string.IsNullOrWhiteSpace(prefabId)) { _logger.Log(LogLevel.Error, "[NetworkingService] Cannot spawn with null ID"); return null; } try { if (SemiFunc.IsMultiplayer()) { GameObject val = NetworkPrefabs.SpawnNetworkPrefab(prefabId, position, rotation, (byte)0, (object[])null); if ((Object)(object)val != (Object)null) { return val; } _logger.Log(LogLevel.Debug, () => "[NetworkingService] NetworkPrefabs failed, using Photon fallback for " + prefabId); return PhotonNetwork.InstantiateRoomObject(prefabId, position, rotation, (byte)0, (object[])null); } return SpawnLocal(prefabId, position, rotation); } catch (Exception ex2) { Exception ex3 = ex2; Exception ex = ex3; _logger.Log(LogLevel.Error, () => "[NetworkingService] Error spawning " + prefabId + ": " + ex.Message); return null; } } private GameObject SpawnLocal(string prefabId, Vector3 position, Quaternion rotation) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (_prefabCache.TryGetValue(prefabId, out var value)) { return Object.Instantiate<GameObject>(value, position, rotation); } GameObject val = Resources.Load<GameObject>(prefabId); if ((Object)(object)val == (Object)null) { _logger.Log(LogLevel.Error, () => "[NetworkingService] Prefab not found for " + prefabId); return null; } return Object.Instantiate<GameObject>(val, position, rotation); } public bool CanSpawn() { if (SemiFunc.IsMultiplayer()) { return SemiFunc.IsMasterClientOrSingleplayer(); } return true; } } } namespace ItemConjurer.Core.Infrastructure.Logging { public interface ILogService { bool IsEnabled(LogLevel level); void Log(LogLevel level, string message); void Log(LogLevel level, Func<string> messageFactory); } public enum LogLevel { Trace, Debug, Info, Warning, Error } public class LogService : ILogService { private readonly ManualLogSource _logger = Logger.CreateLogSource(source); private LogLevel _minimumLevel = LogLevel.Info; public LogService(string source) { } public bool IsEnabled(LogLevel level) { return level >= _minimumLevel; } public void Log(LogLevel level, string message) { if (IsEnabled(level)) { LogToSource(level, message); } } public void Log(LogLevel level, Func<string> messageFactory) { if (IsEnabled(level)) { LogToSource(level, messageFactory()); } } private void LogToSource(LogLevel level, string message) { switch (level) { case LogLevel.Trace: case LogLevel.Debug: _logger.LogDebug((object)message); break; case LogLevel.Info: _logger.LogInfo((object)message); break; case LogLevel.Warning: _logger.LogWarning((object)message); break; case LogLevel.Error: _logger.LogError((object)message); break; } } public void SetMinimumLevel(LogLevel level) { _minimumLevel = level; } } } namespace ItemConjurer.Core.Infrastructure.Game { public class EnemySystemBridge : IEnemySystem { private readonly ILogService _logger = Guard.Against.Null(logger, "logger"); private readonly NetworkingService _networkService = Guard.Against.Null(networkService, "networkService"); private const string LogPrefix = "[EnemySystemBridge]"; public bool IsAvailable { get { if ((Object)(object)EnemyDirector.instance != (Object)null) { return (Object)(object)LevelGenerator.Instance != (Object)null; } return false; } } public EnemySystemBridge(ILogService logger, NetworkingService networkService) { } public IReadOnlyList<EnemySetup> GetAllEnemySetups() { if (!IsAvailable) { return Array.Empty<EnemySetup>(); } return ExecuteWithErrorHandling(() => EnemyDirectorExtensions.GetEnemies(EnemyDirector.instance), "Error retrieving enemy setups", new List<EnemySetup>()); } public bool TrySpawnEnemy(EnemySetup setup, Vector3 position, Quaternion rotation, out List<EnemyParent> spawned) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) spawned = new List<EnemyParent>(); if (!IsAvailable || (Object)(object)setup == (Object)null) { return false; } try { if (SemiFunc.IsMultiplayer()) { SpawnEnemyInMultiplayer(setup, position, rotation, spawned); } else { SpawnEnemyInSingleplayer(setup, position, rotation, spawned); } if (spawned.Count > 0) { RegisterEnemiesWithDirectors(spawned); return true; } return false; } catch (Exception ex2) { Exception ex = ex2; _logger.Log(LogLevel.Error, delegate { EnemySetup obj = setup; return "[EnemySystemBridge] Error spawning '" + ((obj != null) ? ((Object)obj).name : null) + "': " + ex.Message; }); return false; } } public LevelPoint GetSafeSpawnPoint(Vector3 position, float minDist, float maxDist) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (!IsAvailable) { return null; } return ExecuteWithErrorHandling(delegate { //IL_0001: Unknown result type (might be due to invalid IL or missing references) LevelPoint val = SemiFunc.LevelPointGetPlayerDistance(position, minDist, maxDist, false); return ((Object)(object)val != (Object)null) ? val : FindOptimalSpawnPoint(minDist, maxDist); }, "Failed to calculate safe spawn point", null); } private LevelPoint FindOptimalSpawnPoint(float minDist, float maxDist) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)PlayerController.instance == (Object)null) { return null; } LevelPoint result = null; float num = minDist; foreach (LevelPoint levelPathPoint in LevelGenerator.Instance.LevelPathPoints) { float num2 = Vector3.Distance(((Component)levelPathPoint).transform.position, ((Component)PlayerController.instance).transform.position); if (num2 >= minDist && num2 <= maxDist && num2 > num) { num = num2; result = levelPathPoint; } } return result; } private void SpawnEnemyInMultiplayer(EnemySetup setup, Vector3 position, Quaternion rotation, List<EnemyParent> output) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) List<EnemyParent> list = Enemies.SpawnEnemy(setup, position, rotation, false); if (list != null) { output.AddRange(list); } } private bool SpawnEnemyInSingleplayer(EnemySetup setup, Vector3 position, Quaternion rotation, List<EnemyParent> output) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) bool result = false; foreach (GameObject distinctSpawnObject in EnemySetupExtensions.GetDistinctSpawnObjects(setup)) { if (!((Object)(object)distinctSpawnObject == (Object)null)) { EnemyParent val = InstantiateEnemyInstance(distinctSpawnObject, position, rotation); if ((Object)(object)val != (Object)null) { output.Add(val); result = true; } } } return result; } private EnemyParent InstantiateEnemyInstance(GameObject prefab, Vector3 position, Quaternion rotation) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) return ExecuteWithErrorHandling((Func<EnemyParent>)delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) RegisterPrefabIfNeeded(prefab); GameObject val = Object.Instantiate<GameObject>(prefab, position, rotation); EnemyParent component = val.GetComponent<EnemyParent>(); if ((Object)(object)component == (Object)null) { return null; } InitializeEnemyInstance(component, val, position); return component; }, "Error spawning '" + ((Object)prefab).name + "'", (EnemyParent)null); } private void RegisterPrefabIfNeeded(GameObject prefab) { string enemyPrefabPath = ResourcesHelper.GetEnemyPrefabPath(prefab); if (!string.IsNullOrEmpty(enemyPrefabPath)) { _networkService.RegisterPrefab(enemyPrefabPath, prefab); } } private void InitializeEnemyInstance(EnemyParent parent, GameObject instance, Vector3 position) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) Traverse.Create((object)parent).Field("SetupDone").SetValue((object)true); Enemy componentInChildren = instance.GetComponentInChildren<Enemy>(); if (componentInChildren != null) { componentInChildren.EnemyTeleported(position); } UpdateEnemySpawnCount(); EnemyDirector.instance.FirstSpawnPointAdd(parent); } private void UpdateEnemySpawnCount() { Traverse obj = Traverse.Create((object)LevelGenerator.Instance); int value = obj.Field("EnemiesSpawnTarget").GetValue<int>(); obj.Field("EnemiesSpawnTarget").SetValue((object)(value + 1)); } private void RegisterEnemiesWithDirectors(IEnumerable<EnemyParent> parents) { (EnemyBangDirector director, List<Vector3> destinations) bangDirectorData = GetBangDirectorData(); EnemyBangDirector item = bangDirectorData.director; List<Vector3> item2 = bangDirectorData.destinations; (EnemyGnomeDirector, List<Vector3>) gnomeDirectorData = GetGnomeDirectorData(); foreach (EnemyParent parent in parents) { RegisterBangEnemy(parent, item, item2); RegisterGnomeEnemy(parent, gnomeDirectorData.Item1, gnomeDirectorData.Item2); RegisterOnScreenEnemy(parent); } } private (EnemyBangDirector director, List<Vector3> destinations) GetBangDirectorData() { EnemyBangDirector instance = EnemyBangDirector.instance; List<Vector3> item = (((Object)(object)instance != (Object)null) ? Traverse.Create((object)instance).Field("destinations").GetValue<List<Vector3>>() : null); return (instance, item); } private (EnemyGnomeDirector director, List<Vector3> destinations) GetGnomeDirectorData() { EnemyGnomeDirector instance = EnemyGnomeDirector.instance; List<Vector3> item = (((Object)(object)instance != (Object)null) ? Traverse.Create((object)instance).Field("destinations").GetValue<List<Vector3>>() : null); return (instance, item); } private void RegisterBangEnemy(EnemyParent parent, EnemyBangDirector director, List<Vector3> destinations) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)director == (Object)null) && destinations != null) { EnemyBang componentInChildren = ((Component)parent).GetComponentInChildren<EnemyBang>(); if (!((Object)(object)componentInChildren == (Object)null)) { director.units.Add(componentInChildren); destinations.Add(Vector3.zero); Traverse.Create((object)componentInChildren).Field("directorIndex").SetValue((object)(director.units.Count - 1)); } } } private void RegisterGnomeEnemy(EnemyParent parent, EnemyGnomeDirector director, List<Vector3> destinations) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)director == (Object)null) && destinations != null) { EnemyGnome componentInChildren = ((Component)parent).GetComponentInChildren<EnemyGnome>(); if (!((Object)(object)componentInChildren == (Object)null)) { director.gnomes.Add(componentInChildren); destinations.Add(Vector3.zero); Traverse.Create((object)componentInChildren).Field("directorIndex").SetValue((object)(director.gnomes.Count - 1)); } } } private void RegisterOnScreenEnemy(EnemyParent parent) { EnemyOnScreen componentInChildren = ((Component)parent).GetComponentInChildren<EnemyOnScreen>(); if ((Object)(object)componentInChildren == (Object)null) { return; } foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { componentInChildren.PlayerAdded(player.photonView.ViewID); } } private T ExecuteWithErrorHandling<T>(Func<T> operation, string errorMessage, T defaultValue) { try { return operation(); } catch (Exception ex2) { Exception ex = ex2; _logger.Log(LogLevel.Error, () => "[EnemySystemBridge] " + errorMessage + ": " + ex.Message); return defaultValue; } } } } namespace ItemConjurer.Core.Infrastructure.DI { public class DefaultServiceContainer : IServiceContainer { private readonly Dictionary<Type, Func<IServiceContainer, object>> _factories = new Dictionary<Type, Func<IServiceContainer, object>>(); private readonly Dictionary<Type, object> _singletons = new Dictionary<Type, object>(); public void Register<T>(T implementation) where T : class { Guard.Against.Null(implementation, "implementation"); Register<T, T>(implementation); } public void Register<TInterface, TImplementation>(TImplementation implementation) where TImplementation : class, TInterface { Guard.Against.Null(implementation, "implementation"); Type typeFromHandle = typeof(TInterface); _singletons[typeFromHandle] = implementation; _factories[typeFromHandle] = (IServiceContainer _) => implementation; } public void RegisterFactory<T>(Func<IServiceContainer, T> factory) where T : class { Guard.Against.Null(factory, "factory"); Type typeFromHandle = typeof(T); _factories[typeFromHandle] = (IServiceContainer container) => factory(container); } public T Resolve<T>() where T : class { Type typeFromHandle = typeof(T); if (_factories.TryGetValue(typeFromHandle, out var value)) { return (T)value(this); } throw new InvalidOperationException("Service of type " + typeFromHandle.Name + " is not registered"); } public bool TryResolve<T>(out T service) where T : class { service = null; Type typeFromHandle = typeof(T); if (!_factories.TryGetValue(typeFromHandle, out var value)) { return false; } try { service = (T)value(this); return true; } catch { return false; } } public bool IsRegistered<T>() where T : class { return _factories.ContainsKey(typeof(T)); } public void Clear() { _factories.Clear(); _singletons.Clear(); } } public interface IServiceContainer { void Register<T>(T implementation) where T : class; void Register<TInterface, TImplementation>(TImplementation implementation) where TImplementation : class, TInterface; void RegisterFactory<T>(Func<IServiceContainer, T> factory) where T : class; T Resolve<T>() where T : class; bool TryResolve<T>(out T service) where T : class; bool IsRegistered<T>() where T : class; void Clear(); } public static class ServiceContainerExtensions { public static void Register<TInterface, TImplementation>(this IServiceContainer container) where TImplementation : class, TInterface, new() { Guard.Against.Null(container, "container"); TImplementation implementation = new TImplementation(); container.Register<TInterface, TImplementation>(implementation); } public static T ResolveOrDefault<T>(this IServiceContainer container, T defaultValue = null) where T : class { Guard.Against.Null(container, "container"); if (!container.TryResolve<T>(out var service)) { return defaultValue; } return service; } } } namespace ItemConjurer.Core.Infrastructure.Constants { public static class ConjurerConstants { public static class UI { public const float DefaultWindowWidth = 490f; public const float DefaultWindowHeight = 600f; public const float DefaultWindowX = 20f; public const float DefaultWindowY = 20f; public const float ButtonHeight = 28f; public const int MaxListItems = 500; public const int WindowId = 6969; public const float TabButtonHeight = 25f; public const float SearchLabelWidth = 60f; public const float SearchFieldWidth = 250f; public const float ScrollViewHeight = 400f; public const float StarButtonWidth = 25f; public const float SpacerHeight = 5f; public const float SpacerHeight10 = 10f; public const float CategoryButtonWidth = 85f; } public static class Colors { public static readonly Color HeaderBackground = new Color(0.12f, 0.12f, 0.14f); public static readonly Color TabSelected = new Color(0.2f, 0.4f, 0.8f); public static readonly Color CategoryButtonNormal = new Color(0.2f, 0.2f, 0.22f); public static readonly Color CategoryButtonSelected = new Color(0.1f, 0.6f, 0.2f); public static readonly Color CategoryButtonHover = new Color(0.3f, 0.3f, 0.35f); public static readonly Color ItemNormal = new Color(0.15f, 0.15f, 0.15f); public static readonly Color ItemAlternate = new Color(0.18f, 0.18f, 0.2f); public static readonly Color ItemHover = new Color(0.25f, 0.3f, 0.4f); public static readonly Color ItemSelected = new Color(0.2f, 0.25f, 0.4f); public static readonly Color AlternateRowColor = new Color(0.22f, 0.22f, 0.24f); public static readonly Color StarYellow = new Color(1f, 0.92f, 0.016f); public static readonly Color SpawnButtonColor = new Color(0.2f, 0.7f, 0.3f); public static readonly Color SpawnButtonHover = new Color(0.3f, 0.8f, 0.4f); public static readonly Color TextBright = new Color(0.9f, 0.9f, 0.9f); public static readonly Color TextHighlight = new Color(1f, 1f, 1f); public static readonly Color TextControl = new Color(0.8f, 0.8f, 0.8f); public static readonly Color ControlBackgroundColor = new Color(0.18f, 0.18f, 0.2f, 1f); public static readonly Color ControlFieldBackground = new Color(0.12f, 0.12f, 0.14f); } public static class Categories { public const string All = "All"; public const string Items = "Items"; public const string Valuables = "Valuables"; public const string Unknown = "Unknown"; public const string Easy = "Easy"; public const string Medium = "Medium"; public const string Hard = "Hard"; public const string Weapons = "Weapons"; public const string Tools = "Tools"; public const string Upgrades = "Upgrades"; public const string Modded = "Modded"; public const string Artifacts = "Artifacts"; public const string Technology = "Technology"; public const string Resources = "Resources"; public const string Arctic = "Arctic"; public const string Wizard = "Wizard"; public const string Toys = "Toys"; public const string Default = "Not Categorized"; } public static class History { public const int MaxRecentItems = 10; } public static class ViewModes { public const string All = "All"; public const string Recent = "Recent"; public const string Favorites = "Favorites"; public const string Results = "Results"; } public static class SpawnLimits { public const int MaxSafeEnemies = 50; public const float MinSafeDelay = 1f; public const float DefaultDelay = 1f; public const float DefaultVerticalOffset = 0.2f; public const float DefaultSpawnAmount = 1f; public const float DefaultEnemyMinDistance = 8f; public const float DefaultEnemyMaxDistance = 20f; public const float DelayMultiplier = 4f; } public static class FileNames { public const string SettingsFileName = "ItemConjurer_settings.json"; } public static class GameObjectNames { public const string CoroutineRunnerName = "ItemConjurer_CoroutineRunner"; } public static class SpawnPositionConfig { public const float DefaultForwardDistance = 2f; public const float DefaultHeightOffset = 0.3f; public const float ItemSpawnHeightOffset = 0.3f; public const float ValuableSpawnHeightOffset = 0.3f; public const float StackingHeightOffset = 0.2f; } } } namespace ItemConjurer.Core.Infrastructure.Bootstrap { public abstract class BaseModuleInitializer : IModuleInitializer { protected readonly string LogPrefix; public abstract int InitializationPriority { get; } public abstract string ModuleName { get; } protected BaseModuleInitializer() { LogPrefix = "[" + ModuleName + "]"; } public abstract void RegisterServices(IServiceContainer container); public virtual void Initialize(IServiceContainer container) { GetLogger(container)?.Log(LogLevel.Info, LogPrefix + " Initializing " + ModuleName + " module"); } protected ILogService GetLogger(IServiceContainer container) { if (!container.TryResolve<ILogService>(out var service)) { return null; } return service; } } public interface IModuleInitializer { int InitializationPriority { get; } string ModuleName { get; } void RegisterServices(IServiceContainer container); void Initialize(IServiceContainer container); } public class ServiceBootstrapper { private readonly IServiceContainer _container; private readonly List<IModuleInitializer> _modules = new List<IModuleInitializer>(); private bool _initialized; private static ServiceBootstrapper _instance; private const string LogPrefix = "[Bootstrap]"; public static ServiceBootstrapper Instance => _instance ?? (_instance = new ServiceBootstrapper()); public IServiceContainer Container => _container; public static bool IsInitialized => _instance?._initialized ?? false; private ServiceBootstrapper() { _container = new DefaultServiceContainer(); RegisterModules(); } public void Initialize(bool discover = true) { if (_initialized) { if (_container.TryResolve<ILogService>(out var service)) { service.Log(LogLevel.Warning, "[Bootstrap] Services are already initialized"); } return; } try { foreach (IModuleInitializer item in _modules.OrderBy((IModuleInitializer m) => m.InitializationPriority)) { item.RegisterServices(_container); } ILogService logService = _container.Resolve<ILogService>(); logService.Log(LogLevel.Info, "[Bootstrap] Services registration complete"); foreach (IModuleInitializer item2 in _modules.OrderBy((IModuleInitializer m) => m.InitializationPriority)) { try { item2.Initialize(_container); } catch (Exception ex) { logService.Log(LogLevel.Error, "[Bootstrap] Error initializing module '" + item2.ModuleName + "': " + ex.Message); } } if (discover) { RunDiscovery(logService); } logService.Log(LogLevel.Info, "[Bootstrap] Initialization complete"); _initialized = true; } catch (Exception ex2) { if (_container.TryResolve<ILogService>(out var service2)) { service2.Log(LogLevel.Error, "[Bootstrap] Fatal error during initialization: " + ex2.Message); } else { Debug.LogError((object)("[Bootstrap] Fatal error during initialization: " + ex2.Message)); } throw; } } public void RunDiscovery() { if (!_initialized) { throw new InvalidOperationException("[Bootstrap] Cannot run discovery before initialization"); } ILogService logger = _container.Resolve<ILogService>(); RunDiscovery(logger); } private void RunDiscovery(ILogService logger) { Guard.Against.Null(logger, "logger"); logger.Log(LogLevel.Info, "[Bootstrap] Running discovery of spawnables"); try { _container.Resolve<DiscoveryService>().DiscoverAll(); } catch (Exception ex) { logger.Log(LogLevel.Error, "[Bootstrap] Error during discovery: " + ex.Message); } } private void RegisterModules() { _modules.Add(new InfrastructureModuleInitializer()); _modules.Add(new DataModuleInitializer()); _modules.Add(new GameServicesModuleInitializer()); _modules.Add(new FeaturesModuleInitializer()); } public static void Reset() { if (_instance != null) { _instance._container.Clear(); _instance = null; } } } } namespace ItemConjurer.Core.Infrastructure.Bootstrap.Modules { public class DataModuleInitializer : BaseModuleInitializer { public override int InitializationPriority => 20; public override string ModuleName => "Data"; public override void RegisterServices(IServiceContainer container) { ILogService logService = Guard.Against.Null(GetLogger(container), "ILogService"); SpawnableRepository implementation = new SpawnableRepository(logService); container.Register((ISpawnableRepository)implementation); logService.Log(LogLevel.Debug, LogPrefix + " Repository services registered"); SpawnConfigProvider implementation2 = new SpawnConfigProvider(logService); container.Register(implementation2); logService.Log(LogLevel.Debug, LogPrefix + " Configuration services registered"); } } public class FeaturesModuleInitializer : BaseModuleInitializer { public override int InitializationPriority => 40; public override string ModuleName => "Features"; public override void RegisterServices(IServiceContainer container) { ILogService logService = Guard.Against.Null(GetLogger(container), "ILogService"); ISpawnableRepository repository = Guard.Against.Null(container.Resolve<ISpawnableRepository>(), "ISpawnableRepository"); IEnemySystem enemySystem = Guard.Against.Null(container.Resolve<IEnemySystem>(), "IEnemySystem"); NetworkingService networkService = Guard.Against.Null(container.Resolve<NetworkingService>(), "NetworkingService"); SpawnConfigProvider configProvider = Guard.Against.Null(container.Resolve<SpawnConfigProvider>(), "SpawnConfigProvider"); RegisterDiscoveryServices(container, logService, repository, enemySystem, networkService); RegisterSpawnServices(container, logService, repository, configProvider); logService.Log(LogLevel.Debug, LogPrefix + " Feature services registered"); } private void RegisterDiscoveryServices(IServiceContainer container, ILogService logger, ISpawnableRepository repository, IEnemySystem enemySystem, NetworkingService networkService) { ItemDiscoveryStrategy itemDiscoveryStrategy = new ItemDiscoveryStrategy(logger, networkService); ValuableDiscoveryStrategy valuableDiscoveryStrategy = new ValuableDiscoveryStrategy(logger, networkService); EnemyDiscoveryStrategy enemyDiscoveryStrategy = new EnemyDiscoveryStrategy(enemySystem, logger, networkService); container.Register((IDiscoveryStrategy)itemDiscoveryStrategy); container.Register((IDiscoveryStrategy)valuableDiscoveryStrategy); container.Register((IDiscoveryStrategy)enemyDiscoveryStrategy); List<IDiscoveryStrategy> strategies = new List<IDiscoveryStrategy> { itemDiscoveryStrategy, valuableDiscoveryStrategy, enemyDiscoveryStrategy }; container.RegisterFactory((Func<IServiceContainer, IEnumerable<IDiscoveryStrategy>>)((IServiceContainer c) => strategies)); DiscoveryService implementation = new DiscoveryService(strategies, repository, logger); container.Register(implementation); logger.Log(LogLevel.Debug, LogPrefix + " Discovery services registered"); } private void RegisterSpawnServices(IServiceContainer container, ILogService logger, ISpawnableRepository repository, SpawnConfigProvider configProvider) { SpawnableFinder implementation = new SpawnableFinder(repository, logger); container.Register(implementation); SpawnService spawnService = new SpawnService(repository, logger); container.Register(spawnService); SpawnHistoryService spawnHistoryService = new SpawnHistoryService(configProvider, logger); container.Register((ISpawnHistoryService)spawnHistoryService); List<ISpawner> spawners = new List<ISpawner>(); TypedSpawner item = new TypedSpawner(spawnService, configProvider, logger, SpawnableType.Item); spawners.Add(item); TypedSpawner item2 = new TypedSpawner(spawnService, configProvider, logger, SpawnableType.Valuable); spawners.Add(item2); EnemySpawner enemySpawner = new EnemySpawner(spawnService, configProvider, logger, spawnHistoryService); spawners.Add(enemySpawner); container.Register(enemySpawner); container.RegisterFactory((Func<IServiceContainer, IEnumerable<ISpawner>>)((IServiceContainer c) => spawners)); logger.Log(LogLevel.Debug, LogPrefix + " Spawning services registered"); } } public class GameServicesModuleInitializer : BaseModuleInitializer { public override int InitializationPriority => 30; public override string ModuleName => "GameServices"; public override void RegisterServices(IServiceContainer container) { ILogService logService = Guard.Against.Null(GetLogger(container), "ILogService"); NetworkingService networkService = Guard.Against.Null(container.Resolve<NetworkingService>(), "NetworkingService"); EnemySystemBridge implementation = new EnemySystemBridge(logService, networkService); container.Register((IEnemySystem)implementation); logService.Log(LogLevel.Debug, LogPrefix + " Game service bridges registered"); } } public class InfrastructureModuleInitializer : BaseModuleInitializer { public override int InitializationPriority => 10; public override string ModuleName => "Infrastructure"; public override void RegisterServices(IServiceContainer container) { LogService logService = new LogService("ItemConjurer"); container.Register((ILogService)logService); logService.Log(LogLevel.Info, LogPrefix + " Logging services registered"); NetworkingService implementation = new NetworkingService(logService); container.Register(implementation); logService.Log(LogLevel.Debug, LogPrefix + " Networking services registered"); } } } namespace ItemConjurer.Core.Domain.Models { public enum SpawnableType { Item, Valuable, Enemy } public class SpawnParameters { public Vector3 Position { get; set; } = Vector3.zero; public Quaternion Rotation { get; set; } = Quaternion.identity; public int Count { get; set; } = 1; public float Delay { get; set; } = 1f; public float VerticalOffset { get; set; } = 0.2f; public float ForwardDistance { get; set; } = 2f; public float HeightOffset { get; set; } = 0.3f; public Vector3 CalculateSpawnPosition(Vector3 sourcePosition, Vector3 forward) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_002d: Unknown result type (might be due to invalid IL or missing references) forward = ((!(((Vector3)(ref forward)).sqrMagnitude < 0.001f)) ? ((Vector3)(ref forward)).normalized : Vector3.forward); return sourcePosition + forward * ForwardDistance; } } } namespace ItemConjurer.Core.Domain.Adapters { public abstract class BaseSpawnableAdapter : ISpawnable { public abstract string Id { get; } public abstract string Name { get; } public abstract string Category { get; } public abstract SpawnableType Type { get; } public abstract GameObject Spawn(Vector3 position, Quaternion rotation); public abstract bool Equals(ISpawnable other); public override bool Equals(object obj) { if (obj is ISpawnable other) { return Equals(other); } return false; } public override int GetHashCode() { return Id.GetHashCode(StringComparison.OrdinalIgnoreCase); } } public class EnemyAdapter : BaseSpawnableAdapter { private readonly EnemySetup _enemySetup; private readonly IEnemySystem _enemySystem; private readonly ILogService _logger; private readonly string _enemyName; private readonly string _category; private const string LogPrefix = "[EnemyAdapter]"; public override string Id => ((Object)_enemy