Decompiled source of ItemSpawnSync v0.9.0

plugins/com.github.flonou.Peak-ItemSpawnSync.dll

Decompiled 2 days 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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ItemSpawnSync.Core;
using ItemSpawnSync.Data;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.flonou.Peak-ItemSpawnSync")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.9.0.0")]
[assembly: AssemblyInformationalVersion("0.9.0+70d156596acb830af9304f144b9951a67b540010")]
[assembly: AssemblyProduct("com.github.flonou.Peak-ItemSpawnSync")]
[assembly: AssemblyTitle("ItemSpawnSync")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.0.0")]
[module: UnverifiableCode]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
}
public class ContractResolver : DefaultContractResolver
{
	protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		JsonProperty val = ((DefaultContractResolver)this).CreateProperty(member, memberSerialization);
		val.Writable = true;
		val.Readable = true;
		return val;
	}

	protected override List<MemberInfo> GetSerializableMembers(Type objectType)
	{
		if (objectType.Name.Contains("AnonymousType"))
		{
			return objectType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Cast<MemberInfo>().ToList();
		}
		return (from f in objectType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
			where f.IsPublic || ((MemberInfo)f).GetCustomAttribute<SerializeField>() != null
			select f).Cast<MemberInfo>().ToList();
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace FFSPeak.Patches
{
	[HarmonyPatch]
	public class SpawnerSpawnItemsPatch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private List<Type>.Enumerator <>7__wrap1;

			MethodBase IEnumerator<MethodBase>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TargetMethods>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = default(List<Type>.Enumerator);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						List<Type> list = new List<Type>();
						Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
						foreach (Assembly assembly in assemblies)
						{
							try
							{
								IEnumerable<Type> collection = from t in assembly.GetTypes()
									where t.IsClass && !t.IsAbstract && typeof(Spawner).IsAssignableFrom(t)
									select t;
								list.AddRange(collection);
							}
							catch
							{
							}
						}
						<>7__wrap1 = list.GetEnumerator();
						<>1__state = -3;
						break;
					}
					case 1:
						<>1__state = -3;
						break;
					}
					while (<>7__wrap1.MoveNext())
					{
						Type current = <>7__wrap1.Current;
						MethodInfo method = current.GetMethod("SpawnItems", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(List<Transform>) }, null);
						if (method != null)
						{
							<>2__current = method;
							<>1__state = 1;
							return true;
						}
					}
					<>m__Finally1();
					<>7__wrap1 = default(List<Type>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>7__wrap1).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetMethods>d__0(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<TargetMethods>d__0))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__0(-2);
		}

		private static bool Prefix(Spawner __instance, List<Transform> spawnSpots, ref List<PhotonView> __result)
		{
			SpawnerSyncManager instance = SpawnerSyncManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			if (instance.UseLoadedSpawnData)
			{
				if (instance.HasSpawnerData(__instance))
				{
					SpawnerInstanceData spawnerData = instance.GetSpawnerData(__instance);
					__result = instance.SpawnItemsFromData(__instance, spawnerData);
					return false;
				}
				__result = new List<PhotonView>();
				return instance.SpawnIfNoDataFound;
			}
			__result = new List<PhotonView>();
			if (instance.DisableSpawning)
			{
				return instance.CapturingSpawn;
			}
			return true;
		}
	}
}
namespace ItemSpawnSync
{
	[BepInPlugin("com.github.flonou.Peak-ItemSpawnSync", "ItemSpawnSync", "0.9.0")]
	public class Plugin : BaseUnityPlugin
	{
		public ConfigEntry<bool>? DisableSpawningConfig;

		public bool EnableKeyTrigger = true;

		public ConfigEntry<string>? FileNameConfig;

		public ConfigEntry<KeyCode>? LoadDataKeyConfig;

		public ConfigEntry<KeyCode>? SaveDataKeyConfig;

		public ConfigEntry<bool>? SpawnIfNoDataFoundConfig;

		public ConfigEntry<KeyCode>? TriggerSpawnKeyConfig;

		private string? dataDirectory;

		private Harmony? harmony;

		private static readonly JsonSerializerSettings jsonSettings = new JsonSerializerSettings
		{
			ReferenceLoopHandling = (ReferenceLoopHandling)1,
			Formatting = (Formatting)0,
			ContractResolver = (IContractResolver)(object)new ContractResolver()
		};

		public const string Id = "com.github.flonou.Peak-ItemSpawnSync";

		public static Plugin? Instance { get; private set; }

		public bool IsSpawnDataLocked => SpawnerSyncManager.Instance.IsDataLocked;

		public KeyCode LoadDataKey => LoadDataKeyConfig.Value;

		public static ManualLogSource? Log { get; private set; }

		public KeyCode SaveDataKey => SaveDataKeyConfig.Value;

		public KeyCode TriggerSpawnKey => TriggerSpawnKeyConfig.Value;

		public static string Name => "ItemSpawnSync";

		public static string Version => "0.9.0";

		public string GetSpawnDataAsJson()
		{
			MapSpawnerData currentMapData = SpawnerSyncManager.Instance.CurrentMapData;
			return JsonConvert.SerializeObject((object)currentMapData);
		}

		public bool LoadSpawnData(MapSpawnerData data, bool lockData = false)
		{
			bool flag = SpawnerSyncManager.Instance.LoadMapSpawnerData(data, lockData);
			if (flag)
			{
				Log.LogInfo((object)($"Loaded spawn data with {data.Spawners.Count} spawners" + (lockData ? " (LOCKED)" : "")));
			}
			return flag;
		}

		public MapSpawnerData? LoadSpawnDataFromFile(string filename)
		{
			try
			{
				string text = Path.Combine(dataDirectory, filename);
				if (!File.Exists(text))
				{
					Log.LogError((object)("Spawn data file not found: " + text));
					return null;
				}
				string text2 = File.ReadAllText(text);
				MapSpawnerData mapSpawnerData = JsonConvert.DeserializeObject<MapSpawnerData>(text2);
				if (mapSpawnerData != null)
				{
					LoadSpawnData(mapSpawnerData);
					Log.LogInfo((object)("Loaded spawn data from: " + text));
					Log.LogInfo((object)$"  Spawners: {mapSpawnerData.Spawners.Count}");
					Log.LogInfo((object)$"  Items: {CountTotalItems(mapSpawnerData)}");
				}
				else
				{
					Log.LogError((object)("Failed to deserialize spawn data from json " + text2));
				}
				return mapSpawnerData;
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to load spawn data: " + ex.Message));
				return null;
			}
		}

		public bool LoadSpawnDataFromJson(string json, bool lockData = false)
		{
			try
			{
				MapSpawnerData mapSpawnerData = JsonConvert.DeserializeObject<MapSpawnerData>(json);
				if (mapSpawnerData != null)
				{
					return LoadSpawnData(mapSpawnerData, lockData);
				}
				Log.LogError((object)("Could not deserialize spawn data from JSON: " + json));
				return false;
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to load spawn data from JSON: " + ex.Message));
				return false;
			}
		}

		public void SaveCurrentSpawnData()
		{
			//IL_002f: 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)
			try
			{
				MapSpawnerData currentMapData = SpawnerSyncManager.Instance.CurrentMapData;
				if (currentMapData == null || currentMapData.Spawners.Count == 0)
				{
					Log.LogWarning((object)"No spawn data to save. Start capture first and trigger spawners.");
					return;
				}
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				string path = $"{name}_spawn_data_{DateTime.Now:yyyyMMdd_HHmmss}.json";
				string text = Path.Combine(dataDirectory, path);
				string contents = JsonConvert.SerializeObject((object)currentMapData, (Formatting)1, jsonSettings);
				File.WriteAllText(text, contents);
				Log.LogInfo((object)("Saved spawn data to: " + text));
				Log.LogInfo((object)$"  Spawners: {currentMapData.Spawners.Count}");
				Log.LogInfo((object)$"  Items: {CountTotalItems(currentMapData)}");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to save spawn data: " + ex.Message));
			}
		}

		protected void Awake()
		{
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			TriggerSpawnKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "TriggerSpawnKey", (KeyCode)285, "Key to trigger all spawners");
			SaveDataKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "SaveDataKey", (KeyCode)286, "Key to save current spawn data to file");
			LoadDataKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "LoadDataKey", (KeyCode)287, "Key to load spawn data from file");
			DisableSpawningConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableSpawning", false, "If true, prevents any item spawning unless from loaded data");
			SpawnIfNoDataFoundConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SpawnIfNoDataFound", false, "If true, spawners without loaded data will spawn normally");
			FileNameConfig = ((BaseUnityPlugin)this).Config.Bind<string>("General", "DefaultFileName", "spawn_data.json", "Default filename to load spawn data.");
			dataDirectory = Path.Combine(Paths.ConfigPath, "ItemSpawnSync");
			Directory.CreateDirectory(dataDirectory);
			SpawnerSyncManager.Instance.Initialize(Log);
			SpawnerSyncManager.Instance.EnableKeyTrigger = EnableKeyTrigger;
			SpawnerSyncManager.Instance.DisableSpawning = DisableSpawningConfig.Value;
			SpawnerSyncManager.Instance.SpawnIfNoDataFound = SpawnIfNoDataFoundConfig.Value;
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
			Log.LogInfo((object)("Data directory: " + dataDirectory));
			harmony = new Harmony(Name);
			harmony.PatchAll();
			Log.LogInfo((object)"Harmony patches applied");
			Log.LogInfo((object)"Controls:");
			Log.LogInfo((object)$"  {TriggerSpawnKey} - Trigger all spawners");
			Log.LogInfo((object)$"  {SaveDataKey} - Save spawn data to file");
			Log.LogInfo((object)$"  {LoadDataKey} - Load spawn data from file");
		}

		protected void Update()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(TriggerSpawnKey))
			{
				SpawnerSyncManager.Instance.CaptureSpawns();
			}
			if (Input.GetKeyDown(SaveDataKey))
			{
				SaveCurrentSpawnData();
			}
			if (Input.GetKeyDown(LoadDataKey))
			{
				LoadSpawnDataFromFile(FileNameConfig.Value);
				if (SpawnerSyncManager.Instance.DisableSpawning)
				{
					SpawnerSyncManager.Instance.SpawnItemsFromStartSpawners();
				}
			}
		}

		private int CountTotalItems(MapSpawnerData data)
		{
			int num = 0;
			foreach (SpawnerInstanceData spawner in data.Spawners)
			{
				num += spawner.SpawnedItems.Count;
			}
			return num;
		}

		private void OnDestroy()
		{
			Harmony? obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
}
namespace ItemSpawnSync.Data
{
	[Serializable]
	public class SpawnedItemData
	{
		public string ItemPrefabName = string.Empty;

		public Vector3 Position;

		public Quaternion Rotation;
	}
	[Serializable]
	public class SpawnerInstanceData
	{
		public string SpawnerTypeName = string.Empty;

		public int SpawnerInstanceID;

		public Vector3 SpawnerPosition;

		public List<SpawnedItemData> SpawnedItems = new List<SpawnedItemData>();
	}
	[Serializable]
	public class MapSpawnerData
	{
		public List<SpawnerInstanceData> Spawners = new List<SpawnerInstanceData>();
	}
}
namespace ItemSpawnSync.Core
{
	public class SpawnerSyncManager : MonoBehaviour
	{
		public bool DisableSpawning;

		public bool EnableKeyTrigger;

		public bool SpawnIfNoDataFound;

		protected MethodInfo ForceSyncForFramesMethod = typeof(Item).GetMethod("ForceSyncForFrames", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static SpawnerSyncManager? instance;

		private ManualLogSource? logger;

		private Dictionary<int, Spawner> spawnerRegistry = new Dictionary<int, Spawner>();

		private Dictionary<Spawner, SpawnerInstanceData> spawnerToDataMap = new Dictionary<Spawner, SpawnerInstanceData>();

		public bool CapturingSpawn { get; internal set; }

		public MapSpawnerData? CurrentMapData { get; private set; }

		public static SpawnerSyncManager Instance
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected O, but got Unknown
				if ((Object)(object)instance == (Object)null)
				{
					GameObject val = new GameObject("SpawnerSyncManager");
					instance = val.AddComponent<SpawnerSyncManager>();
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				return instance;
			}
		}

		public bool IsDataLocked { get; private set; }

		public bool UseLoadedSpawnData { get; private set; }

		public void CaptureSpawns()
		{
			CurrentMapData = new MapSpawnerData();
			TriggerAllSpawners();
		}

		public static List<Spawner> FindAllSpawnersInScene()
		{
			return Object.FindObjectsByType<Spawner>((FindObjectsSortMode)0).ToList();
		}

		public SpawnerInstanceData? GetSpawnerData(Spawner spawner)
		{
			if (!spawnerToDataMap.TryGetValue(spawner, out SpawnerInstanceData value))
			{
				return null;
			}
			return value;
		}

		public bool HasSpawnerData(Spawner spawner)
		{
			return spawnerToDataMap.ContainsKey(spawner);
		}

		public void Initialize(ManualLogSource logger)
		{
			this.logger = logger;
		}

		public bool LoadMapSpawnerData(MapSpawnerData data, bool lockData = false)
		{
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			if (IsDataLocked)
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)"Spawn data is locked. Cannot load new data.");
				}
				return false;
			}
			CurrentMapData = data;
			spawnerRegistry.Clear();
			spawnerToDataMap.Clear();
			List<Spawner> list = FindAllSpawnersInScene();
			HashSet<SpawnerInstanceData> matchedData = new HashSet<SpawnerInstanceData>();
			ManualLogSource? obj2 = logger;
			if (obj2 != null)
			{
				obj2.LogInfo((object)$"Found {list.Count} spawners in scene, attempting to match with {data.Spawners.Count} data entries");
			}
			int num = 0;
			foreach (Spawner spawner2 in list)
			{
				if (!((Object)(object)((MonoBehaviourPun)spawner2).photonView != (Object)null) || ((MonoBehaviourPun)spawner2).photonView.ViewID < 0)
				{
					continue;
				}
				SpawnerInstanceData spawnerInstanceData = data.Spawners.FirstOrDefault((SpawnerInstanceData d) => d.SpawnerInstanceID == ((MonoBehaviourPun)spawner2).photonView.ViewID && !matchedData.Contains(d));
				if (spawnerInstanceData != null)
				{
					spawnerToDataMap[spawner2] = spawnerInstanceData;
					matchedData.Add(spawnerInstanceData);
					num++;
					ManualLogSource? obj3 = logger;
					if (obj3 != null)
					{
						obj3.LogInfo((object)$"Matched spawner {((Object)spawner2).name} by ViewID {((MonoBehaviourPun)spawner2).photonView.ViewID}");
					}
				}
			}
			int num2 = 0;
			List<Spawner> list2 = list.Where((Spawner s) => !spawnerToDataMap.ContainsKey(s)).ToList();
			List<SpawnerInstanceData> list3 = data.Spawners.Where((SpawnerInstanceData d) => !matchedData.Contains(d)).ToList();
			foreach (Spawner spawner in list2)
			{
				SpawnerInstanceData spawnerInstanceData2 = (from d in list3
					where d.SpawnerTypeName == ((object)spawner).GetType().Name
					orderby Vector3.Distance(((Component)spawner).transform.position, d.SpawnerPosition)
					select d).FirstOrDefault();
				if (spawnerInstanceData2 == null)
				{
					continue;
				}
				float num3 = Vector3.Distance(((Component)spawner).transform.position, spawnerInstanceData2.SpawnerPosition);
				if (num3 < 0.01f)
				{
					spawnerToDataMap[spawner] = spawnerInstanceData2;
					matchedData.Add(spawnerInstanceData2);
					list3.Remove(spawnerInstanceData2);
					num2++;
					ManualLogSource? obj4 = logger;
					if (obj4 != null)
					{
						obj4.LogInfo((object)$"Matched spawner {((Object)spawner).name} at position {spawnerInstanceData2.SpawnerPosition} by proximity ({num3:F3}m)");
					}
				}
			}
			ManualLogSource? obj5 = logger;
			if (obj5 != null)
			{
				obj5.LogInfo((object)$"Matched {num} spawners by ViewID, {num2} by proximity. Total: {spawnerToDataMap.Count}/{data.Spawners.Count}");
			}
			UseLoadedSpawnData = true;
			if (lockData)
			{
				IsDataLocked = true;
				ManualLogSource? obj6 = logger;
				if (obj6 != null)
				{
					obj6.LogInfo((object)$"Started replaying spawner data with {data.Spawners.Count} spawners (LOCKED)");
				}
			}
			else
			{
				ManualLogSource? obj7 = logger;
				if (obj7 != null)
				{
					obj7.LogInfo((object)$"Started replaying spawner data with {data.Spawners.Count} spawners");
				}
			}
			return true;
		}

		public List<PhotonView> SpawnItemsFromData(Spawner spawner, SpawnerInstanceData data)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			List<PhotonView> list = new List<PhotonView>();
			try
			{
				foreach (SpawnedItemData spawnedItem in data.SpawnedItems)
				{
					Item component = PhotonNetwork.InstantiateItemRoom(spawnedItem.ItemPrefabName, spawnedItem.Position, spawnedItem.Rotation).GetComponent<Item>();
					list.Add(((Component)component).GetComponent<PhotonView>());
					ForceSyncForFramesMethod.Invoke(component, new object[1] { 10 });
					if ((Object)(object)component != (Object)null && spawner.isKinematic)
					{
						((Component)component).GetComponent<PhotonView>().RPC("SetKinematicRPC", (RpcTarget)3, new object[3]
						{
							true,
							((Component)component).transform.position,
							((Component)component).transform.rotation
						});
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogError((object)("Error spawning items from data for spawner " + ((Object)spawner).name + ": " + ex.Message));
				}
			}
			return list;
		}

		public void SpawnItemsFromStartSpawners()
		{
			List<Spawner> list = (from s in FindAllSpawnersInScene()
				where s.spawnOnStart
				select s).ToList();
			ManualLogSource? obj = logger;
			if (obj != null)
			{
				obj.LogInfo((object)$"Spawning items from {list.Count} start spawners...");
			}
			foreach (Spawner item in list)
			{
				try
				{
					item.baseSpawnChance = 1f;
					if (((Behaviour)item).enabled)
					{
						item.ForceSpawn();
					}
				}
				catch (Exception ex)
				{
					ManualLogSource? obj2 = logger;
					if (obj2 != null)
					{
						obj2.LogError((object)("Error spawning from start spawner " + ((Object)item).name + " of type " + ((object)item).GetType().Name + ": " + ex.Message));
					}
				}
			}
		}

		public void TriggerAllSpawners()
		{
			List<Spawner> list = FindAllSpawnersInScene();
			ManualLogSource? obj = logger;
			if (obj != null)
			{
				obj.LogInfo((object)$"Triggering {list.Count} spawners...");
			}
			CapturingSpawn = true;
			int num = 0;
			foreach (Spawner item in list)
			{
				try
				{
					if (TriggerSpawner(item))
					{
						num++;
					}
				}
				catch (Exception ex)
				{
					ManualLogSource? obj2 = logger;
					if (obj2 != null)
					{
						obj2.LogError((object)("Error triggering spawner " + ((Object)item).name + " of type " + ((object)item).GetType().Name + ": " + ex.Message));
					}
				}
			}
			CapturingSpawn = false;
			ManualLogSource? obj3 = logger;
			if (obj3 != null)
			{
				obj3.LogInfo((object)$"Triggered {num} spawners out of {list.Count} successfully");
			}
		}

		private void SaveSpawnerData(Spawner spawner, List<GameObject> spawnedObjects)
		{
			//IL_001f: 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)
			Type type = ((object)spawner).GetType();
			SpawnerInstanceData spawnerInstanceData = new SpawnerInstanceData
			{
				SpawnerTypeName = type.Name,
				SpawnerPosition = ((Component)spawner).transform.position,
				SpawnerInstanceID = (((Object)(object)((MonoBehaviourPun)spawner).photonView != (Object)null) ? ((MonoBehaviourPun)spawner).photonView.ViewID : (-1)),
				SpawnedItems = spawnedObjects.Select(delegate(GameObject obj)
				{
					//IL_0039: Unknown result type (might be due to invalid IL or missing references)
					//IL_003e: Unknown result type (might be due to invalid IL or missing references)
					//IL_004a: 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)
					string text = ((Object)obj).name;
					if (text.EndsWith("(Clone)"))
					{
						string text2 = text;
						text = text2.Substring(0, text2.Length - 7);
					}
					return new SpawnedItemData
					{
						ItemPrefabName = text,
						Position = obj.transform.position,
						Rotation = obj.transform.rotation
					};
				}).ToList()
			};
			CurrentMapData.Spawners.Add(spawnerInstanceData);
			spawnerToDataMap[spawner] = spawnerInstanceData;
		}

		private bool TriggerSpawner(Spawner spawner)
		{
			if (spawner.spawnOnStart)
			{
				List<PhotonView> list = spawner.TrySpawnItems();
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogInfo((object)$"Triggered spawnOnStart on spawner {((Object)spawner).name} and got {list.Count} items");
				}
				SaveSpawnerData(spawner, list.Select((PhotonView view) => ((Component)view).gameObject).ToList());
				return true;
			}
			Type type = ((object)spawner).GetType();
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
			MethodInfo method = type.GetMethod("GetSpawnSpots", bindingAttr);
			if (method != null)
			{
				List<Transform> list2 = method.Invoke(spawner, null) as List<Transform>;
				List<PhotonView> list3 = spawner.SpawnItems(list2);
				ManualLogSource? obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogInfo((object)$"Triggered {type.Name}.SpawnItems() on spawner {((Object)spawner).name} and got {list3.Count} items");
				}
				SaveSpawnerData(spawner, list3.Select((PhotonView view) => ((Component)view).gameObject).ToList());
				return true;
			}
			ManualLogSource? obj3 = logger;
			if (obj3 != null)
			{
				obj3.LogWarning((object)(type.Name + " spawner " + ((Object)spawner).name + " does not have expected spawn method GetSpawnSpots."));
			}
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}