Decompiled source of Underground Ruins v1.0.1
Underground_Ruins.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Common; using HarmonyLib; using JetBrains.Annotations; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using Underground_Ruins; using UnityEngine; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.RepresentationModel; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: AssemblyFileVersion("1.0.1")] [assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyProduct("Underground_Ruins")] [assembly: AssemblyCompany("warpalicious")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("Underground_Ruins")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<f226bb40-aada-4ad3-8f0b-bb460e036783>Embedded] internal sealed class <f226bb40-aada-4ad3-8f0b-bb460e036783>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<f226bb40-aada-4ad3-8f0b-bb460e036783>Embedded] internal sealed class <00cb15e2-ff46-40a2-ae2a-484c986e2dfc>IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [<f226bb40-aada-4ad3-8f0b-bb460e036783>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <d19a41d4-b8f4-41ee-8b21-a4b047800d1a>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <d19a41d4-b8f4-41ee-8b21-a4b047800d1a>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <d19a41d4-b8f4-41ee-8b21-a4b047800d1a>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [<f226bb40-aada-4ad3-8f0b-bb460e036783>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContextAttribute : Attribute { public readonly byte Flag; public <acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContextAttribute(byte P_0) { Flag = P_0; } } } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] public class RoomExtras : MonoBehaviour { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] private static class Patches { [HarmonyPatch(typeof(DungeonGenerator), "SetupAvailableRooms")] [HarmonyPostfix] [HarmonyPriority(0)] private static void OnDungeonGeneratorSetupAvailableRooms() { RoomExtras.OnDungeonGeneratorSetupAvailableRooms(); } [HarmonyPatch(typeof(DungeonGenerator), "Generate", new Type[] { typeof(int), typeof(SpawnMode) })] [HarmonyPostfix] private static void OnDungeonGeneratorGenerate() { RoomExtras.OnDungeonGeneratorGenerate(); } [HarmonyPatch(typeof(DungeonGenerator), "PlaceOneRoom")] [HarmonyPostfix] private static void OnDungeonGeneratorPlaceOneRoom(bool __result) { RoomExtras.OnDungeonGeneratorPlaceOneRoom(__result); } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] [HarmonyPatch(typeof(DungeonGenerator), "PlaceRoom", new Type[] { typeof(RoomConnection), typeof(RoomData), typeof(SpawnMode) })] [HarmonyPostfix] private static void OnDungeonGeneratorPlaceRoom(bool __result, RoomData roomData) { RoomExtras.OnDungeonGeneratorPlaceRoom(__result, roomData); } } public int PlacementLimit = 0; public string PlacementGroup = string.Empty; [HideInInspector] public static Dictionary<string, int> placements = new Dictionary<string, int>(); private static string lastRoomPlaced = ""; public static void ApplyPatches(Harmony harmony) { if (harmony == null) { throw new ArgumentNullException("harmony"); } harmony.PatchAll(typeof(Patches)); } private static void OnDungeonGeneratorSetupAvailableRooms() { RoomExtras roomExtras = default(RoomExtras); foreach (RoomData availableRoom in DungeonGenerator.m_availableRooms) { if (availableRoom.m_prefab.IsLoaded && ((Component)availableRoom.RoomInPrefab).TryGetComponent<RoomExtras>(ref roomExtras) && roomExtras != null && roomExtras.PlacementLimit > 0) { if (!string.IsNullOrEmpty(roomExtras.PlacementGroup)) { placements[roomExtras.PlacementGroup] = 0; } else { placements[((Object)roomExtras).name] = 0; } } } } private static void OnDungeonGeneratorGenerate() { placements.Clear(); } private static void OnDungeonGeneratorPlaceRoom(bool result, RoomData roomData) { if (result) { lastRoomPlaced = ((Object)roomData.RoomInPrefab).name; } } private static void OnDungeonGeneratorPlaceOneRoom(bool wasPlaced) { if (!wasPlaced || string.IsNullOrEmpty(lastRoomPlaced)) { return; } RoomData val = DungeonGenerator.m_availableRooms.Where([<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] (RoomData r) => string.Equals(lastRoomPlaced, ((Object)r.RoomInPrefab).name)).FirstOrDefault(); RoomExtras extras = default(RoomExtras); if (!((Component)val.RoomInPrefab).TryGetComponent<RoomExtras>(ref extras)) { return; } int num = 0; if (!string.IsNullOrEmpty(extras.PlacementGroup) && placements.ContainsKey(extras.PlacementGroup)) { num = ++placements[extras.PlacementGroup]; if (extras.PlacementLimit != 0 && num >= extras.PlacementLimit) { Debug.Log((object)string.Format("[{0}] Removing group {1}, limit reached {2}", "RoomExtras", extras.PlacementGroup, num)); RoomExtras roomExtras2 = default(RoomExtras); DungeonGenerator.m_tempRooms.RemoveAll([<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] (RoomData r) => ((Component)r.RoomInPrefab).TryGetComponent<RoomExtras>(ref roomExtras2) && roomExtras2.PlacementGroup == extras.PlacementGroup); RoomExtras roomExtras = default(RoomExtras); DungeonGenerator.m_availableRooms.RemoveAll([<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] (RoomData r) => ((Component)r.RoomInPrefab).TryGetComponent<RoomExtras>(ref roomExtras) && roomExtras.PlacementGroup == extras.PlacementGroup); } } else if (placements.ContainsKey(((Object)extras).name)) { num = ++placements[((Object)extras).name]; if (extras.PlacementLimit != 0 && num >= extras.PlacementLimit) { Debug.Log((object)string.Format("[{0}] Removing {1}, limit reached {2}", "RoomExtras", ((Object)extras).name, num)); DungeonGenerator.m_tempRooms.Remove(val); DungeonGenerator.m_availableRooms.Remove(val); } } } } namespace Common { [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public class AssetManager { public static AssetBundle assetBundle; public static string bundleName; public static void LoadAssetBundle() { assetBundle = AssetUtils.LoadAssetBundleFromResources(bundleName, Assembly.GetExecutingAssembly()); if ((Object)(object)assetBundle == (Object)null) { WarpLogger.Logger.LogError((object)("Failed to load asset bundle with name: " + bundleName)); } } } public class ConfigurationManager { public enum Toggle { On = 1, Off = 0 } } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] public static class CreatureManager { public static void SetupCreatures(LocationManager.LocationPosition position, string creatureListName, GameObject jotunnLocationContainer, int creatureCount, string creatureYAMLContent) { if (creatureCount != 0) { if (position == LocationManager.LocationPosition.Exterior) { List<string> creatureList = CreateCreatureList(creatureListName, creatureCount, creatureYAMLContent); List<CreatureSpawner> exteriorCreatureSpawners = GetExteriorCreatureSpawners(jotunnLocationContainer); AddCreaturestoSpawnerList(exteriorCreatureSpawners, creatureList); } else { List<string> creatureList2 = CreateCreatureList(creatureListName, creatureCount, creatureYAMLContent); List<CreatureSpawner> interiorCreatureSpawners = GetInteriorCreatureSpawners(jotunnLocationContainer); AddCreaturestoSpawnerList(interiorCreatureSpawners, creatureList2); } } } public static void SetupCreatures(string creatureListName, GameObject gameObject, string creatureYAMLContent) { int count = GetCreatureSpawners(gameObject).Count; if (count != 0) { List<string> creatureList = CreateCreatureList(creatureListName, count, creatureYAMLContent); List<CreatureSpawner> creatureSpawners = GetCreatureSpawners(gameObject); AddCreaturestoSpawnerList(creatureSpawners, creatureList); } } public static List<CreatureSpawner> GetCreatureSpawners(GameObject gameObject) { return gameObject.GetComponentsInChildren<CreatureSpawner>().ToList(); } public static GameObject GetCreaturePrefab(string prefabName) { GameObject prefab = Cache.GetPrefab<GameObject>(prefabName); if ((Object)(object)prefab != (Object)null) { return prefab; } WarpLogger.Logger.LogError((object)("Prefab not found for name:" + prefabName)); return null; } public static void AddCreaturetoSpawner(CreatureSpawner creatureSpawner, string creaturePrefab) { GameObject creaturePrefab2 = GetCreaturePrefab(creaturePrefab); if ((Object)(object)creaturePrefab2 != (Object)null) { creatureSpawner.m_creaturePrefab = creaturePrefab2; WarpLogger.Logger.LogDebug((object)("Creature with name " + creaturePrefab + " was added to " + (object)creatureSpawner)); } else { WarpLogger.Logger.LogError((object)("Creature not found for name: " + creaturePrefab)); } } public static void AddCreaturestoSpawnerList(List<CreatureSpawner> CreatureSpawnerList, List<string> CreatureList) { int num = 0; foreach (CreatureSpawner CreatureSpawner in CreatureSpawnerList) { string creaturePrefab = CreatureList[num % CreatureList.Count]; AddCreaturetoSpawner(CreatureSpawner, creaturePrefab); num++; } } public static List<CreatureSpawner> GetExteriorCreatureSpawners(GameObject location) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) List<CreatureSpawner> list = new List<CreatureSpawner>(); CreatureSpawner[] componentsInChildren = location.GetComponentsInChildren<CreatureSpawner>(); CreatureSpawner[] array = componentsInChildren; foreach (CreatureSpawner val in array) { if ((Object)(object)((Component)val).transform.parent != (Object)null && ((Component)val).transform.position.y <= 5000f) { list.Add(val); WarpLogger.Logger.LogDebug((object)("Exterior creature spawner found in " + ((object)location)?.ToString() + "with name: " + ((Object)val).name)); } } return list; } public static List<CreatureSpawner> GetInteriorCreatureSpawners(GameObject location) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) List<CreatureSpawner> list = new List<CreatureSpawner>(); CreatureSpawner[] componentsInChildren = location.GetComponentsInChildren<CreatureSpawner>(); CreatureSpawner[] array = componentsInChildren; foreach (CreatureSpawner val in array) { if ((Object)(object)((Component)val).transform.parent != (Object)null && ((Component)val).transform.position.y >= 5000f) { list.Add(val); WarpLogger.Logger.LogDebug((object)("Interior creature spawner found in " + ((object)location)?.ToString() + " with name: " + ((Object)((Component)val).transform.parent).name)); } } return list; } public static List<string> CreateCreatureList(string creatureListName, int creatureCount, string yamlContent) { List<string> list = new List<string>(); YamlStream yamlStream = new YamlStream(); yamlStream.Load(new StringReader(yamlContent)); YamlMappingNode yamlMappingNode = (YamlMappingNode)yamlStream.Documents[0].RootNode; if (yamlMappingNode.Children.ContainsKey(new YamlScalarNode(creatureListName))) { YamlSequenceNode yamlSequenceNode = yamlMappingNode.Children[new YamlScalarNode(creatureListName)] as YamlSequenceNode; int count = yamlSequenceNode.Children.Count; int num = Random.Range(0, count - 1); for (int i = 0; i < creatureCount; i++) { int index = (num + i) % count; YamlScalarNode yamlScalarNode = (YamlScalarNode)yamlSequenceNode.Children[index]; list.Add(yamlScalarNode.Value); } } return list; } } [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public class LocationManager { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] public enum LocationPosition { Interior, Exterior } public static void AddLocation(AssetBundle assetBundle, string locationName, string creatureYAMLContent, string creatureListName, int creatureCount, string lootYAMLContent, string lootListName, LocationConfig locationConfig) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown GameObject val = assetBundle.LoadAsset<GameObject>(locationName); GameObject val2 = ZoneManager.Instance.CreateLocationContainer(val); CreatureManager.SetupCreatures(LocationPosition.Exterior, creatureListName, val2, creatureCount, creatureYAMLContent); if (LootManager.isLootListVersion2(lootYAMLContent)) { List<DropData> lootList = LootManager.ParseContainerYaml_v2(lootListName, lootYAMLContent); List<Container> locationsContainers = LootManager.GetLocationsContainers(val2); LootManager.SetupChestLoot(locationsContainers, lootList); } else { List<string> lootList2 = LootManager.CreateLootList(lootListName, lootYAMLContent); List<Container> locationsContainers2 = LootManager.GetLocationsContainers(val2); LootManager.SetupChestLoot(locationsContainers2, lootList2); List<DropOnDestroyed> locationsDropOnDestroyeds = LootManager.GetLocationsDropOnDestroyeds(val2, LocationPosition.Exterior); if (locationsDropOnDestroyeds != null) { LootManager.SetupDropOnDestroyedLoot(locationsDropOnDestroyeds, lootList2); } } CustomLocation val3 = new CustomLocation(val2, true, locationConfig); ZoneManager.Instance.AddCustomLocation(val3); } public static void AddLocation(AssetBundle assetBundle, string locationName, string creatureYAMLContent, string creatureListName, string lootYAMLContent, string lootListName, LocationConfig locationConfig) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown GameObject val = assetBundle.LoadAsset<GameObject>(locationName); GameObject val2 = ZoneManager.Instance.CreateLocationContainer(val); CreatureManager.SetupCreatures(creatureListName, val2, creatureYAMLContent); if (LootManager.isLootListVersion2(lootYAMLContent)) { List<DropData> lootList = LootManager.ParseContainerYaml_v2(lootListName, lootYAMLContent); List<Container> locationsContainers = LootManager.GetLocationsContainers(val2); LootManager.SetupChestLoot(locationsContainers, lootList); } else { List<string> lootList2 = LootManager.CreateLootList(lootListName, lootYAMLContent); List<Container> locationsContainers2 = LootManager.GetLocationsContainers(val2); LootManager.SetupChestLoot(locationsContainers2, lootList2); } CustomLocation val3 = new CustomLocation(val2, true, locationConfig); ZoneManager.Instance.AddCustomLocation(val3); } public static void AddLocation(AssetBundle assetBundle, string locationName, LocationConfig locationConfig) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown GameObject val = assetBundle.LoadAsset<GameObject>(locationName); GameObject val2 = ZoneManager.Instance.CreateLocationContainer(val); CustomLocation val3 = new CustomLocation(val2, true, locationConfig); ZoneManager.Instance.AddCustomLocation(val3); } public static void AddLocation(GameObject locationGameObject, LocationConfig locationConfig) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown GameObject val = ZoneManager.Instance.CreateLocationContainer(locationGameObject); CustomLocation val2 = new CustomLocation(val, true, locationConfig); ZoneManager.Instance.AddCustomLocation(val2); } } [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public static class LootManager_v2 { public static void SetupContainers(GameObject gameObject, string yamlContent) { List<Container> containers = GetContainers(gameObject); List<DropData> drops = ParseContainerYAML(yamlContent); foreach (Container item in containers) { item.m_defaultItems.m_drops = drops; } } public static void SetupPickableItems(GameObject gameObject, string yamlContent, string listName) { List<PickableItem> pickableItems = GetPickableItems(gameObject); List<RandomItem> list = ParsePickableYaml(listName, yamlContent); RandomItem[] randomItemPrefabs = list.ToArray(); foreach (PickableItem item in pickableItems) { item.m_randomItemPrefabs = randomItemPrefabs; } } public static List<DropData> ParseContainerYAML(string yamlContent) { //IL_007c: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) List<DropData> list = new List<DropData>(); IDeserializer deserializer = new DeserializerBuilder().Build(); Dictionary<string, List<Dictionary<string, object>>> dictionary = deserializer.Deserialize<Dictionary<string, List<Dictionary<string, object>>>>(yamlContent); foreach (List<Dictionary<string, object>> value in dictionary.Values) { foreach (Dictionary<string, object> item2 in value) { string text = item2["item"].ToString(); GameObject prefab = Cache.GetPrefab<GameObject>(text); if ((Object)(object)prefab != (Object)null) { DropData val = default(DropData); val.m_item = prefab; val.m_stackMin = int.Parse(item2["stackMin"].ToString()); val.m_stackMax = int.Parse(item2["stackMax"].ToString()); val.m_weight = float.Parse(item2["weight"].ToString()); val.m_dontScale = false; DropData item = val; list.Add(item); } } } return list; } public static List<RandomItem> ParsePickableYaml(string pickablelootListName, string yamlContent) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) List<RandomItem> list = new List<RandomItem>(); IDeserializer deserializer = new DeserializerBuilder().Build(); Dictionary<string, List<Dictionary<string, object>>> dictionary = deserializer.Deserialize<Dictionary<string, List<Dictionary<string, object>>>>(yamlContent); if (dictionary.ContainsKey(pickablelootListName)) { WarpLogger.Logger.LogDebug((object)("Found loot list with name " + pickablelootListName + " in pickable list Yaml file")); foreach (Dictionary<string, object> item2 in dictionary[pickablelootListName]) { string text = item2["item"].ToString(); GameObject prefab = Cache.GetPrefab<GameObject>(text); if ((Object)(object)prefab != (Object)null) { ItemDrop component = prefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { RandomItem val = default(RandomItem); val.m_itemPrefab = component; val.m_stackMin = int.Parse(item2["stackMin"].ToString()); val.m_stackMax = int.Parse(item2["stackMax"].ToString()); RandomItem item = val; list.Add(item); WarpLogger.Logger.LogDebug((object)("Added item with name: " + text + " to pickable list " + pickablelootListName + " with stackMin: " + item.m_stackMin + ", stackMax: " + item.m_stackMax)); } } else { WarpLogger.Logger.LogWarning((object)("Prefab for item " + text + " not found.")); } } } else { WarpLogger.Logger.LogError((object)("Failed to find loot list with name: " + pickablelootListName + " in loot list Yaml file")); } return list; } public static List<Container> GetContainers(GameObject room) { return room.GetComponentsInChildren<Container>().ToList(); } public static List<PickableItem> GetPickableItems(GameObject room) { return room.GetComponentsInChildren<PickableItem>().ToList(); } } public class PieceManager { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public static void ReplaceResourceDrops(CustomLocation location) { Piece[] componentsInChildren = location.Prefab.GetComponentsInChildren<Piece>(); Piece[] array = componentsInChildren; foreach (Piece val in array) { if (!((Object)(object)((Component)val).transform.parent != (Object)null)) { continue; } WarpLogger.Logger.LogDebug((object)("Piece with name " + ((object)val)?.ToString() + " found in location with name: " + (object)location)); Requirement[] resources = val.m_resources; Requirement[] array2 = resources; foreach (Requirement val2 in array2) { if (val2 != null) { WarpLogger.Logger.LogDebug((object)("Resource with name " + ((object)val2)?.ToString() + " found in piece with name: " + ((Object)((Component)val).transform.parent).name)); } } } } } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] public static class TraderManager { [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] public class TradeItemYAML { public string PrefabName { get; set; } public string Action { get; set; } public int Quality { get; set; } public int Stack { get; set; } public int Price { get; set; } public string RequiredGlobalKey { get; set; } } [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] public class SellItem { public ItemDrop m_prefab { get; set; } public int m_stack { get; set; } public int m_price { get; set; } public string m_requiredGlobalKey { get; set; } } public static Dictionary<string, List<TradeItem>> buyItemLists = new Dictionary<string, List<TradeItem>>(); public static Dictionary<string, List<SellItem>> sellItemLists = new Dictionary<string, List<SellItem>>(); public static void AddTraderBuyItems(GameObject locationContainer, List<TradeItem> traderItems) { Trader componentInChildren = locationContainer.GetComponentInChildren<Trader>(); if ((Object)(object)componentInChildren == (Object)null) { WarpLogger.Logger.LogWarning((object)("Failed to find Trader script in location with name: " + (object)locationContainer)); } else { componentInChildren.m_items = traderItems; } } public static void BuildBuyItemList(string traderItemYamlContent, string traderName) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown List<TradeItem> list = new List<TradeItem>(); IDeserializer deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); Dictionary<string, List<TradeItemYAML>> dictionary = deserializer.Deserialize<Dictionary<string, List<TradeItemYAML>>>(traderItemYamlContent); if (dictionary == null || !dictionary.ContainsKey(traderName)) { WarpLogger.Logger.LogWarning((object)("Parsed data is null or trader name: " + traderName + " does not exist in the YAML content.")); return; } List<TradeItemYAML> list2 = dictionary[traderName]; foreach (TradeItemYAML item2 in list2) { GameObject prefab = Cache.GetPrefab<GameObject>(item2.PrefabName); if (!(item2.Action != "buy")) { ItemDrop component = prefab.GetComponent<ItemDrop>(); if (item2.Quality != 1) { component.SetQuality(item2.Quality); } TradeItem item = new TradeItem { m_prefab = component, m_stack = item2.Stack, m_price = item2.Price, m_requiredGlobalKey = item2.RequiredGlobalKey }; list.Add(item); Debug.Log((object)("Added item with name: " + item2.PrefabName + " to trader buy list with name: " + traderName)); } } buyItemLists.Add(traderName, list); } public static void BuildSellItemList(string traderItemYamlContent, string traderName) { List<SellItem> list = new List<SellItem>(); IDeserializer deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); Dictionary<string, List<TradeItemYAML>> dictionary = deserializer.Deserialize<Dictionary<string, List<TradeItemYAML>>>(traderItemYamlContent); List<TradeItemYAML> list2 = dictionary[traderName]; foreach (TradeItemYAML item2 in list2) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item2.PrefabName); if (!(item2.Action != "sell")) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if (item2.Quality != 0) { component.SetQuality(item2.Quality); } SellItem item = new SellItem { m_prefab = component, m_stack = item2.Stack, m_price = item2.Price, m_requiredGlobalKey = item2.RequiredGlobalKey }; list.Add(item); } } sellItemLists.Add(traderName, list); } } public class WarpLogger { [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(1)] public static readonly ManualLogSource Logger = Logger.CreateLogSource("MoreWorldLocations"); } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] public class LootManager : MonoBehaviour { public static List<string> CreateLootList(string lootListName, string yamlContent) { YamlStream yamlStream = new YamlStream(); yamlStream.Load(new StringReader(yamlContent)); YamlMappingNode yamlMappingNode = (YamlMappingNode)yamlStream.Documents[0].RootNode; List<string> list = new List<string>(); if (yamlMappingNode.Children.ContainsKey(new YamlScalarNode(lootListName))) { WarpLogger.Logger.LogDebug((object)("Found loot list with name " + lootListName + " in loot list Yaml file")); YamlSequenceNode yamlSequenceNode = yamlMappingNode.Children[new YamlScalarNode(lootListName)] as YamlSequenceNode; foreach (YamlNode item in yamlSequenceNode) { YamlScalarNode yamlScalarNode = item as YamlScalarNode; list.Add(yamlScalarNode.Value); WarpLogger.Logger.LogDebug((object)("Added item with name: " + item?.ToString() + " to loot list with name " + lootListName)); } } else { WarpLogger.Logger.LogError((object)("Failed to find loot list with name: " + lootListName + " in loot list Yaml file")); } return list; } public static bool isLootListVersion2(string yamlContent) { YamlStream yamlStream = new YamlStream(); yamlStream.Load(new StringReader(yamlContent)); YamlMappingNode yamlMappingNode = (YamlMappingNode)yamlStream.Documents[0].RootNode; if (yamlMappingNode.Children.ContainsKey(new YamlScalarNode("version"))) { YamlScalarNode yamlScalarNode = (YamlScalarNode)yamlMappingNode.Children[new YamlScalarNode("version")]; string value = yamlScalarNode.Value; if (value == "2.0") { WarpLogger.Logger.LogDebug((object)"Version is 2"); return true; } return false; } WarpLogger.Logger.LogDebug((object)"Version not found in YAML file"); return false; } public static List<string> ParseContainerYaml_v1(string lootListName, string yamlContent) { YamlStream yamlStream = new YamlStream(); yamlStream.Load(new StringReader(yamlContent)); YamlMappingNode yamlMappingNode = (YamlMappingNode)yamlStream.Documents[0].RootNode; List<string> list = new List<string>(); if (yamlMappingNode.Children.ContainsKey(new YamlScalarNode(lootListName))) { WarpLogger.Logger.LogDebug((object)("Found loot list with name " + lootListName + " in loot list Yaml file")); YamlSequenceNode yamlSequenceNode = yamlMappingNode.Children[new YamlScalarNode(lootListName)] as YamlSequenceNode; foreach (YamlNode item in yamlSequenceNode) { YamlScalarNode yamlScalarNode = item as YamlScalarNode; list.Add(yamlScalarNode.Value); WarpLogger.Logger.LogDebug((object)("Added item with name: " + item?.ToString() + " to loot list with name " + lootListName)); } } else { WarpLogger.Logger.LogError((object)("Failed to find loot list with name: " + lootListName + " in loot list Yaml file")); } return list; } public static List<DropData> ParseContainerYaml_v2(string lootListName, string yamlContent) { //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) List<DropData> list = new List<DropData>(); string input = RemoveVersionFromYaml(yamlContent); IDeserializer deserializer = new DeserializerBuilder().Build(); Dictionary<string, List<Dictionary<string, object>>> dictionary = deserializer.Deserialize<Dictionary<string, List<Dictionary<string, object>>>>(input); if (dictionary.ContainsKey(lootListName)) { WarpLogger.Logger.LogDebug((object)("Found loot list with name " + lootListName + " in loot list Yaml file")); foreach (Dictionary<string, object> item2 in dictionary[lootListName]) { string text = item2["item"].ToString(); GameObject prefab = Cache.GetPrefab<GameObject>(text); if ((Object)(object)prefab != (Object)null) { if (!int.TryParse(item2["stackMin"].ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { result = 2; WarpLogger.Logger.LogWarning((object)("Failed to parse stackMin for item " + text + ". Defaulting to " + result)); } if (!int.TryParse(item2["stackMax"].ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2)) { result2 = 3; WarpLogger.Logger.LogWarning((object)("Failed to parse stackMax for item " + text + ". Defaulting to " + result2)); } if (!float.TryParse(item2["weight"].ToString(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { result3 = 1f; WarpLogger.Logger.LogWarning((object)("Failed to parse weight for item " + text + ". Defaulting to " + result3)); } DropData val = default(DropData); val.m_item = prefab; val.m_stackMin = result; val.m_stackMax = result2; val.m_weight = result3; val.m_dontScale = false; DropData item = val; list.Add(item); WarpLogger.Logger.LogDebug((object)("Added item with name: " + text + " to loot list " + lootListName + " with stackMin: " + item.m_stackMin + ", stackMax: " + item.m_stackMax + ", weight: " + item.m_weight)); } else { WarpLogger.Logger.LogWarning((object)("Prefab for item " + text + " not found.")); } } } else { WarpLogger.Logger.LogError((object)("Failed to find loot list with name: " + lootListName + " in loot list Yaml file")); } return list; } private static string RemoveVersionFromYaml(string yamlContent) { string[] array = yamlContent.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries); List<string> list = new List<string>(); bool flag = false; string[] array2 = array; foreach (string text in array2) { if (text.TrimStart(Array.Empty<char>()).StartsWith("version")) { flag = true; } else { list.Add(text); } } if (flag) { WarpLogger.Logger.LogDebug((object)"Version key found and removed from YAML content."); } return string.Join("\n", list); } public static List<Container> GetLocationsContainers(GameObject location) { List<Container> list = new List<Container>(); Container[] componentsInChildren = location.GetComponentsInChildren<Container>(); Container[] array = componentsInChildren; foreach (Container val in array) { list.Add(val); WarpLogger.Logger.LogDebug((object)("Container found in " + ((object)location)?.ToString() + "with name: " + ((Object)val).name)); } return list; } public static List<Container> GetLocationsContainers(GameObject location, LocationManager.LocationPosition locationPosition) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) List<Container> list = new List<Container>(); Container[] componentsInChildren = location.GetComponentsInChildren<Container>(); Container[] array = componentsInChildren; foreach (Container val in array) { if (((Component)val).transform.position.y <= 5000f) { list.Add(val); WarpLogger.Logger.LogDebug((object)("Container found in " + ((object)location)?.ToString() + "with name: " + ((Object)val).name)); } } return list; } public static void SetupChestLoot(List<Container> containerList, List<string> lootList) { foreach (Container container in containerList) { DropTable defaultItems = CreateDropTable(lootList, 2, 3); container.m_defaultItems = defaultItems; WarpLogger.Logger.LogDebug((object)("Container with name " + ((Object)container).name + " has received new dropTable")); } } public static void SetupChestLoot(List<Container> containerList, List<DropData> lootList) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown DropTable val = new DropTable(); val.m_dropMax = 2; val.m_drops = lootList; foreach (Container container in containerList) { container.m_defaultItems = val; WarpLogger.Logger.LogDebug((object)("Container with name " + ((Object)container).name + " has received new dropTable")); } } public static List<DropOnDestroyed> GetLocationsDropOnDestroyeds(GameObject location, LocationManager.LocationPosition locationPosition) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) List<DropOnDestroyed> list = new List<DropOnDestroyed>(); DropOnDestroyed[] componentsInChildren = location.GetComponentsInChildren<DropOnDestroyed>(); DropOnDestroyed[] array = componentsInChildren; foreach (DropOnDestroyed val in array) { if (((Object)val).name.StartsWith("loot_drop") && ((Component)val).transform.position.y <= 5000f) { list.Add(val); WarpLogger.Logger.LogDebug((object)("DropOnDestroyed found in " + ((object)location)?.ToString() + "with name: " + ((Object)val).name)); } } if (list.Count > 0) { return list; } return null; } public static void SetupDropOnDestroyedLoot(List<DropOnDestroyed> dropOnDestroyedList, List<string> lootList) { foreach (DropOnDestroyed dropOnDestroyed in dropOnDestroyedList) { DropTable dropWhenDestroyed = CreateDropTable(lootList, 1, 2); dropOnDestroyed.m_dropWhenDestroyed = dropWhenDestroyed; } } public static DropTable CreateDropTable(List<string> itemNames, int dropMin, int dropMax) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) DropTable val = new DropTable { m_dropMin = dropMin, m_dropMax = dropMax, m_dropChance = 1f, m_oneOfEach = true }; foreach (string itemName in itemNames) { WarpLogger.Logger.LogDebug((object)("Attempting to add item with name " + itemName)); GameObject prefab = Cache.GetPrefab<GameObject>(itemName); if ((Object)(object)prefab != (Object)null) { DropData val2 = default(DropData); val2.m_item = prefab; val2.m_stackMin = 2; val2.m_stackMax = 4; val2.m_weight = 1f; val2.m_dontScale = false; DropData item = val2; val.m_drops.Add(item); WarpLogger.Logger.LogDebug((object)("Added item with name " + itemName)); } else { WarpLogger.Logger.LogError((object)("Prefab for " + itemName + " not found")); } } return val; } public static void AddContainerToChild(GameObject parentGameObject, string childName, DropTable dropTable) { Transform val = parentGameObject.transform.Find(childName); if ((Object)(object)val != (Object)null) { Container val2 = ((Component)val).gameObject.AddComponent<Container>(); if ((Object)(object)val2 != (Object)null) { val2.m_defaultItems = dropTable; val2.m_name = "Chest"; val2.m_width = 4; val2.m_height = 2; } } else { WarpLogger.Logger.LogError((object)("Child GameObject (" + childName + ") not found in parent GameObject (" + ((object)parentGameObject)?.ToString() + ")")); } } } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] public class YAMLManager { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] public enum Toggle { On = 1, Off = 0 } public string creatureYAMLContent; public string lootYAMLContent; public string defaultCreatureYamlContent; public string customCreatureYamlContent; public string defaultlootYamlContent; public string customlootYamlContent; public string defaultPickableItemContent; public string customPickableItemContent; public string defaultTraderYamlContent; public string customTraderYamlContent; public void ParseDefaultYamls() { defaultCreatureYamlContent = AssetUtils.LoadTextFromResources("warpalicious.More_World_Locations_CreatureLists.yml"); defaultlootYamlContent = AssetUtils.LoadTextFromResources("warpalicious.More_World_Locations_LootLists.yml"); } public void ParseCustomYamls() { string path = Path.Combine(Paths.ConfigPath, "warpalicious.More_World_Locations_CreatureLists.yml"); if (File.Exists(path)) { customCreatureYamlContent = File.ReadAllText(path); WarpLogger.Logger.LogInfo((object)"Successfully loaded warpalicious.More_World_Locations_CreatureLists.yml file from BepinEx config folder"); } string path2 = Path.Combine(Paths.ConfigPath, "warpalicious.More_World_Locations_LootLists.yml"); if (File.Exists(path2)) { customlootYamlContent = File.ReadAllText(path2); WarpLogger.Logger.LogInfo((object)"Successfully loaded warpalicious.More_World_Locations_LootLists.yml file from BepinEx config folder"); } } public void ParseCreatureYaml(string filename) { defaultCreatureYamlContent = AssetUtils.LoadTextFromResources(filename + "_CreatureLists.yml"); string path = Path.Combine(Paths.ConfigPath, filename + "_CreatureLists.yml"); if (File.Exists(path)) { customCreatureYamlContent = File.ReadAllText(path); WarpLogger.Logger.LogInfo((object)("Successfully loaded + " + filename + "_CreatureLists.yml file from BepinEx config folder")); } } public void ParseTraderYaml(string filename) { defaultTraderYamlContent = AssetUtils.LoadTextFromResources(filename); string path = Path.Combine(Paths.ConfigPath, filename); if (File.Exists(path)) { customTraderYamlContent = File.ReadAllText(path); WarpLogger.Logger.LogInfo((object)("Successfully loaded + " + filename + " file from BepinEx config folder")); } } public void ParseContainerYaml(string filename) { defaultlootYamlContent = AssetUtils.LoadTextFromResources(filename + "_ContainerLists.yml"); string path = Path.Combine(Paths.ConfigPath, filename + "_ContainerLists.yml"); if (File.Exists(path)) { customlootYamlContent = File.ReadAllText(path); WarpLogger.Logger.LogInfo((object)("Successfully loaded + " + filename + "_ContainerLists.yml file from BepinEx config folder")); } } public void ParsePickableItemYaml(string filename) { defaultPickableItemContent = AssetUtils.LoadTextFromResources(filename + "_PickableItemLists.yml"); string path = Path.Combine(Paths.ConfigPath, filename + "_PickableItemLists.yml"); if (File.Exists(path)) { customPickableItemContent = File.ReadAllText(path); WarpLogger.Logger.LogInfo((object)("Successfully loaded + " + filename + "_PickableItemLists.yml file from BepinEx config folder")); } } public string GetCreatureYamlContent(ConfigurationManager.Toggle useCustomCreatureYaml) { if (useCustomCreatureYaml == ConfigurationManager.Toggle.On) { return customCreatureYamlContent; } return defaultCreatureYamlContent; } public string GetLootYamlContent(ConfigurationManager.Toggle useCustomLootYaml) { if (useCustomLootYaml == ConfigurationManager.Toggle.On) { return customlootYamlContent; } return defaultlootYamlContent; } public string GetPickableItemContent(ConfigurationManager.Toggle useCustomPickableItemYAML) { if (useCustomPickableItemYAML == ConfigurationManager.Toggle.On) { return customPickableItemContent; } return defaultPickableItemContent; } } } namespace Dungeon_The_Ritual { [HarmonyPatch(typeof(ZNet), "OnNewConnection")] public static class RegisterAndCheckVersion { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] private static void Prefix(ZNetPeer peer, ref ZNet __instance) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown Underground_RuinsPlugin.Dungeon_The_RitualLogger.LogDebug((object)"Registering version RPC handler"); peer.m_rpc.Register<ZPackage>("Underground_Ruins_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_Dungeon_The_Ritual_Version); Underground_RuinsPlugin.Dungeon_The_RitualLogger.LogDebug((object)"Invoking version check"); ZPackage val = new ZPackage(); val.Write("1.0.1"); peer.m_rpc.Invoke("Underground_Ruins_VersionCheck", new object[1] { val }); } } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] public static class VerifyClient { private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance) { if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc)) { return true; } Underground_RuinsPlugin.Dungeon_The_RitualLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting")); rpc.Invoke("Error", new object[1] { 3 }); return false; } private static void Postfix(ZNet __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "Underground_RuinsRequestAdminSync", new object[1] { (object)new ZPackage() }); } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] public class ShowConnectionError { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] private static void Postfix(FejdStartup __instance) { if (__instance.m_connectionFailedPanel.activeSelf) { __instance.m_connectionFailedError.fontSizeMax = 25f; __instance.m_connectionFailedError.fontSizeMin = 15f; TMP_Text connectionFailedError = __instance.m_connectionFailedError; connectionFailedError.text = connectionFailedError.text + "\n" + Underground_RuinsPlugin.ConnectionError; } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] public static class RemoveDisconnectedPeerFromVerified { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] private static void Prefix(ZNetPeer peer, ref ZNet __instance) { if (__instance.IsServer()) { Underground_RuinsPlugin.Dungeon_The_RitualLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list")); RpcHandlers.ValidatedPeers.Remove(peer.m_rpc); } } } [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public static class RpcHandlers { public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>(); public static void RPC_Dungeon_The_Ritual_Version(ZRpc rpc, ZPackage pkg) { string text = pkg.ReadString(); Underground_RuinsPlugin.Dungeon_The_RitualLogger.LogInfo((object)("Version check, local: 1.0.1, remote: " + text)); if (text != "1.0.1") { Underground_RuinsPlugin.ConnectionError = "Underground_Ruins Installed: 1.0.1\n Needed: " + text; if (ZNet.instance.IsServer()) { Underground_RuinsPlugin.Dungeon_The_RitualLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting...")); rpc.Invoke("Error", new object[1] { 3 }); } } else if (!ZNet.instance.IsServer()) { Underground_RuinsPlugin.Dungeon_The_RitualLogger.LogInfo((object)"Received same version from server!"); } else { Underground_RuinsPlugin.Dungeon_The_RitualLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list")); ValidatedPeers.Add(rpc); } } } } namespace Underground_Ruins { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] public class AttachPuzzle : MonoBehaviour { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] public class PuzzleStand { [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(1)] public GameObject PuzzleStandGameObject = new GameObject(); public bool puzzleStand = false; public bool puzzlePickable = false; public int puzzlePosition = 0; } public List<PuzzleStand> puzzleItemStandList = new List<PuzzleStand>(); public List<PuzzleStand> puzzleSolutionPickableList = new List<PuzzleStand>(); public List<int> puzzleSolution = new List<int>(); public int countPuzzleStands = 8; public Door targetDoor; public Switch puzzleSwitch; public string solutionItemName = "SurtlingCore"; public void Initialize() { //IL_002b: 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) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown Debug.Log((object)"AttachPuzzle called Initialize"); GetItemStands(); GetPickables(); GameObject val = FindGameObjectInSector("PuzzleSecretDoor", ((Component)this).gameObject.transform.position); if ((Object)(object)val != (Object)null) { Debug.Log((object)"Found door in scene"); targetDoor = val.GetComponent<Door>(); } GameObject val2 = FindGameObjectInSector("PuzzleLever", ((Component)this).gameObject.transform.position); if ((Object)(object)val2 != (Object)null) { Debug.Log((object)"Found switch in scene"); puzzleSwitch = val2.GetComponentInChildren<Switch>(); } if ((Object)(object)puzzleSwitch != (Object)null) { Debug.Log((object)"Switch assigned"); puzzleSwitch.m_onUse = new Callback(OnSwitchUse); } else { Debug.Log((object)"Failed to assign switch"); } GenerateSolution(); } public GameObject FindGameObjectInSector(string prefabName, Vector3 position) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0014: Unknown result type (might be due to invalid IL or missing references) int stableHashCode = StringExtensionMethods.GetStableHashCode(prefabName); Vector2i zone = ZoneSystem.GetZone(position); int num = ZDOMan.instance.SectorToIndex(zone); if (num >= 0 && num < ZDOMan.instance.m_objectsBySector.Length) { List<ZDO> list = ZDOMan.instance.m_objectsBySector[num]; if (list != null) { foreach (ZDO item in list) { int prefab = item.GetPrefab(); if (prefab == stableHashCode) { Debug.Log((object)("Match found for prefab hash: " + stableHashCode)); ZNetView obj = ZNetScene.instance.FindInstance(item); GameObject val = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)val != (Object)null) { Debug.Log((object)("Found instance of GameObject with name " + prefabName + " in sector")); return val; } Debug.Log((object)"No active GameObject instance found for matching ZDO"); } } } else { Debug.Log((object)"Sector list is null, no ZDOs to check"); } } else { Debug.Log((object)("Sector index out of range: " + num)); } Debug.Log((object)"No matching GameObject found in sector"); return null; } public void GetItemStands() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < countPuzzleStands; i++) { string text = i + "_PuzzleStand"; GameObject val = FindGameObjectInSector(text, ((Component)this).gameObject.transform.position); if ((Object)(object)val == (Object)null) { Debug.Log((object)("Cant not find puzzle stand with name " + text + " in scene")); continue; } Debug.Log((object)("Found puzzle stand with name " + text + " in scene")); PuzzleStand item = new PuzzleStand { PuzzleStandGameObject = val, puzzleStand = true, puzzlePickable = false, puzzlePosition = i }; puzzleItemStandList.Add(item); } } public void GetPickables() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < countPuzzleStands; i++) { string text = i + "_PuzzlePickable"; GameObject val = FindGameObjectInSector(text, ((Component)this).gameObject.transform.position); if ((Object)(object)val == (Object)null) { Debug.Log((object)("Cant not find puzzle stand with name " + text + " in scene")); continue; } Debug.Log((object)("Found puzzle stand with name " + text + " in scene")); PuzzleStand item = new PuzzleStand { PuzzleStandGameObject = val, puzzleStand = false, puzzlePickable = true, puzzlePosition = i }; puzzleSolutionPickableList.Add(item); } } public bool OnSwitchUse(Switch caller, Humanoid user, ItemData item) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (CheckSolution()) { targetDoor.Open(Vector3.forward); Debug.Log((object)"Puzzle solved! Door is opening."); return true; } Debug.Log((object)"Puzzle solution is incorrect."); return false; } public void GenerateSolution() { Debug.Log((object)"Generating solution"); if (puzzleSolutionPickableList.Count <= 0 || puzzleSolutionPickableList == null) { return; } puzzleSolution.Clear(); for (int i = 0; i < countPuzzleStands; i++) { puzzleSolution.Add(0); } for (int j = 0; j < countPuzzleStands; j++) { int num = Random.Range(0, 2); int.TryParse(((Object)puzzleSolutionPickableList[j].PuzzleStandGameObject).name[0].ToString(), out var result); if (result >= 0 && result < puzzleSolution.Count) { puzzleSolution[result] = num; if (num == 0) { puzzleSolutionPickableList[j].PuzzleStandGameObject.GetComponent<Pickable>().SetPicked(true); } } else { Debug.LogWarning((object)("Position " + result + " is out of bounds for puzzle solution list.")); } } Debug.Log((object)("Solution for puzzle generated. Answer is: " + string.Join(",", puzzleSolution))); } public bool CheckSolution() { List<int> list = Enumerable.Repeat(0, countPuzzleStands).ToList(); if (puzzleItemStandList == null || (Object)(object)targetDoor == (Object)null) { return false; } foreach (PuzzleStand puzzleItemStand in puzzleItemStandList) { if (puzzleItemStand == null) { continue; } ItemStand component = puzzleItemStand.PuzzleStandGameObject.GetComponent<ItemStand>(); if ((Object)(object)component == (Object)null || (Object)(object)component.m_nview == (Object)null || component.m_nview.GetZDO() == null) { continue; } string visualName = component.m_visualName; Debug.Log((object)("Checking solution. Item attached has name " + visualName)); if (int.TryParse(((Object)puzzleItemStand.PuzzleStandGameObject).name[0].ToString(), out var result)) { if (result >= 0 && result < list.Count) { list[result] = ((visualName == solutionItemName) ? 1 : 0); } else { Debug.LogWarning((object)("Position " + result + " is out of bounds for temp puzzle solution.")); } } else { Debug.LogError((object)("Failed to parse position from GameObject name: " + ((Object)((Component)component).gameObject).name)); } } bool result2 = list.SequenceEqual(puzzleSolution); Debug.Log((object)("Checking solution. Provided answer is: " + string.Join(",", list))); return result2; } } public class CustomPrefabs { public static void RegisterKitPrefabs() { Logger.LogDebug((object)"RegisterKitPrefabs invoked"); List<string> list = new List<string> { "BFD_CastleKit_groundtorch_blue.prefab", "BFD_Pickable_SurtlingCoreStand.prefab", "BFD_Spawner_GreydwarfNest.prefab", "BFD_Vegvisir_GDKing.prefab", "PuzzleSecretDoor.prefab", "PuzzleLever.prefab", "Warp_Greydwarf_Root.prefab", "Warp_MineRock_Copper.prefab", "BFD_CryptKey.prefab", "BFD_chest_spawner1.prefab", "BFD_chest_spawner2.prefab", "BFD_Modular5_chest_loot1.prefab", "BFD_Modular5_chest_loot2.prefab", "BFD_Modular5_Spawner1.prefab", "BFD_Modular5_Spawner2.prefab", "BFD_Modular5_Spawner3.prefab", "BFD_Modular6_Spawner1.prefab", "BFD_Modular6_Spawner2.prefab", "BFD_Modular6_Spawner3.prefab", "BFD_Modular6_Spawner5.prefab", "BFD_Modular7_Spawner1.prefab", "BFD_Modular7_Spawner2.prefab", "BFD_Modular8_Puzzle_chest_loot1.prefab", "BFD_Modular8_Puzzle_chest_loot2.prefab", "BFD_Modular8_Puzzle_chest_loot3.prefab", "BFD_Modular8_Puzzle_Pickable1.prefab", "BFD_Modular8_Puzzle_Pickable2.prefab", "BFD_Modular8_Puzzle_Pickable3.prefab", "BFD_Modular9_Pickable1.prefab", "BFD_Modular9_Pickable2.prefab", "BFD_Modular9_Pickable3.prefab", "BFD_Modular9_Pickable4.prefab", "BFD_Modular9_Pickable5.prefab", "BFD_Modular9_Pickable6.prefab", "BFD_Modular9_Spawner1.prefab", "BFD_Modular9_Spawner2.prefab", "BFD_Modular9_Spawner3.prefab", "BFD_Modular9_Spawner4.prefab", "BFD_Modular12_Spawner1.prefab", "BFD_Modular12_Spawner2.prefab", "BFD_Modular12_Spawner3.prefab", "BFD_Modular13_Spawner1.prefab", "BFD_Modular14_chest_loot1.prefab", "BFD_Modular14_Pickable2.prefab", "BFD_Modular14_Pickable3.prefab", "BFD_Modular14_Spawner1.prefab", "BFD_ModularElbow_Spawner1.prefab", "BFD_ModularElbow_Spawner2.prefab", "BFD_ModularEnd1_Pickable2.prefab", "BFD_ModularEnd1_Pickable3.prefab", "BFD_ModularEnd4_chest_loot1.prefab", "BFD_ModularEnd6_chest_loot1.prefab", "BFD_ModularEnd7_chest_loot1.prefab", "BFD_Stairwell5_chest_loot1.prefab" }; for (int i = 0; i <= 7; i++) { list.Add($"{i}_PuzzleStand.prefab"); list.Add($"{i}_PuzzlePickable.prefab"); } foreach (string item in list) { RegisterCustomPrefab(Underground_RuinsPlugin.assetBundle, item); } PrefabManager.OnVanillaPrefabsAvailable -= RegisterKitPrefabs; } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public static GameObject RegisterCustomPrefab(AssetBundle bundle, string assetName) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown string value = assetName.Replace(".prefab", ""); if (!string.IsNullOrEmpty(value)) { CustomPrefab val = new CustomPrefab(bundle, assetName, true); Logger.LogDebug((object)("Registering " + ((Object)val.Prefab).name)); if (val != null && val.IsValid()) { PrefabExtension.FixReferences(val.Prefab, true); PrefabManager.Instance.AddPrefab(val); return val.Prefab; } } return null; } } public class DungeonGenerator_Patch { [HarmonyPatch(typeof(DungeonGenerator), "Load")] public class DungeonGenerator_Awake_Patch { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public static void Prefix(DungeonGenerator __instance) { if (((Object)((Component)__instance).gameObject).name == "DG_BlackForestDungeon(Clone)") { ((Component)__instance).gameObject.AddComponent<AttachPuzzle>(); } } } [HarmonyPatch(typeof(DungeonGenerator), "Generate", new Type[] { typeof(int), typeof(SpawnMode) })] public class DungeonGenerator_Generate_Patch { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public static void Postfix(DungeonGenerator __instance) { if (((Object)((Component)__instance).gameObject).name == "DG_BlackForestDungeon(Clone)" && !((Object)(object)__instance == (Object)null)) { ((Component)__instance).gameObject.GetComponent<AttachPuzzle>().Initialize(); } } } } [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public class RoomManager { public static Dictionary<string, RoomConfig> AllLimitRooms = new Dictionary<string, RoomConfig> { { "BFD_Modular8_Puzzle", new RoomConfig { ThemeName = "Underground Ruins", Weight = 0f } }, { "BFD_Modular12_Solution", new RoomConfig { ThemeName = "Underground Ruins", Weight = 0f } } }; public static Dictionary<string, RoomConfig> AllRoomConfigs = new Dictionary<string, RoomConfig> { { "BFD_MainEntrance2", new RoomConfig { ThemeName = "Underground Ruins", Entrance = true, Weight = 1f } }, { "BFD_Modular3", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_Modular5", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f, MinPlaceOrder = 2 } }, { "BFD_Modular6", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_Modular7", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_Modular9", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_Modular10", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_Modular11", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_Modular12", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_Modular13", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_Modular14", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_ModularElbow", new RoomConfig { ThemeName = "Underground Ruins", Weight = 1f } }, { "BFD_ModularEnd3", new RoomConfig { ThemeName = "Underground Ruins", Endcap = true, EndcapPrio = 0, Weight = 1f } }, { "BFD_ModularEnd4", new RoomConfig { ThemeName = "Underground Ruins", Endcap = true, EndcapPrio = 0, Weight = 1f } }, { "BFD_ModularEnd5", new RoomConfig { ThemeName = "Underground Ruins", Endcap = true, EndcapPrio = 0, Weight = 1f } }, { "BFD_ModularEnd6", new RoomConfig { ThemeName = "Underground Ruins", Endcap = true, EndcapPrio = 0, Weight = 1f } }, { "BFD_ModularEnd7", new RoomConfig { ThemeName = "Underground Ruins", Endcap = true, EndcapPrio = 0, Weight = 1f } }, { "BFD_ModularEnd8", new RoomConfig { ThemeName = "Underground Ruins", Endcap = true, EndcapPrio = 0, Weight = 1f } }, { "BFD_ModularEnd9", new RoomConfig { ThemeName = "Underground Ruins", Endcap = true, EndcapPrio = 0, Weight = 1f } }, { "BFD_ModularDivider1", new RoomConfig { ThemeName = "Underground Ruins", Entrance = false, Endcap = false, Divider = true, EndcapPrio = 0, Weight = 1f } }, { "BFD_Stairwell3", new RoomConfig { ThemeName = "Underground Ruins", Weight = 0.8f } }, { "BFD_Stairwell5", new RoomConfig { ThemeName = "Underground Ruins", Weight = 0.9f } } }; public static void AddAllRooms() { AssetBundle assetBundle = Underground_RuinsPlugin.assetBundle; foreach (KeyValuePair<string, RoomConfig> allRoomConfig in AllRoomConfigs) { AddRoom(assetBundle, allRoomConfig.Key, allRoomConfig.Value, Underground_RuinsPlugin.dungeonBFDYamlManager.GetCreatureYamlContent(Underground_RuinsPlugin.MWD_UndergroundRuins_CreatureYaml_Config.Value), Underground_RuinsPlugin.MWD_UndergroundRuins_CreatureList_Config.Value, Underground_RuinsPlugin.dungeonBFDYamlManager.GetLootYamlContent(Underground_RuinsPlugin.MWD_UndergroundRuins_LootYaml_Config.Value), Underground_RuinsPlugin.MWD_UndergroundRuins_LootList_Config.Value, Underground_RuinsPlugin.dungeonBFDYamlManager.GetPickableItemContent(Underground_RuinsPlugin.MWD_UndergroundRuins_PickableItemYaml_Config.Value), Underground_RuinsPlugin.MWD_UndergroundRuins_PickableItemList_Config.Value); } foreach (KeyValuePair<string, RoomConfig> allLimitRoom in AllLimitRooms) { AddLimitRooms(assetBundle, allLimitRoom.Key, allLimitRoom.Value, Underground_RuinsPlugin.dungeonBFDYamlManager.GetCreatureYamlContent(Underground_RuinsPlugin.MWD_UndergroundRuins_CreatureYaml_Config.Value), Underground_RuinsPlugin.MWD_UndergroundRuins_CreatureList_Config.Value, Underground_RuinsPlugin.dungeonBFDYamlManager.GetLootYamlContent(Underground_RuinsPlugin.MWD_UndergroundRuins_LootYaml_Config.Value), Underground_RuinsPlugin.MWD_UndergroundRuins_LootList_Config.Value, Underground_RuinsPlugin.dungeonBFDYamlManager.GetPickableItemContent(Underground_RuinsPlugin.MWD_UndergroundRuins_PickableItemYaml_Config.Value), Underground_RuinsPlugin.MWD_UndergroundRuins_PickableItemList_Config.Value); } DungeonManager.OnVanillaRoomsAvailable -= AddAllRooms; } public static void RegisterTheme(GameObject dungeonGameObject, string themeName) { if (DungeonManager.Instance.RegisterDungeonTheme(dungeonGameObject, themeName)) { WarpLogger.Logger.LogDebug((object)("RoomTheme with name " + themeName + " was successfully registered to " + (object)dungeonGameObject)); } else { WarpLogger.Logger.LogError((object)("RoomTheme with name " + themeName + " failed to register")); } } public static void AddRoom(AssetBundle assetBundle, string prefabName, RoomConfig roomConfig, string creatureYAMLContent, string creatureListName, string lootYAMLContent, string lootListName, string pickableItemYAMLContent, string pickableListName) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown GameObject val = assetBundle.LoadAsset<GameObject>(prefabName); GameObject val2 = ZoneManager.Instance.CreateLocationContainer(val); AddTentaRoot(val2); List<DropData> lootList = LootManager.ParseContainerYaml_v2(lootListName, lootYAMLContent); List<Container> locationsContainers = LootManager.GetLocationsContainers(val2); LootManager.SetupChestLoot(locationsContainers, lootList); LootManager_v2.SetupPickableItems(val2, pickableItemYAMLContent, pickableListName); CreatureManager.SetupCreatures(creatureListName, val2, creatureYAMLContent); CustomRoom val3 = new CustomRoom(val2, true, roomConfig); DungeonManager.Instance.AddCustomRoom(val3); } public static void AddLimitRooms(AssetBundle assetBundle, string prefabName, RoomConfig roomConfig, string creatureYAMLContent, string creatureListName, string lootYAMLContent, string lootListName, string pickableItemYAMLContent, string pickableListName) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown GameObject val = assetBundle.LoadAsset<GameObject>(prefabName); GameObject val2 = ZoneManager.Instance.CreateLocationContainer(val); val2.AddComponent<RoomExtras>(); val2.GetComponent<RoomExtras>().PlacementLimit = 1; AddTentaRoot(val2); List<DropData> lootList = LootManager.ParseContainerYaml_v2(lootListName, lootYAMLContent); List<Container> locationsContainers = LootManager.GetLocationsContainers(val2); LootManager.SetupChestLoot(locationsContainers, lootList); LootManager_v2.SetupPickableItems(val2, pickableItemYAMLContent, pickableListName); CreatureManager.SetupCreatures(creatureListName, val2, creatureYAMLContent); CustomRoom val3 = new CustomRoom(val2, true, roomConfig); DungeonManager.Instance.AddCustomRoom(val3); } public static void AddTentaRoot(GameObject gameObject) { EggHatch[] componentsInChildren = gameObject.GetComponentsInChildren<EggHatch>(); if (componentsInChildren.Length != 0) { EggHatch[] array = componentsInChildren; foreach (EggHatch val in array) { val.m_spawnPrefab.GetComponent<CreatureSpawner>().m_creaturePrefab = CreatureManager.GetCreaturePrefab("TentaRoot"); } } } } public class LocationConfigs { public struct LocationRing { public int MinDistance { [<00cb15e2-ff46-40a2-ae2a-484c986e2dfc>IsReadOnly] get; set; } public int MaxDistance { [<00cb15e2-ff46-40a2-ae2a-484c986e2dfc>IsReadOnly] get; set; } public LocationRing(int minDistance, int maxDistance) { MinDistance = minDistance; MaxDistance = maxDistance; } } public static class LocationRings { public static LocationRing Ring1 { get; set; } = new LocationRing(0, 500); public static LocationRing Ring2 { get; set; } = new LocationRing(500, 2000); public static LocationRing Ring3 { get; set; } = new LocationRing(1500, 3000); public static LocationRing Ring4 { get; set; } = new LocationRing(2500, 4000); public static LocationRing Ring5 { get; set; } = new LocationRing(3500, 6000); public static LocationRing Ring6 { get; set; } = new LocationRing(4500, 8500); public static LocationRing Ring7 { get; set; } = new LocationRing(5000, 10500); } [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(1)] public static LocationConfig MWD_TheRitual_Config = new LocationConfig { Biome = (Biome)8, BiomeArea = (BiomeArea)2, Quantity = Underground_RuinsPlugin.MWD_UndergroundRuins_Quantity_Config.Value, Priotized = true, ExteriorRadius = 8f, ClearArea = true, RandomRotation = false, Group = "Dungeon_UndergroundRuins", MinDistanceFromSimilar = 512f, MaxTerrainDelta = 2f, MinAltitude = 10f, MinDistance = LocationRings.Ring3.MinDistance, MaxDistance = LocationRings.Ring6.MaxDistance }; } public class Locations { public static void AddAllLocations() { LocationManager.AddLocation(Underground_RuinsPlugin.dungeonGameObject, LocationConfigs.MWD_TheRitual_Config); ZoneManager.OnVanillaLocationsAvailable -= AddAllLocations; } } [BepInPlugin("warpalicious.Underground_Ruins", "Underground_Ruins", "1.0.1")] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] public class Underground_RuinsPlugin : BaseUnityPlugin { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] public enum Toggle { On = 1, Off = 0 } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order = null; [UsedImplicitly] public bool? Browsable = null; [UsedImplicitly] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(2)] public string Category = null; [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(new byte[] { 2, 1 })] [UsedImplicitly] public Action<ConfigEntryBase> CustomDrawer = null; } [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] private class AcceptableShortcuts : AcceptableValueBase { public AcceptableShortcuts() : base(typeof(KeyboardShortcut)) { } public override object Clamp(object value) { return value; } public override bool IsValid(object value) { return true; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes); } } internal const string ModName = "Underground_Ruins"; internal const string ModVersion = "1.0.1"; internal const string Author = "warpalicious"; private const string ModGUID = "warpalicious.Underground_Ruins"; private static string ConfigFileName = "warpalicious.Underground_Ruins.cfg"; private static string ConfigFileFullPath; internal static string ConnectionError; private readonly Harmony _harmony = new Harmony("warpalicious.Underground_Ruins"); public static readonly ManualLogSource Dungeon_The_RitualLogger; private static readonly ConfigSync ConfigSync; public static YAMLManager dungeonBFDYamlManager; public static AssetBundle assetBundle; public static string bundleName; public static GameObject dungeonGameObject; public Texture2D tex = null; public static ConfigEntry<int> MWD_UndergroundRuins_Quantity_Config; public static ConfigEntry<ConfigurationManager.Toggle> MWD_UndergroundRuins_CreatureYaml_Config; public static ConfigEntry<string> MWD_UndergroundRuins_CreatureList_Config; public static ConfigEntry<ConfigurationManager.Toggle> MWD_UndergroundRuins_LootYaml_Config; public static ConfigEntry<string> MWD_UndergroundRuins_LootList_Config; public static ConfigEntry<ConfigurationManager.Toggle> MWD_UndergroundRuins_PickableItemYaml_Config; public static ConfigEntry<string> MWD_UndergroundRuins_PickableItemList_Config; private static ConfigEntry<Toggle> _serverConfigLocked; public static void LoadAssetBundle() { assetBundle = AssetUtils.LoadAssetBundleFromResources(bundleName, Assembly.GetExecutingAssembly()); if ((Object)(object)assetBundle == (Object)null) { WarpLogger.Logger.LogError((object)("Failed to load asset bundle with name: " + bundleName)); } } public void Awake() { bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; _serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only."); ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); RoomExtras.ApplyPatches(_harmony); SetupWatcher(); LoadAssetBundle(); MWD_UndergroundRuins_Quantity_Config = config("1 - Underground Ruins", "Spawn Quantity", 30, "Amount of attempts world generation will try to place dungeon exterior during world generation"); MWD_UndergroundRuins_CreatureYaml_Config = config("1 - Underground Ruins", "Use Custom Creature YAML file", ConfigurationManager.Toggle.Off, "When Off, location will spawn default creatures. When On, dungeon will select creatures from list in the custom YAML file in BepinEx config folder"); MWD_UndergroundRuins_CreatureList_Config = config("1 - Underground Ruins", "Name of Creature List", "UndergroundRuinsCreatures1", "The name of the creature list to use from YAML file"); MWD_UndergroundRuins_LootYaml_Config = config("1 - Underground Ruins", "Use Custom Loot YAML file", ConfigurationManager.Toggle.Off, "When Off, location will use default loot. When On, dungeon will select loot from list in the custom YAML file in BepinEx config folder"); MWD_UndergroundRuins_LootList_Config = config("1 - Underground Ruins", "Name of Loot List", "UndergroundRuinsLoot1", "The name of the loot list to use from YAML file"); MWD_UndergroundRuins_PickableItemYaml_Config = config("1 - Underground Ruins", "Use Custom PickableItem YAML file", ConfigurationManager.Toggle.Off, "When Off, location will use default loot. When On, dungeon will select loot from list in the custom YAML file in BepinEx config folder"); MWD_UndergroundRuins_PickableItemList_Config = config("1 - Underground Ruins", "Name of PickableItem List", "UndergroundRuinsPickables1", "The name of the loot list to use from YAML file"); dungeonGameObject = assetBundle.LoadAsset<GameObject>("BFD_Exterior"); RoomManager.RegisterTheme(dungeonGameObject, "Underground Ruins"); dungeonBFDYamlManager.ParseDefaultYamls(); dungeonBFDYamlManager.ParseCustomYamls(); dungeonBFDYamlManager.ParsePickableItemYaml("warpalicious.More_World_Locations"); TranslationUtils.AddLocalizations(); PrefabManager.OnVanillaPrefabsAvailable += CustomPrefabs.RegisterKitPrefabs; ZoneManager.OnVanillaLocationsAvailable += Locations.AddAllLocations; DungeonManager.OnVanillaRoomsAvailable += RoomManager.AddAllRooms; if (saveOnConfigSet) { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; ((BaseUnityPlugin)this).Config.Save(); } } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { Dungeon_The_RitualLogger.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch { Dungeon_The_RitualLogger.LogError((object)("There was an issue loading your " + ConfigFileName)); Dungeon_The_RitualLogger.LogError((object)"Please check your config entries for spelling and format!"); } } private ConfigEntry<T> config<[<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags); ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val); SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2); syncedConfigEntry.SynchronizedConfig = synchronizedSetting; return val2; } private ConfigEntry<T> config<[<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } static Underground_RuinsPlugin() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; ConnectionError = ""; Dungeon_The_RitualLogger = Logger.CreateLogSource("Underground_Ruins"); ConfigSync = new ConfigSync("warpalicious.Underground_Ruins") { DisplayName = "Underground_Ruins", CurrentVersion = "1.0.1", MinimumRequiredVersion = "1.0.1" }; dungeonBFDYamlManager = new YAMLManager(); bundleName = "dungeonblackforest"; MWD_UndergroundRuins_Quantity_Config = null; MWD_UndergroundRuins_CreatureYaml_Config = null; MWD_UndergroundRuins_CreatureList_Config = null; MWD_UndergroundRuins_LootYaml_Config = null; MWD_UndergroundRuins_LootList_Config = null; MWD_UndergroundRuins_PickableItemYaml_Config = null; MWD_UndergroundRuins_PickableItemList_Config = null; _serverConfigLocked = null; } } public static class KeyboardExtensions { public static bool IsKeyDown(this KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } public static bool IsKeyHeld(this KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } } public class TranslationUtils { [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(1)] public static CustomLocalization Localization; public static void AddLocalizations() { Localization = LocalizationManager.Instance.GetLocalization(); CustomLocalization localization = Localization; string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "enemy_Thornskar", "Thornskar" } }); } } } namespace LocalizationManager { [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(1)] [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(0)] [PublicAPI] public class Localizer { private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors; private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts; private static readonly ConditionalWeakTable<Localization, string> localizationLanguage; private static readonly List<WeakReference<Localization>> localizationObjects; [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(2)] private static BaseUnityPlugin _plugin; private static readonly List<string> fileExtensions; private static BaseUnityPlugin plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out var value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out var value2)) { text = value2.Aggregate(text, [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null) { if (convertConfigValue == null) { convertConfigValue = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary<string, Func<string>>(); } config.SettingChanged += [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] (object _, EventArgs _) => { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List<WeakReference<Localization>> list = new List<WeakReference<Localization>>(); foreach (WeakReference<Localization> localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference<Localization> item in list) { localizationObjects.Remove(item); } } public static void Load() { LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); } private static void LoadLocalization(Localization __instance, string language) { if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference<Localization>(__instance)); } localizationLanguage.Add(__instance, language); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f) { string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1]; if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text2 = null; if (language != "English") { if (dictionary.ContainsKey(language)) { text2 = File.ReadAllText(dictionary[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text2 = Encoding.UTF8.GetString(array2); } } } if (text2 == null && dictionary.ContainsKey("English")) { text2 = File.ReadAllText(dictionary["English"]); } if (text2 != null) { foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>()) { dictionary2[item2.Key] = item2.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair<string, string> item3 in dictionary2) { UpdatePlaceholderText(__instance, item3.Key); } } static Localizer() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>(); loadedTexts = new Dictionary<string, Dictionary<string, string>>(); localizationLanguage = new ConditionalWeakTable<Localization, string>(); localizationObjects = new List<WeakReference<Localization>>(); fileExtensions = new List<string> { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } [return: <d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(2)] private static byte[] LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } [<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(2)] public static byte[] ReadEmbeddedFileBytes([<d19a41d4-b8f4-41ee-8b21-a4b047800d1a>Nullable(1)] string resourceFileName, Assembly containingAssembly = null) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<acd929a8-1e15-4d09-8079-1999ea7732d6>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<c3d4bac0-a24d-4ad8-963a-002afc682663>Embedded] internal sealed class <c3d4bac0-a24d-4ad8-963a-002afc682663>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<c3d4bac0-a24d-4ad8-963a-002afc682663>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <2806f3cc-6658-4ec4-9453-85ebdea4aacf>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <2806f3cc-6658-4ec4-9453-85ebdea4aacf>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <2806f3cc-6658-4ec4-9453-85ebdea4aacf>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [<c3d4bac0-a24d-4ad8-963a-002afc682663>Embedded] [CompilerGenerated] internal sealed class <4eb4be65-54db-4b08-870c-5200f60306d9>NullableContextAttribute : Attribute { public readonly byte Flag; public <4eb4be65-54db-4b08-870c-5200f60306d9>NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [<c3d4bac0-a24d-4ad8-963a-002afc682663>Embedded] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ServerSync { [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(0)] [PublicAPI] [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] internal abstract class OwnConfigEntryBase { [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(2)] public object LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(0)] [PublicAPI] internal class SyncedConfigEntry<[<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(2)] T> : OwnConfigEntryBase { public readonly ConfigEntry<T> SourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public SyncedConfigEntry(ConfigEntry<T> sourceConfig) { SourceConfig = sourceConfig; } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(0)] [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(2)] internal abstract class CustomSyncedValueBase { public object LocalBaseValue; [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(1)] public readonly string Identifier; [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(1)] public readonly Type Type; private object boxedValue; protected bool localIsOwner; public readonly int Priority; public object BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action ValueChanged; [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] [PublicAPI] [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(0)] internal sealed class CustomSyncedValue<[<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(2)] T> : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(0)] [PublicAPI] internal class ConfigSync { [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(0)] [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(2)] public static ZRpc currentRpc; [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(0)] [HarmonyPatch(typeof(ZNet), "Awake")] internal static class RegisterRPCPatch { [HarmonyPostfix] [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges()); } [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] static void SendAdmin(List<ZNetPeer> peers, bool isAdmin) { ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1] { new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = isAdmin } }); ConfigSync configSync = configSyncs.First(); if (configSync != null) { ((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package)); } } [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] static IEnumerator WatchAdminListChanges() { MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); List<string> CurrentList = new List<string>(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!adminList.GetList().SequenceEqual(CurrentList)) { CurrentList = new List<string>(adminList.GetList()); List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p) { string hostName = p.m_rpc.GetSocket().GetHostName(); return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName })); }).ToList(); List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList(); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } } [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(0)] [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class RegisterClientRPCPatch { [HarmonyPostfix] [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(1)] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { return; } foreach (ConfigSync configSync in configSyncs) { peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync); } } } [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(0)] private class ParsedConfigs { [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(new byte[] { 1, 1, 2 })] public readonly Dictionary<OwnConfigEntryBase, object> configValues = new Dictionary<OwnConfigEntryBase, object>(); [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(new byte[] { 1, 1, 2 })] public readonly Dictionary<CustomSyncedValueBase, object> customValues = new Dictionary<CustomSyncedValueBase, object>(); } [<4eb4be65-54db-4b08-870c-5200f60306d9>NullableContext(0)] [HarmonyPatch(typeof(ZNet), "Shutdown")] private class ResetConfigsOnShutdown { [HarmonyPostfix] private static void Postfix() { ProcessingServerUpdate = true; foreach (ConfigSync configSync in configSyncs) { configSync.resetConfigsFromServer(); configSync.IsSourceOfTruth = true; configSync.InitialSyncDone = false; } ProcessingServerUpdate = false; } } [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(0)] [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private class SendConfigsAfterLogin { [<2806f3cc-6658-4ec4-9453-85ebdea4aacf>Nullable(0)] private class BufferingSocket : ISocket { public volatile bool finished = false; public volatile int versionMatchQueued = -1; public readonly List<ZPackage> Package = new List<ZPackage>(); public readonly ISocket Original; public BufferingSocket(ISocket original) { Original = original; } public bool IsConnected() { return Original.IsConnected(); } public ZPackage Recv() { return Original.Recv(); } public int GetSendQueueSize() { return Original.GetSendQueueSize(); } public int GetCurrentSendRate() { return Original.GetCurrentSendRate(); } public bool IsHost() { return Original.IsHost(); } public void Dispose() { Original.Dispose(); } public bool GotNewData() { return Original.GotNewData(); } public void Close() { Original.Close(); } public string GetEndPointString() { return Original.GetEndPointString(); } public void GetAndResetStats(out int totalSent, out int totalRecv) { Original.GetAndResetStats(ref totalSent, ref totalRecv); } public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec) { Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec); } public ISocket Accept() { return Original.Accept(); } public int GetHostPort() { return Original.GetHostPort(); } public bool Flush() { return Original.Flush(); } public string GetHostName() { return Original.GetHostName(); } public void Versi