Decompiled source of ItemConjurer v2.3.1

plugins/item_conjurer/ItemConjurer.dll

Decompiled 2 weeks ago
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