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;
using Zorro.Core;
[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.2.0")]
[assembly: AssemblyInformationalVersion("0.9.2+53b5671712ad82e1ad1d013c784944f44dc1e84c")]
[assembly: AssemblyProduct("com.github.flonou.Peak-ItemSpawnSync")]
[assembly: AssemblyTitle("ItemSpawnSync")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.2.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;
}
}
}
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.2")]
public class Plugin : BaseUnityPlugin
{
public bool EnableKeyTrigger = true;
public ConfigEntry<bool>? DisableSpawningConfig;
public ConfigEntry<string>? FileNameConfig;
public ConfigEntry<KeyboardShortcut>? LoadDataKeyConfig;
public ConfigEntry<KeyboardShortcut>? ExportLootDataKeyConfig;
public ConfigEntry<KeyboardShortcut>? SaveDataKeyConfig;
public ConfigEntry<bool>? SpawnIfNoDataFoundConfig;
public ConfigEntry<KeyboardShortcut>? TriggerSpawnKeyConfig;
public ConfigEntry<KeyboardShortcut>? ImportLootDataKeyConfig;
private static 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 KeyboardShortcut LoadDataKey => LoadDataKeyConfig.Value;
public static ManualLogSource? Log { get; private set; }
public KeyboardShortcut SaveDataKey => SaveDataKeyConfig.Value;
public KeyboardShortcut TriggerSpawnKey => TriggerSpawnKeyConfig.Value;
public KeyboardShortcut ExportLootDataKey => ExportLootDataKeyConfig.Value;
public KeyboardShortcut ImportLootDataKey => ImportLootDataKeyConfig.Value;
public static string DataDirectory => dataDirectory;
public static string Name => "ItemSpawnSync";
public static string Version => "0.9.2";
public string GetSpawnDataAsJson()
{
MapSpawnerData currentMapData = SpawnerSyncManager.Instance.CurrentMapData;
return JsonConvert.SerializeObject((object)currentMapData);
}
public bool LoadSpawnDataInCurrentLevel(MapSpawnerData data, bool lockData = false)
{
bool flag = SpawnerSyncManager.Instance.LoadMapSpawnerDataInCurrentLevel(data, lockData);
if (flag)
{
Log.LogInfo((object)($"Loaded spawn data with {data.Spawners.Count} spawners" + (lockData ? " (LOCKED)" : "")));
}
if (SpawnerSyncManager.Instance.DisableSpawning)
{
SpawnerSyncManager.Instance.SpawnItemsFromStartSpawners();
}
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)
{
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 true;
}
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_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_0235: Unknown result type (might be due to invalid IL or missing references)
//IL_023f: Expected O, but got Unknown
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_0292: Unknown result type (might be due to invalid IL or missing references)
//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
TriggerSpawnKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "TriggerSpawnKey", new KeyboardShortcut((KeyCode)285, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key to trigger all spawners");
SaveDataKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "SaveDataKey", new KeyboardShortcut((KeyCode)286, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key to save current spawn data to file");
LoadDataKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "LoadDataKey", new KeyboardShortcut((KeyCode)287, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key to load spawn data from file");
ExportLootDataKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "ExportLootDataKey", new KeyboardShortcut((KeyCode)288, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key to export loot data to file");
ImportLootDataKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "ImportLootDataKey", new KeyboardShortcut((KeyCode)289, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key to import loot 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");
Log.LogInfo((object)$" {ExportLootDataKey} - Export loot data to file");
Log.LogInfo((object)$" {ImportLootDataKey} - Import loot data from file");
}
protected void Update()
{
//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)
//IL_001b: 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_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: 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_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
KeyboardShortcut val = TriggerSpawnKey;
if (((KeyboardShortcut)(ref val)).IsDown())
{
SpawnerSyncManager.Instance.CaptureSpawns();
}
val = SaveDataKey;
if (((KeyboardShortcut)(ref val)).IsDown())
{
SaveCurrentSpawnData();
}
val = LoadDataKey;
if (((KeyboardShortcut)(ref val)).IsDown())
{
MapSpawnerData mapSpawnerData = LoadSpawnDataFromFile(FileNameConfig.Value);
if (mapSpawnerData != null)
{
LoadSpawnDataInCurrentLevel(mapSpawnerData);
}
}
val = ExportLootDataKey;
if (((KeyboardShortcut)(ref val)).IsDown())
{
LootDataContainer.ExportLootData();
}
val = ImportLootDataKey;
if (((KeyboardShortcut)(ref val)).IsDown())
{
LootDataContainer.ImportLootData();
}
}
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
{
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();
}
}
public class LootDataContainer
{
protected static string LootDataFileName = "LootData.json";
public static Dictionary<string, Dictionary<string, int>> SpawnData = new Dictionary<string, Dictionary<string, int>>();
public static void ImportLootData()
{
string text = Path.Combine(Plugin.DataDirectory, LootDataFileName);
if (!File.Exists(text))
{
ManualLogSource? log = Plugin.Log;
if (log != null)
{
log.LogError((object)("Loot data file not found at " + text));
}
return;
}
string text2 = File.ReadAllText(text);
SpawnData = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, int>>>(text2) ?? new Dictionary<string, Dictionary<string, int>>();
ManualLogSource? log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)("Loot data imported from " + text));
}
ApplyLootData();
}
public static void ExportLootData()
{
ExtractLootData();
string contents = JsonConvert.SerializeObject((object)SpawnData, (Formatting)1);
string text = Path.Combine(Plugin.DataDirectory, LootDataFileName);
File.WriteAllText(text, contents);
ManualLogSource? log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("Loot data exported to " + text));
}
}
private static void ApplyLootData()
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
if (LootData.AllSpawnWeightData == null)
{
LootData.PopulateLootData();
}
if (LootData.AllSpawnWeightData == null)
{
ManualLogSource? log = Plugin.Log;
if (log != null)
{
log.LogError((object)"No loot data found to export.");
}
return;
}
Item val = default(Item);
foreach (KeyValuePair<string, Dictionary<string, int>> spawnDatum in SpawnData)
{
string key = spawnDatum.Key;
foreach (SpawnPool key2 in LootData.AllSpawnWeightData.Keys)
{
SpawnPool current2 = key2;
if (!(((object)(SpawnPool)(ref current2)).ToString() == key))
{
continue;
}
foreach (KeyValuePair<string, int> item in spawnDatum.Value)
{
string itemName = item.Key;
int value = item.Value;
KeyValuePair<ushort, Item> keyValuePair = SingletonAsset<ItemDatabase>.Instance.itemLookup.FirstOrDefault((KeyValuePair<ushort, Item> kvp) => ItemDatabase.TryGetItem(kvp.Key, ref val) && ((Object)((Component)val).gameObject).name == itemName);
if (LootData.AllSpawnWeightData[current2].ContainsKey(keyValuePair.Key))
{
LootData.AllSpawnWeightData[current2].Remove(keyValuePair.Key);
}
if (value > 0)
{
LootData.AllSpawnWeightData[current2].Add(keyValuePair.Key, value);
continue;
}
ManualLogSource? log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)("Skipping item " + itemName + " with zero spawn weight in pool " + key));
}
}
break;
}
}
}
private static void ExtractLootData()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
if (LootData.AllSpawnWeightData == null)
{
LootData.PopulateLootData();
}
if (LootData.AllSpawnWeightData == null)
{
ManualLogSource? log = Plugin.Log;
if (log != null)
{
log.LogError((object)"No loot data found to export.");
}
return;
}
Item val = default(Item);
foreach (KeyValuePair<SpawnPool, Dictionary<ushort, int>> allSpawnWeightDatum in LootData.AllSpawnWeightData)
{
SpawnPool key = allSpawnWeightDatum.Key;
string key2 = ((object)(SpawnPool)(ref key)).ToString();
Dictionary<string, int> dictionary = new Dictionary<string, int>();
SpawnData.Add(key2, dictionary);
foreach (KeyValuePair<ushort, int> item in allSpawnWeightDatum.Value)
{
if (ItemDatabase.TryGetItem(item.Key, ref val))
{
LootData component = ((Component)val).GetComponent<LootData>();
int value = item.Value;
dictionary.Add(((Object)((Component)val).gameObject).name, value);
}
}
}
}
}
[Serializable]
public class SpawnedItemData
{
public string ItemPrefabName = string.Empty;
public Vector3 Position;
public Quaternion Rotation;
public int ViewID;
}
[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 Dictionary<int, Item> OriginalIdToItemMap { get; private set; } = new Dictionary<int, Item>();
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 LoadMapSpawnerDataInCurrentLevel(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_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: 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>();
PhotonView component2 = ((Component)component).GetComponent<PhotonView>();
OriginalIdToItemMap[spawnedItem.ViewID] = component;
list.Add(component2);
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<PhotonView> 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(PhotonView 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 = ((Component)obj).transform.position,
Rotation = ((Component)obj).transform.rotation,
ViewID = obj.ViewID
};
}).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);
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);
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)
{
}
}
}