Decompiled source of ItemConjurer v2.3.1
plugins/item_conjurer/ItemConjurer.dll
Decompiled 2 weeks 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