Decompiled source of MonsterDB v0.1.1
MonsterDB.dll
Decompiled a month 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.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using MonsterDB.Solution; using MonsterDB.Solution.Behaviors; using MonsterDB.Solution.Methods; using ServerSync; using TMPro; using UnityEngine; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; 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("0.1.1")] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyProduct("MonsterDB")] [assembly: AssemblyCompany("RustyMods")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("MonsterDB")] [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("0.1.1.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<f6024122-3fbc-47fa-8a4c-3dbc1f9fe35a>Embedded] internal sealed class <f6024122-3fbc-47fa-8a4c-3dbc1f9fe35a>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [<f6024122-3fbc-47fa-8a4c-3dbc1f9fe35a>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [CompilerGenerated] internal sealed class <391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [<f6024122-3fbc-47fa-8a4c-3dbc1f9fe35a>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <280c4705-4a7b-4139-8a59-78254fb4951c>NullableContextAttribute : Attribute { public readonly byte Flag; public <280c4705-4a7b-4139-8a59-78254fb4951c>NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace MonsterDB { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [BepInPlugin("RustyMods.MonsterDB", "MonsterDB", "0.1.1")] public class MonsterDBPlugin : BaseUnityPlugin { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] private enum Toggle { On = 1, Off = 0 } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(2)] [UsedImplicitly] public string Category; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 2, 1 })] [UsedImplicitly] public Action<ConfigEntryBase> CustomDrawer; } internal const string ModName = "MonsterDB"; internal const string ModVersion = "0.1.1"; internal const string Author = "RustyMods"; private const string ModGUID = "RustyMods.MonsterDB"; private static readonly string ConfigFileName = "RustyMods.MonsterDB.cfg"; private static readonly string ConfigFileFullPath; internal static string ConnectionError; private readonly Harmony _harmony = new Harmony("RustyMods.MonsterDB"); public static readonly ManualLogSource MonsterDBLogger; public static readonly ConfigSync ConfigSync; public static GameObject m_root; public static MonsterDBPlugin m_plugin; private static ConfigEntry<Toggle> _serverConfigLocked; private static ConfigEntry<Toggle> _shareTextures; private static ConfigEntry<Toggle> _useRandomNames; private static ConfigEntry<Toggle> _autoUpdate; public static bool ShareTextures() { return _shareTextures.Value == Toggle.On; } public static bool UseNames() { return _useRandomNames.Value == Toggle.On; } public static bool AutoUpdate() { return _autoUpdate.Value == Toggle.On; } private void InitConfigs() { _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); _shareTextures = config("2 - Settings", "Server Sync Textures", Toggle.Off, "If on, clients can download textures from server, experimental"); _useRandomNames = config("2 - Settings", "Use Viking Names", Toggle.Off, "If on, any creatures based on Human, will use random names"); _autoUpdate = config("2 - Settings", "Auto Update", Toggle.On, "If on, any changes made to files will automatically update creature"); } public void Awake() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown m_plugin = this; m_root = new GameObject("root"); Object.DontDestroyOnLoad((Object)(object)m_root); m_root.SetActive(false); InitConfigs(); Tutorial.Write(); SpawnMan.Setup(); TextureManager.ReadLocalTextures(); CreatureManager.Setup(); Initialization.ReadLocalFiles(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); SetupWatcher(); } 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 { MonsterDBLogger.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch { MonsterDBLogger.LogError((object)("There was an issue loading your " + ConfigFileName)); MonsterDBLogger.LogError((object)"Please check your config entries for spelling and format!"); } } private ConfigEntry<T> config<[<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>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<[<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>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 MonsterDBPlugin() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; ConnectionError = ""; MonsterDBLogger = Logger.CreateLogSource("MonsterDB"); ConfigSync = new ConfigSync("RustyMods.MonsterDB") { DisplayName = "MonsterDB", CurrentVersion = "0.1.1", MinimumRequiredVersion = "0.1.1" }; m_root = null; m_plugin = null; _serverConfigLocked = null; _shareTextures = null; _useRandomNames = null; _autoUpdate = null; } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] public static class RegisterAndCheckVersion { [<280c4705-4a7b-4139-8a59-78254fb4951c>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 MonsterDBPlugin.MonsterDBLogger.LogDebug((object)"Registering version RPC handler"); peer.m_rpc.Register<ZPackage>("MonsterDB_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_MonsterDB_Version); MonsterDBPlugin.MonsterDBLogger.LogInfo((object)"Invoking version check"); ZPackage val = new ZPackage(); val.Write("0.1.1"); peer.m_rpc.Invoke("MonsterDB_VersionCheck", new object[1] { val }); } } [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] public static class VerifyClient { private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance) { if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc)) { return true; } MonsterDBPlugin.MonsterDBLogger.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(), "MonsterDBRequestAdminSync", new object[1] { (object)new ZPackage() }); } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] public class ShowConnectionError { [<280c4705-4a7b-4139-8a59-78254fb4951c>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" + MonsterDBPlugin.ConnectionError; } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] public static class RemoveDisconnectedPeerFromVerified { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] private static void Prefix(ZNetPeer peer, ref ZNet __instance) { if (__instance.IsServer()) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list")); RpcHandlers.ValidatedPeers.Remove(peer.m_rpc); } } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public static class RpcHandlers { public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>(); public static void RPC_MonsterDB_Version(ZRpc rpc, ZPackage pkg) { string text = pkg.ReadString(); MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Version check, local: 0.1.1, remote: " + text)); if (text != "0.1.1") { MonsterDBPlugin.ConnectionError = "MonsterDB Installed: 0.1.1\n Needed: " + text; if (ZNet.instance.IsServer()) { MonsterDBPlugin.MonsterDBLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting...")); rpc.Invoke("Error", new object[1] { 3 }); } } else if (!ZNet.instance.IsServer()) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)"Received same version from server!"); } else { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list")); ValidatedPeers.Add(rpc); } } public static string ComputeHashForMod() { using SHA256 sHA = SHA256.Create(); byte[] array = sHA.ComputeHash(File.ReadAllBytes(Assembly.GetExecutingAssembly().Location)); StringBuilder stringBuilder = new StringBuilder(); byte[] array2 = array; foreach (byte b in array2) { stringBuilder.Append(b.ToString("X2")); } return stringBuilder.ToString(); } } } namespace MonsterDB.Solution { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public static class Commands { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] [HarmonyPatch(typeof(Terminal), "updateSearch")] private static class Terminal_UpdateSearch_Patch { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] private static bool Prefix(Terminal __instance, string word) { if (!Object.op_Implicit((Object)(object)ZNetScene.instance)) { return true; } if ((Object)(object)__instance.m_search == (Object)null) { return true; } string[] array = ((TMP_InputField)__instance.m_input).text.Split(new char[1] { ' ' }); if (array.Length < 3) { return true; } if (array[0] != "monsterdb") { return true; } HandleSearch(__instance, word, array); return false; } } [HarmonyPatch(typeof(Terminal), "Awake")] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] private static class Terminal_Awake_Patch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_0; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_1; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_2; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_3; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_4; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_5; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_6; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_7; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_8; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_9; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_10; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(new byte[] { 0, 1 })] public static Action<ConsoleEventArgs> <>9__0_11; public static ConsoleEventFailable <>9__0_12; [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_0(ConsoleEventArgs _) { foreach (CommandInfo value in m_commands.Values) { if (value.m_show) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)(value.m_input + " - " + value.m_description)); } } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_1(ConsoleEventArgs _) { Initialization.RemoveAllClones(); Initialization.CloneAll(); Initialization.UpdateAll(); } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_2(ConsoleEventArgs _) { CreatureManager.Import(); Initialization.RemoveAllClones(); Initialization.CloneAll(); Initialization.UpdateAll(); } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_3(ConsoleEventArgs _) { if (!Object.op_Implicit((Object)(object)ZNetScene.instance)) { return; } foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if (Object.op_Implicit((Object)(object)prefab.GetComponent<Character>())) { Write(prefab, writeAll: true); } } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_4(ConsoleEventArgs args) { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text = args[2]; GameObject val = DataBase.TryGetGameObject(text); if ((Object)(object)val == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text)); } else { Write(val); } } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_5(ConsoleEventArgs args) { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text = args[2]; GameObject val = DataBase.TryGetGameObject(text); if ((Object)(object)val == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text)); return; } CreatureManager.Read(((Object)val).name, CreatureManager.IsClone(val)); CreatureManager.Update(val); MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Updated " + ((Object)val).name)); } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_6(ConsoleEventArgs args) { if (args.Length >= 4 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text = args[2]; GameObject val = DataBase.TryGetGameObject(text); if ((Object)(object)val == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text)); return; } string name = args[3]; CreatureManager.Clone(val, name); } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_7(ConsoleEventArgs args) { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text = args[2]; GameObject val = DataBase.TryGetGameObject(text); if ((Object)(object)val == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text)); } else { CreatureManager.Reset(val); } } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_8(ConsoleEventArgs args) { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text = args[2]; GameObject val = DataBase.TryGetGameObject(text); if ((Object)(object)val == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text)); } else if (Object.op_Implicit((Object)(object)val.GetComponent<ItemDrop>())) { ItemDataMethods.Write(val); } } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_9(ConsoleEventArgs args) { if (args.Length >= 4 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text = args[2]; GameObject val = DataBase.TryGetGameObject(text); if ((Object)(object)val == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text)); return; } string name = args[3]; ItemDataMethods.Clone(val, name); } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_10(ConsoleEventArgs args) { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text = args[2]; GameObject val = DataBase.TryGetGameObject(text); if ((Object)(object)val == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text)); } else { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)(SpawnMan.Write(val) ? "Wrote spawn data to disk" : "Failed to find spawn data")); } } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] internal void <Postfix>b__0_11(ConsoleEventArgs args) { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text = args[2]; GameObject val = DataBase.TryGetGameObject(text); if ((Object)(object)val == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text)); } else { CreatureManager.Export(text); } } } internal object <Postfix>b__0_12(ConsoleEventArgs args) { if (args.Length < 2) { return false; } if (!m_commands.TryGetValue(args[1], out var value)) { return false; } value.m_command(args); return true; } } private static void Postfix() { //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Expected O, but got Unknown //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Expected O, but got Unknown //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Expected O, but got Unknown CommandInfo commandInfo = new CommandInfo("help", "Use to list out MonsterDB commands", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs _) => { foreach (CommandInfo value2 in m_commands.Values) { if (value2.m_show) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)(value2.m_input + " - " + value2.m_description)); } } }); CommandInfo commandInfo2 = new CommandInfo("reload", "Reloads all MonsterDB files", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs _) => { Initialization.RemoveAllClones(); Initialization.CloneAll(); Initialization.UpdateAll(); }); CommandInfo commandInfo3 = new CommandInfo("import", "Imports all creature files from Import folder, and reloads data", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs _) => { CreatureManager.Import(); Initialization.RemoveAllClones(); Initialization.CloneAll(); Initialization.UpdateAll(); }); CommandInfo commandInfo4 = new CommandInfo("write_all", "Writes all creatures data to disk", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs _) => { if (!Object.op_Implicit((Object)(object)ZNetScene.instance)) { return; } foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if (Object.op_Implicit((Object)(object)prefab.GetComponent<Character>())) { Write(prefab, writeAll: true); } } }); CommandInfo commandInfo5 = new CommandInfo("write", "[prefabName] Writes creature data to disk", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs args) => { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text8 = args[2]; GameObject val10 = DataBase.TryGetGameObject(text8); if ((Object)(object)val10 == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text8)); } else { Write(val10); } } }); CommandInfo commandInfo6 = new CommandInfo("update", "[prefabName] Reads files and updates creature", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs args) => { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text7 = args[2]; GameObject val9 = DataBase.TryGetGameObject(text7); if ((Object)(object)val9 == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text7)); } else { CreatureManager.Read(((Object)val9).name, CreatureManager.IsClone(val9)); CreatureManager.Update(val9); MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Updated " + ((Object)val9).name)); } } }); CommandInfo commandInfo7 = new CommandInfo("clone", "[prefabName] [cloneName] Clones creature, and saves to disk", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs args) => { if (args.Length >= 4 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text6 = args[2]; GameObject val8 = DataBase.TryGetGameObject(text6); if ((Object)(object)val8 == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text6)); } else { string name2 = args[3]; CreatureManager.Clone(val8, name2); } } }); CommandInfo commandInfo8 = new CommandInfo("reset", "[prefabName] Resets creature data to original state", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs args) => { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text5 = args[2]; GameObject val7 = DataBase.TryGetGameObject(text5); if ((Object)(object)val7 == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text5)); } else { CreatureManager.Reset(val7); } } }); CommandInfo commandInfo9 = new CommandInfo("write_item", "[prefabName] Saves itemData to file for reference", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs args) => { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text4 = args[2]; GameObject val6 = DataBase.TryGetGameObject(text4); if ((Object)(object)val6 == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text4)); } else if (Object.op_Implicit((Object)(object)val6.GetComponent<ItemDrop>())) { ItemDataMethods.Write(val6); } } }); CommandInfo commandInfo10 = new CommandInfo("clone_item", "[prefabName] [cloneName] Clones item to use as a new attack for creatures", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs args) => { if (args.Length >= 4 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text3 = args[2]; GameObject val5 = DataBase.TryGetGameObject(text3); if ((Object)(object)val5 == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text3)); } else { string name = args[3]; ItemDataMethods.Clone(val5, name); } } }); CommandInfo commandInfo11 = new CommandInfo("write_spawn", "[prefabName] Writes to disk spawn data, of current spawn system", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs args) => { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text2 = args[2]; GameObject val4 = DataBase.TryGetGameObject(text2); if ((Object)(object)val4 == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text2)); } else { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)(SpawnMan.Write(val4) ? "Wrote spawn data to disk" : "Failed to find spawn data")); } } }); CommandInfo commandInfo12 = new CommandInfo("export", "[prefabName] Writes creature data to a single YML document to share", [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] (ConsoleEventArgs args) => { if (args.Length >= 3 && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text = args[2]; GameObject val3 = DataBase.TryGetGameObject(text); if ((Object)(object)val3 == (Object)null) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Failed to find prefab: " + text)); } else { CreatureManager.Export(text); } } }); object obj = <>c.<>9__0_12; if (obj == null) { ConsoleEventFailable val = delegate(ConsoleEventArgs args) { if (args.Length < 2) { return false; } if (!m_commands.TryGetValue(args[1], out var value)) { return false; } value.m_command(args); return true; }; <>c.<>9__0_12 = val; obj = (object)val; } ConsoleCommand val2 = new ConsoleCommand("monsterdb", "use help to list out commands", (ConsoleEventFailable)obj, false, false, false, false, false, new ConsoleOptionsFetcher(Enumerable.ToList), false, false, true); } } [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] private class CommandInfo { public readonly string m_input; public readonly string m_description; public readonly bool m_show; public readonly Action<ConsoleEventArgs> m_command; public CommandInfo(string input, string description, Action<ConsoleEventArgs> command, bool show = true) { m_input = input; m_description = description; m_command = command; m_show = show; m_commands[m_input] = this; } } private static readonly Dictionary<string, CommandInfo> m_commands = new Dictionary<string, CommandInfo>(); private static List<string> MonsterNames = new List<string>(); private static List<string> ItemNames = new List<string>(); private static void HandleSearch(Terminal __instance, string word, string[] strArray) { bool flag; switch (word) { case "reload": case "import": case "write_spawn": case "help": flag = true; break; default: flag = false; break; } if (flag) { TMP_Text search = __instance.m_search; if (1 == 0) { } string text = word switch { "reload" => "<color=red>Reloads all MonsterDB files</color>", "import" => "<color=yellow>Imports all creature files from Import folder, and reload data</color>", "write_spawn" => "<color=yellow>Tries to export spawn system data of creature</color>, <color=red>location dependant</color>", "help" => "<color=white>Lists out MonsterDB commands and descriptions</color>", _ => "", }; if (1 == 0) { } search.text = text; return; } if (1 == 0) { } List<string> list; switch (word) { case "write": case "clone": list = GetMonsterList(); break; case "update": case "reset": list = GetUpdateList(); break; case "write_item": case "clone_item": list = GetItemList(); break; default: list = new List<string>(); break; } if (1 == 0) { } List<string> list2 = list; list2.Sort(); string currentSearch = strArray[2]; List<string> list3; if (!Utility.IsNullOrWhiteSpace(currentSearch)) { int num = list2.IndexOf(currentSearch); list3 = ((num != -1) ? list2.GetRange(num, list2.Count - num) : list2); list3 = list3.FindAll((string x) => x.ToLower().Contains(currentSearch.ToLower())); } else { list3 = list2; } __instance.m_lastSearch.Clear(); __instance.m_lastSearch.AddRange(list3); __instance.m_lastSearch.Remove(word); __instance.m_search.text = ""; int num2 = 10; int num3 = Math.Min(__instance.m_lastSearch.Count, num2); for (int i = 0; i < num3; i++) { string text2 = __instance.m_lastSearch[i]; int num4 = text2.ToLower().IndexOf(word.ToLower(), StringComparison.Ordinal); TMP_Text search2 = __instance.m_search; search2.text = search2.text + __instance.safeSubstring(text2, 0, num4) + " "; } if (__instance.m_lastSearch.Count > num2) { int num5 = __instance.m_lastSearch.Count - num2; TMP_Text search3 = __instance.m_search; search3.text += $"... {num5} more."; } } private static void Write(GameObject prefab, bool writeAll = false) { if (!Object.op_Implicit((Object)(object)prefab.GetComponent<Player>())) { string folderPath; if (CreatureManager.IsClone(prefab)) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)"Creature is a MonsterDB clone, will not write to disk"); } else if (CreatureManager.Write(prefab, out folderPath, clone: false, "", writeAll)) { MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Saved " + ((Object)prefab).name + " at:")); MonsterDBPlugin.MonsterDBLogger.LogInfo((object)folderPath); } } } private static List<string> GetMonsterList() { if (MonsterNames.Count > 0) { return MonsterNames; } List<string> list = new List<string>(); foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if (!CreatureManager.IsClone(prefab) && Object.op_Implicit((Object)(object)prefab.GetComponent<Character>())) { list.Add(((Object)prefab).name); } } MonsterNames = list; return list; } private static List<string> GetItemList() { if (ItemNames.Count > 0) { return ItemNames; } List<string> list = new List<string>(); foreach (GameObject value in DataBase.m_allObjects.Values) { if (!((Object)(object)value == (Object)null) && !ItemDataMethods.IsClone(value) && Object.op_Implicit((Object)(object)value.GetComponent<ItemDrop>())) { list.Add(((Object)value).name); } } ItemNames = list; return list; } private static List<string> GetUpdateList() { return CreatureManager.m_data.Keys.ToList(); } } [Serializable] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public class CharacterData { public string ClonedFrom = ""; public string PrefabName = ""; public string Name = ""; public string Group = ""; public string Faction = ""; public bool Boss; public bool DoNotHideBossHUD; public string BossEvent = ""; public string DefeatSetGlobalKey = ""; public bool AISkipTarget; public float CrouchSpeed; public float WalkSpeed; public float Speed; public float TurnSpeed; public float RunSpeed; public float RunTurnSpeed; public float FlySlowSpeed; public float FlyFastSpeed; public float FlyTurnSpeed; public float Acceleration; public float JumpForce; public float JumpForceForward; public float JumpForceTiredFactor; public float AirControl; public bool CanSwim; public float SwimDepth; public float SwimSpeed; public float SwimTurnSpeed; public float SwimAcceleration; public string GroundTilt = ""; public float GroundTiltSpeed; public bool Flying; public float JumpStaminaUsage; public bool DisableWhileSleeping; public bool TolerateWater; public bool TolerateFire; public bool TolerateSmoke; public bool TolerateTar; public float Health; public string BluntResistance = "Normal"; public string SlashResistance = "Normal"; public string PierceResistance = "Normal"; public string ChopResistance = "Normal"; public string PickaxeResistance = "Normal"; public string FireResistance = "Normal"; public string FrostResistance = "Normal"; public string LightningResistance = "Normal"; public string PoisonResistance = "Normal"; public string SpiritResistance = "Normal"; public bool StaggerWhenBlocked; public float StaggerDamageFactor; } [Serializable] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] public class EffectInfo { public string PrefabName = ""; public bool Enabled; public int Variant = -1; public bool Attach; public bool Follow; public bool InheritParentRotation; public bool InheritParentScale; public bool MultiplyParentVisualScale; public bool RandomRotation; public bool Scale; public string ChildTransform = ""; } [Serializable] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public class AttackData { public string OriginalPrefab = ""; public string Name = ""; public string AnimationState = ""; public int ToolTier; public float Damage; public float Blunt; public float Slash; public float Pierce; public float Chop; public float Pickaxe; public float Fire; public float Frost; public float Lightning; public float Poison; public float Spirit; public float AttackForce; public bool Dodgeable; public bool Blockable; public string SpawnOnHit = ""; public string SpawnOnHitTerrain = ""; public string AttackStatusEffect = ""; public float AttackStatusEffectChance; public string AttackType = ""; public string AttackAnimation = ""; public bool HitTerrain; public bool HitFriendly; public float DamageMultiplier; public float DamageMultiplierPerMissingHP; public float DamageMultiplierByTotalHealthMissing; public float ForceMultiplier; public float StaggerMultiplier; public float RecoilPushback; public int SelfDamage; public string AttackOriginJoint = ""; public float AttackRange; public float AttackHeight; public float AttackOffset; public string SpawnOnTrigger = ""; public bool ToggleFlying; public bool Attach; public float AttackAngle; public float AttackRayWidth; public float MaxYAngle; public bool LowerDamagePerHit; public bool HitThroughWalls; public float AttackRangeMinimum; public float AttackInterval; public float AttackMaxAngle; public string Projectile = ""; } [Serializable] public class RandomItemData { [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(1)] public string PrefabName = ""; public float Chance; } [Serializable] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] public class ProjectileData { public string Name = ""; public float Damage; public float Blunt; public float Slash; public float Pierce; public float Chop; public float Pickaxe; public float Fire; public float Frost; public float Lightning; public float Poison; public float Spirit; public float AOE; public bool Dodgeable; public bool Blockable; public float AttackForce; public float BackstabBonus; public string StatusEffect = ""; public float HealthReturn; public bool CanHitWater; public float Duration; public float Gravity; public float Drag; public float RayRadius; public bool StayAfterHitStatic; public bool StayAfterHitDynamic; public float StayDuration; public bool Bounce; public bool BounceOnWater; public float BouncePower; public float BounceRoughness; public int MaxBounces; public float MinBounceVelocity; public bool RespawnItemOnHit; public bool SpawnOnDuration; public string SpawnOnHit = ""; public float SpawnOnHitChance; public int SpawnCount; public List<string> RandomSpawnOnHit = new List<string>(); public int RandomSpawnOnHitCount; public bool RandomSpawnSkipLava; public bool StaticHitOnly; public bool GroundHitOnly; public bool SpawnRandomRotation; } [Serializable] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public class MonsterAIData { public float ViewRange; public float ViewAngle; public float HearRange; public bool MistVision; public float IdleSoundInterval; public float IdleSoundChance; public string PathAgentType = ""; public float MoveMinAngle; public bool SmoothMovement; public bool SerpentMovement; public float SerpentTurnRadius; public float JumpInterval; public float RandomCircleInterval; public float RandomMoveInterval; public float RandomMoveRange; public bool RandomFly; public float ChanceToTakeOff; public float ChanceToLand; public float GroundDuration; public float AirDuration; public float MaxLandAltitude; public float TakeoffTime; public float FlyAltitudeMin; public float FlyAltitudeMax; public float FlyAbsMinAltitude; public bool AvoidFire; public bool AfraidOfFire; public bool AvoidWater; public bool AvoidLava; public bool SkipLavaTargets; public bool Aggravatable; public bool PassiveAggressive; public string SpawnMessage = ""; public string DeathMessage = ""; public string AlertedMessage = ""; public float FleeRange; public float FleeAngle; public float FleeInterval; public float AlertRange; public bool FleeIfHurtWhenTargetCannotBeReached; public float FleeUnreachableSinceAttack; public float FleeUnreachableSinceHurt; public bool FleeIfNotAlerted; public float FleeIfLowHealth; public float FleeTimeSinceHurt; public bool FleeInLava; public bool CirculateWhileCharging; public bool CirculateWhileChargingFlying; public bool EnableHuntPlayer; public bool AttackPlayerObjects; public int PrivateAreaTriggerThreshold; public float InterceptTimeMax; public float InterceptTimeMin; public float MaxChaseDistance; public float MinAttackInterval; public float CircleTargetInterval; public float CircleTargetDuration; public float CircleTargetDistance; public bool Sleeping; public float WakeupRange; public bool NoiseWakeup; public float MaxNoiseWakeupRange; public float WakeupDelayMin; public float WakeupDelayMax; public bool AvoidLand; public List<string> ConsumeItems = new List<string>(); public float ConsumeRange; public float ConsumeSearchRange; public float ConsumeSearchInterval; } [Serializable] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public class AnimalAIData { public float ViewRange; public float ViewAngle; public float HearRange; public bool MistVision; public float IdleSoundInterval; public float IdleSoundChance; public string PathAgentType = ""; public float MoveMinAngle; public bool SmoothMovement; public bool SerpentMovement; public float SerpentTurnRadius; public float JumpInterval; public float RandomCircleInterval; public float RandomMoveInterval; public float RandomMoveRange; public bool RandomFly; public float ChanceToTakeOff; public float ChanceToLand; public float GroundDuration; public float AirDuration; public float MaxLandAltitude; public float TakeoffTime; public float FlyAltitudeMin; public float FlyAltitudeMax; public float FlyAbsMinAltitude; public bool AvoidFire; public bool AfraidOfFire; public bool AvoidWater; public bool AvoidLava; public bool SkipLavaTargets; public bool Aggravatable; public bool PassiveAggressive; public string SpawnMessage = ""; public string DeathMessage = ""; public string AlertedMessage = ""; public float FleeRange; public float FleeAngle; public float FleeInterval; } [Serializable] public class CharacterDropData { [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(1)] public string PrefabName = ""; public int AmountMin; public int AmountMax; public float Chance; public bool OnePerPlayer; public bool LevelMultiplier; public bool DoNotScale; } [Serializable] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] public class TameableData { public float FedDuration; public float TamingTime; public bool StartTamed; public bool Commandable; public float UnsummonDistance; public float UnsummonOnOwnerLogoutSeconds; public string LevelUpOwnerSkill = ""; public float LevelUpFactor; public bool DropSaddleOnDeath; public List<string> RandomStartingName = new List<string>(); } [Serializable] public class ProcreationData { public float UpdateInterval; public float TotalCheckRange; public int MaxCreatures; public float PartnerCheckRange; public float PregnancyChance; public float PregnancyDuration; public int RequiredLovePoints; [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(1)] public string Offspring = ""; public int MinOffspringLevel; public float SpawnOffset; } [Serializable] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public class NPCTalkData { public string Name = ""; public float MaxRange; public float GreetRange; public float ByeRange; public float Offset; public float MinTalkInterval; public float HideDialogueDelay; public float RandomTalkInterval; public float RandomTalkChance; public List<string> RandomTalk = new List<string>(); public List<string> RandomTalkInFactionBase = new List<string>(); public List<string> RandomGreets = new List<string>(); public List<string> RandomGoodbye = new List<string>(); public List<string> PrivateAreaAlarm = new List<string>(); public List<string> Aggravated = new List<string>(); } [Serializable] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public class GrowUpData { public float GrowTime; public bool InheritTame; public string GrownPrefab = ""; public List<AltGrownData> AltGrownPrefabs = new List<AltGrownData>(); } [Serializable] public class AltGrownData { [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(1)] public string GrownPrefab = ""; public float Weight; } [Serializable] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] public class LevelEffectData { public float Scale; public float Hue; public float Saturation; public float Value; public bool SetEmissiveColor; public VisualMethods.ColorData EmissiveColor = new VisualMethods.ColorData(); public string EnableObject = ""; } [Serializable] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] public class CreatureData { public VisualMethods.ScaleData m_scale = new VisualMethods.ScaleData(); public VisualMethods.ScaleData m_ragdollScale = new VisualMethods.ScaleData(); public Dictionary<string, VisualMethods.MaterialData> m_materials = new Dictionary<string, VisualMethods.MaterialData>(); public CharacterData m_characterData = new CharacterData(); public CharacterEffects m_effects = new CharacterEffects(); public List<ItemAttackData> m_defaultItems = new List<ItemAttackData>(); public List<ItemAttackData> m_randomWeapons = new List<ItemAttackData>(); public List<ItemAttackData> m_randomArmors = new List<ItemAttackData>(); public List<ItemAttackData> m_randomShields = new List<ItemAttackData>(); public List<RandomItemData> m_randomItems = new List<RandomItemData>(); public List<RandomItemSetsData> m_randomSets = new List<RandomItemSetsData>(); public MonsterAIData m_monsterAIData = new MonsterAIData(); public AnimalAIData m_animalAIData = new AnimalAIData(); public List<CharacterDropData> m_characterDrops = new List<CharacterDropData>(); public TameableData m_tameable = new TameableData(); public ProcreationData m_procreation = new ProcreationData(); public NPCTalkData m_npcTalk = new NPCTalkData(); public GrowUpData m_growUp = new GrowUpData(); public List<LevelEffectData> m_levelEffects = new List<LevelEffectData>(); public Dictionary<string, bool> m_particles = new Dictionary<string, bool>(); public VisualMethods.HumanData m_humanData = new VisualMethods.HumanData(); } [Serializable] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] public class ItemAttackData { public AttackData m_attackData = new AttackData(); public ItemEffects m_effects = new ItemEffects(); } [Serializable] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] public class RandomItemSetsData { public string m_name = ""; public List<ItemAttackData> m_items = new List<ItemAttackData>(); } [Serializable] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] public class CharacterEffects { public List<EffectInfo> m_hitEffects = new List<EffectInfo>(); public List<EffectInfo> m_critHitEffects = new List<EffectInfo>(); public List<EffectInfo> m_backstabHitEffects = new List<EffectInfo>(); public List<EffectInfo> m_deathEffects = new List<EffectInfo>(); public List<EffectInfo> m_waterEffects = new List<EffectInfo>(); public List<EffectInfo> m_tarEffects = new List<EffectInfo>(); public List<EffectInfo> m_slideEffects = new List<EffectInfo>(); public List<EffectInfo> m_jumpEffects = new List<EffectInfo>(); public List<EffectInfo> m_flyingContinuousEffects = new List<EffectInfo>(); public List<EffectInfo> m_pickupEffects = new List<EffectInfo>(); public List<EffectInfo> m_dropEffects = new List<EffectInfo>(); public List<EffectInfo> m_consumeItemEffects = new List<EffectInfo>(); public List<EffectInfo> m_equipEffects = new List<EffectInfo>(); public List<EffectInfo> m_perfectBlockEffects = new List<EffectInfo>(); public List<EffectInfo> m_alertedEffects = new List<EffectInfo>(); public List<EffectInfo> m_idleSounds = new List<EffectInfo>(); public List<EffectInfo> m_wakeupEffects = new List<EffectInfo>(); public List<EffectInfo> m_birthEffects = new List<EffectInfo>(); public List<EffectInfo> m_loveEffects = new List<EffectInfo>(); public List<EffectInfo> m_tamedEffects = new List<EffectInfo>(); public List<EffectInfo> m_soothEffects = new List<EffectInfo>(); public List<EffectInfo> m_petEffects = new List<EffectInfo>(); public List<EffectInfo> m_unSummonEffects = new List<EffectInfo>(); public List<EffectInfo> m_randomTalkFX = new List<EffectInfo>(); public List<EffectInfo> m_randomGreetFX = new List<EffectInfo>(); public List<EffectInfo> m_randomGoodbyeFX = new List<EffectInfo>(); } [Serializable] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public class ItemEffects { public List<EffectInfo> m_hitEffects = new List<EffectInfo>(); public List<EffectInfo> m_hitTerrainEffects = new List<EffectInfo>(); public List<EffectInfo> m_blockEffects = new List<EffectInfo>(); public List<EffectInfo> m_startEffects = new List<EffectInfo>(); public List<EffectInfo> m_holdStartEffects = new List<EffectInfo>(); public List<EffectInfo> m_equipEffects = new List<EffectInfo>(); public List<EffectInfo> m_unEquipEffects = new List<EffectInfo>(); public List<EffectInfo> m_triggerEffects = new List<EffectInfo>(); public List<EffectInfo> m_trailStartEffects = new List<EffectInfo>(); } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public static class CreatureManager { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] [HarmonyPatch(typeof(ZNet), "Awake")] private static class ZNet_Awake_Patch { private static void Postfix() { UpdateServer(); } } public static readonly string m_folderPath; public static readonly string m_creatureFolderPath; public static readonly string m_cloneFolderPath; private static readonly string m_exportFolderPath; private static readonly string m_importFolderPath; private static readonly CustomSyncedValue<string> m_serverDataFiles; private static readonly Dictionary<string, CreatureData> m_originalData; public static Dictionary<string, CreatureData> m_data; public static readonly Dictionary<string, CreatureData> m_localData; public static readonly Dictionary<string, GameObject> m_clones; private static FileSystemWatcher m_creatureWatcher; private static FileSystemWatcher m_cloneWatcher; private static bool m_writing; private static void UpdateServer() { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { MonsterDBPlugin.MonsterDBLogger.LogDebug((object)"Server: Updating server sync creature & clones"); ISerializer serializer = new SerializerBuilder().Build(); m_serverDataFiles.Value = serializer.Serialize(m_data); } } public static bool IsClone(GameObject creature) { return m_clones.ContainsKey(((Object)creature).name); } public static void Setup() { m_serverDataFiles.ValueChanged += ReadServerFiles; SetupFileWatch(); if (!Directory.Exists(m_folderPath)) { Directory.CreateDirectory(m_folderPath); } if (!Directory.Exists(m_creatureFolderPath)) { Directory.CreateDirectory(m_creatureFolderPath); } if (!Directory.Exists(m_cloneFolderPath)) { Directory.CreateDirectory(m_cloneFolderPath); } if (!Directory.Exists(m_importFolderPath)) { Directory.CreateDirectory(m_importFolderPath); } if (!Directory.Exists(m_exportFolderPath)) { Directory.CreateDirectory(m_exportFolderPath); } } private static void SetupFileWatch() { if (!Directory.Exists(m_folderPath)) { Directory.CreateDirectory(m_folderPath); } if (!Directory.Exists(m_creatureFolderPath)) { Directory.CreateDirectory(m_creatureFolderPath); } if (!Directory.Exists(m_cloneFolderPath)) { Directory.CreateDirectory(m_cloneFolderPath); } if (!Directory.Exists(m_importFolderPath)) { Directory.CreateDirectory(m_importFolderPath); } m_creatureWatcher = new FileSystemWatcher(m_creatureFolderPath, "*.yml") { EnableRaisingEvents = true, IncludeSubdirectories = true, SynchronizingObject = ThreadingHelper.SynchronizingObject, NotifyFilter = NotifyFilters.LastWrite }; m_creatureWatcher.Changed += OnCreatureFileChange; m_cloneWatcher = new FileSystemWatcher(m_cloneFolderPath, "*.yml") { EnableRaisingEvents = true, IncludeSubdirectories = true, SynchronizingObject = ThreadingHelper.SynchronizingObject, NotifyFilter = NotifyFilters.LastWrite }; m_cloneWatcher.Changed += OnCloneFileChange; FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(m_importFolderPath, "*.yml") { EnableRaisingEvents = true, IncludeSubdirectories = true, SynchronizingObject = ThreadingHelper.SynchronizingObject, NotifyFilter = NotifyFilters.LastWrite }; fileSystemWatcher.Changed += OnImportFileChange; } private static void OnImportFileChange(object sender, FileSystemEventArgs e) { if (!MonsterDBPlugin.AutoUpdate() || m_writing || !Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) { return; } try { string fileName = Path.GetFileName(e.Name); IDeserializer deserializer = new DeserializerBuilder().Build(); string input = File.ReadAllText(e.FullPath); CreatureData creatureData = deserializer.Deserialize<CreatureData>(input); GameObject val = DataBase.TryGetGameObject(creatureData.m_characterData.PrefabName); if (!((Object)(object)val == (Object)null)) { m_data[creatureData.m_characterData.PrefabName] = creatureData; UpdateServer(); Update(val); MonsterDBPlugin.MonsterDBLogger.LogDebug((object)(((Object)val).name + " data changed: " + fileName)); } } catch { Helpers.LogParseFailure(e.FullPath); } } private static void OnCloneFileChange(object sender, FileSystemEventArgs e) { if (MonsterDBPlugin.AutoUpdate() && !m_writing && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { string fileName = Path.GetFileName(e.Name); string cloneFolderName = GetCloneFolderName(e.FullPath); GameObject val = DataBase.TryGetGameObject(cloneFolderName); if (!((Object)(object)val == (Object)null)) { Read(cloneFolderName, isClone: true); Update(val); MonsterDBPlugin.MonsterDBLogger.LogDebug((object)(cloneFolderName + " data changed: " + fileName)); } } } private static void OnCreatureFileChange(object sender, FileSystemEventArgs e) { if (MonsterDBPlugin.AutoUpdate() && !m_writing && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { string fileName = Path.GetFileName(e.Name); string creatureFolderName = GetCreatureFolderName(e.FullPath); GameObject val = DataBase.TryGetGameObject(creatureFolderName); if (!((Object)(object)val == (Object)null)) { Read(creatureFolderName); Update(val); MonsterDBPlugin.MonsterDBLogger.LogDebug((object)(creatureFolderName + " data changed: " + fileName)); } } } private static string GetCloneFolderName(string fullPath) { return fullPath.Replace(m_cloneFolderPath, string.Empty).Split(new char[1] { Path.DirectorySeparatorChar })[1]; } private static string GetCreatureFolderName(string fullPath) { return fullPath.Replace(m_creatureFolderPath, string.Empty).Split(new char[1] { Path.DirectorySeparatorChar })[1]; } private static void ReadServerFiles() { if (!Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.IsServer() || Utility.IsNullOrWhiteSpace(m_serverDataFiles.Value)) { return; } IDeserializer deserializer = new DeserializerBuilder().Build(); try { Initialization.ResetAll(); m_data = deserializer.Deserialize<Dictionary<string, CreatureData>>(m_serverDataFiles.Value); Initialization.RemoveAllClones(); Initialization.CloneAll(); Initialization.UpdateAll(); MonsterDBPlugin.MonsterDBLogger.LogDebug((object)"Server updated MonsterDB Files"); } catch { MonsterDBPlugin.MonsterDBLogger.LogDebug((object)"Failed to parse server synced data"); } } public static void Delete(GameObject critter, bool loop = true) { string prefabName = ((Object)critter).name + "_ragdoll"; GameObject val = DataBase.TryGetGameObject(prefabName); if ((Object)(object)val != (Object)null) { Delete(val, loop); } Helpers.RemoveFromZNetScene(critter); Helpers.RemoveFromObjectDB(critter); if (!loop) { m_clones.Remove(((Object)critter).name); } Transform val2 = MonsterDBPlugin.m_root.transform.Find(((Object)critter).name); if (Object.op_Implicit((Object)(object)val2)) { Object.Destroy((Object)(object)((Component)val2).gameObject); } } private static void Save(GameObject critter, string cloneFrom) { if (!m_originalData.ContainsKey(((Object)critter).name)) { CreatureData creatureData = new CreatureData(); VisualMethods.Save(critter, ref creatureData); HumanoidMethods.Save(critter, cloneFrom, ref creatureData); CharacterMethods.Save(critter, cloneFrom, ref creatureData); MonsterAIMethods.Save(critter, ref creatureData); AnimalAIMethods.Save(critter, ref creatureData); CharacterDropMethods.Save(critter, ref creatureData); TameableMethods.Save(critter, ref creatureData); ProcreationMethods.Save(critter, ref creatureData); NPCTalkMethods.Save(critter, ref creatureData); GrowUpMethods.Save(critter, ref creatureData); LevelEffectsMethods.Save(critter, ref creatureData); m_originalData[((Object)critter).name] = creatureData; } } public static bool Write(GameObject critter, out string folderPath, bool clone = false, string clonedFrom = "", bool writeAll = false) { m_writing = true; if (!Directory.Exists(m_folderPath)) { Directory.CreateDirectory(m_folderPath); } if (!Directory.Exists(m_creatureFolderPath)) { Directory.CreateDirectory(m_creatureFolderPath); } string obj = (clone ? m_cloneFolderPath : m_creatureFolderPath); char directorySeparatorChar = Path.DirectorySeparatorChar; folderPath = obj + directorySeparatorChar + ((Object)critter).name; if (writeAll && Directory.Exists(folderPath)) { MonsterDBPlugin.MonsterDBLogger.LogDebug((object)(((Object)critter).name + " files already exist, skipping")); m_writing = false; return false; } if (Directory.Exists(folderPath)) { Directory.Delete(folderPath, recursive: true); } Directory.CreateDirectory(folderPath); VisualMethods.Write(critter, folderPath); HumanoidMethods.Write(critter, folderPath, clonedFrom); CharacterMethods.Write(critter, folderPath, clonedFrom); MonsterAIMethods.Write(critter, folderPath); AnimalAIMethods.Write(critter, folderPath); CharacterDropMethods.Write(critter, folderPath); TameableMethods.Write(critter, folderPath); ProcreationMethods.Write(critter, folderPath); NPCTalkMethods.Write(critter, folderPath); GrowUpMethods.Write(critter, folderPath); LevelEffectsMethods.Write(critter, folderPath); m_writing = false; return true; } public static void Read(string creatureName, bool isClone = false) { string obj = (isClone ? m_cloneFolderPath : m_creatureFolderPath); char directorySeparatorChar = Path.DirectorySeparatorChar; string text = obj + directorySeparatorChar + creatureName; if (Directory.Exists(text)) { CreatureData creatureData = new CreatureData(); VisualMethods.Read(text, ref creatureData); HumanoidMethods.Read(text, ref creatureData); CharacterMethods.Read(text, ref creatureData); MonsterAIMethods.Read(text, ref creatureData); AnimalAIMethods.Read(text, ref creatureData); CharacterDropMethods.Read(text, ref creatureData); TameableMethods.Read(text, ref creatureData); ProcreationMethods.Read(text, ref creatureData); NPCTalkMethods.Read(text, ref creatureData); GrowUpMethods.Read(text, ref creatureData); LevelEffectsMethods.Read(text, ref creatureData); m_data[creatureName] = creatureData; m_localData[creatureName] = creatureData; UpdateServer(); } } public static void Update(GameObject critter, bool local = false) { CreatureData value2; if (local) { if (m_localData.TryGetValue(((Object)critter).name, out var value)) { Save(critter, value.m_characterData.ClonedFrom); Update(critter, value); } } else if (m_data.TryGetValue(((Object)critter).name, out value2)) { Save(critter, value2.m_characterData.ClonedFrom); Update(critter, value2); } } private static void Update(GameObject critter, CreatureData data) { VisualMethods.Update(critter, data); TameableMethods.Update(critter, data); HumanoidMethods.Update(critter, data); CharacterMethods.Update(critter, data); MonsterAIMethods.Update(critter, data); AnimalAIMethods.Update(critter, data); CharacterDropMethods.Update(critter, data); ProcreationMethods.Update(critter, data); NPCTalkMethods.Update(critter, data); GrowUpMethods.Update(critter, data); LevelEffectsMethods.Update(critter, data); } public static void Reset(GameObject critter) { if (m_originalData.TryGetValue(((Object)critter).name, out var value)) { Update(critter, value); MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Reset: " + ((Object)critter).name)); } } public static void Clone(GameObject critter, string name, bool saveToDisk = true, bool cloneAttacks = true) { if (!Directory.Exists(m_folderPath)) { Directory.CreateDirectory(m_folderPath); } if (!Directory.Exists(m_cloneFolderPath)) { Directory.CreateDirectory(m_cloneFolderPath); } GameObject val; if (((Object)critter).name == "Human") { val = HumanMan.Create(name); if ((Object)(object)val == (Object)null) { return; } } else { val = Object.Instantiate<GameObject>(critter, MonsterDBPlugin.m_root.transform, false); ((Object)val).name = name; Dictionary<string, Material> ragDollMats = VisualMethods.CloneMaterials(val); CharacterMethods.CloneRagDoll(val, ragDollMats); HumanoidMethods.CloneRagDoll(val, ragDollMats); m_clones[((Object)val).name] = val; Helpers.RegisterToZNetScene(val); } if (cloneAttacks) { HumanoidMethods.CloneItems(val); } if (saveToDisk) { Write(val, out var folderPath, clone: true, ((Object)critter).name); Read(((Object)val).name, isClone: true); MonsterDBPlugin.MonsterDBLogger.LogInfo((object)("Cloned " + ((Object)critter).name + " as " + ((Object)val).name)); MonsterDBPlugin.MonsterDBLogger.LogInfo((object)folderPath); } } public static void Export(string creatureName) { if (!Directory.Exists(m_folderPath)) { Directory.CreateDirectory(m_folderPath); } if (!Directory.Exists(m_exportFolderPath)) { Directory.CreateDirectory(m_exportFolderPath); } if (!Directory.Exists(m_importFolderPath)) { Directory.CreateDirectory(m_importFolderPath); } if (m_data.TryGetValue(creatureName, out var value)) { ISerializer serializer = new SerializerBuilder().Build(); string contents = serializer.Serialize(value); string exportFolderPath = m_exportFolderPath; char directorySeparatorChar = Path.DirectorySeparatorChar; string text = exportFolderPath + directorySeparatorChar + creatureName + ".yml"; File.WriteAllText(text, contents); MonsterDBPlugin.MonsterDBLogger.LogDebug((object)"Exported creature data: "); MonsterDBPlugin.MonsterDBLogger.LogDebug((object)text); } } public static void Import() { if (!Directory.Exists(m_folderPath)) { Directory.CreateDirectory(m_folderPath); } if (!Directory.Exists(m_importFolderPath)) { Directory.CreateDirectory(m_importFolderPath); } string[] files = Directory.GetFiles(m_importFolderPath); if (files.Length == 0) { return; } IDeserializer deserializer = new DeserializerBuilder().Build(); int num = 0; string[] array = files; foreach (string text in array) { try { string input = File.ReadAllText(text); CreatureData creatureData = deserializer.Deserialize<CreatureData>(input); string prefabName = creatureData.m_characterData.PrefabName; m_data[prefabName] = creatureData; num++; } catch { Helpers.LogParseFailure(text); } } MonsterDBPlugin.MonsterDBLogger.LogDebug((object)$"Imported {num} creature data files"); } static CreatureManager() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; m_folderPath = configPath + directorySeparatorChar + "MonsterDB"; string folderPath = m_folderPath; directorySeparatorChar = Path.DirectorySeparatorChar; m_creatureFolderPath = folderPath + directorySeparatorChar + "Creatures"; string folderPath2 = m_folderPath; directorySeparatorChar = Path.DirectorySeparatorChar; m_cloneFolderPath = folderPath2 + directorySeparatorChar + "Clones"; string folderPath3 = m_folderPath; directorySeparatorChar = Path.DirectorySeparatorChar; m_exportFolderPath = folderPath3 + directorySeparatorChar + "Export"; string folderPath4 = m_folderPath; directorySeparatorChar = Path.DirectorySeparatorChar; m_importFolderPath = folderPath4 + directorySeparatorChar + "Import"; m_serverDataFiles = new CustomSyncedValue<string>(MonsterDBPlugin.ConfigSync, "MonsterDB_ServerFiles", ""); m_originalData = new Dictionary<string, CreatureData>(); m_data = new Dictionary<string, CreatureData>(); m_localData = new Dictionary<string, CreatureData>(); m_clones = new Dictionary<string, GameObject>(); m_creatureWatcher = null; m_cloneWatcher = null; } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public static class DataBase { [HarmonyPatch(typeof(ZNetScene), "Awake")] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] [HarmonyPriority(800)] private static class CacheResources_Patch { private static void Postfix() { CacheResources(); } } public static readonly Dictionary<string, GameObject> m_allObjects = new Dictionary<string, GameObject>(); public static readonly Dictionary<string, Texture2D> m_textures = new Dictionary<string, Texture2D>(); private static void CacheResources() { List<GameObject> list = Resources.FindObjectsOfTypeAll<GameObject>().ToList(); foreach (GameObject item in list) { m_allObjects[((Object)item).name] = item; } List<Texture2D> source = Resources.FindObjectsOfTypeAll<Texture2D>().ToList(); foreach (Texture2D item2 in source.Where([<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] (Texture2D texture) => !Utility.IsNullOrWhiteSpace(((Object)texture).name))) { m_textures[((Object)item2).name] = item2; } string texturePath = TextureManager.m_texturePath; char directorySeparatorChar = Path.DirectorySeparatorChar; string path = texturePath + directorySeparatorChar + "Resources.txt"; if (!File.Exists(path)) { List<string> contents = m_textures.Keys.ToList(); File.WriteAllLines(path, contents); } } [return: <391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(2)] public static GameObject TryGetGameObject(string prefabName) { if (!Object.op_Implicit((Object)(object)ZNetScene.instance) || !Object.op_Implicit((Object)(object)ObjectDB.instance)) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName); if ((Object)(object)itemPrefab != (Object)null) { return itemPrefab; } itemPrefab = ZNetScene.instance.GetPrefab(prefabName); if ((Object)(object)itemPrefab != (Object)null) { return itemPrefab; } if (HumanMan.m_newHumans.TryGetValue(prefabName, out var value)) { return value; } if (ItemDataMethods.m_clonedItems.TryGetValue(prefabName, out var value2)) { return value2; } GameObject value3; return (!m_allObjects.TryGetValue(prefabName, out value3)) ? null : value3; } public static bool TryGetTexture(string textureName, out Texture2D texture) { if (TextureManager.m_customTextures.TryGetValue(textureName, out texture)) { return true; } return m_textures.TryGetValue(textureName, out texture); } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] public static class HumanMan { public static readonly Dictionary<string, GameObject> m_newHumans = new Dictionary<string, GameObject>(); [return: <391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(2)] public static GameObject Create(string name) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Expected O, but got Unknown //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Expected O, but got Unknown //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_062c: Unknown result type (might be due to invalid IL or missing references) //IL_0631: Unknown result type (might be due to invalid IL or missing references) //IL_0646: Unknown result type (might be due to invalid IL or missing references) //IL_064d: Unknown result type (might be due to invalid IL or missing references) //IL_0655: Unknown result type (might be due to invalid IL or missing references) //IL_0660: Unknown result type (might be due to invalid IL or missing references) //IL_066c: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)ZNetScene.instance)) { return null; } GameObject prefab = ZNetScene.instance.GetPrefab("Player"); if (!Object.op_Implicit((Object)(object)prefab)) { return null; } Player val = default(Player); if (!prefab.TryGetComponent<Player>(ref val)) { return null; } GameObject val2 = Object.Instantiate<GameObject>(prefab, MonsterDBPlugin.m_root.transform, false); ((Object)val2).name = name; Object.Destroy((Object)(object)val2.GetComponent<Player>()); Object.Destroy((Object)(object)val2.GetComponent<PlayerController>()); Object.Destroy((Object)(object)val2.GetComponent<Talker>()); Object.Destroy((Object)(object)val2.GetComponent<Skills>()); ZNetView val3 = default(ZNetView); if (val2.TryGetComponent<ZNetView>(ref val3)) { val3.m_persistent = true; val3.m_type = (ObjectType)0; } Human human = val2.AddComponent<Human>(); ((Character)human).m_eye = Utils.FindChild(val2.transform, "EyePos", (IterativeSearchType)0); MonsterAI val4 = val2.AddComponent<MonsterAI>(); CharacterDrop val5 = val2.AddComponent<CharacterDrop>(); Tameable val6 = val2.AddComponent<Tameable>(); val2.AddComponent<Visuals>(); GameObject val7 = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("Player_ragdoll"), MonsterDBPlugin.m_root.transform, false); Ragdoll val8 = default(Ragdoll); EffectList val9; if (val7.TryGetComponent<Ragdoll>(ref val8)) { val8.m_ttl = 8f; Ragdoll obj = val8; val9 = new EffectList(); val9.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { new EffectData { m_prefab = ZNetScene.instance.GetPrefab("vfx_corpse_destruction_small"), m_enabled = true } }; obj.m_removeEffect = val9; val8.m_float = true; val8.m_dropItems = true; } ((Object)val7).name = name + "_ragdoll"; val7.AddComponent<Visuals>(); Helpers.RegisterToZNetScene(val7); val9 = new EffectList(); val9.m_effectPrefabs = (EffectData[])(object)new EffectData[2] { new EffectData { m_prefab = ZNetScene.instance.GetPrefab("vfx_player_death"), m_enabled = true }, new EffectData { m_prefab = val7, m_enabled = true } }; ((Character)human).m_deathEffects = val9; ((Character)human).m_name = "Human"; ((Character)human).m_group = "Humans"; ((Character)human).m_faction = (Faction)2; ((Character)human).m_crouchSpeed = ((Character)val).m_crouchSpeed; ((Character)human).m_walkSpeed = ((Character)val).m_walkSpeed; ((Character)human).m_speed = ((Character)val).m_speed; ((Character)human).m_runSpeed = ((Character)val).m_runSpeed; ((Character)human).m_runTurnSpeed = ((Character)val).m_runTurnSpeed; ((Character)human).m_acceleration = ((Character)val).m_acceleration; ((Character)human).m_jumpForce = ((Character)val).m_jumpForce; ((Character)human).m_jumpForceForward = ((Character)val).m_jumpForceForward; ((Character)human).m_jumpForceTiredFactor = ((Character)val).m_jumpForceForward; ((Character)human).m_airControl = ((Character)val).m_airControl; ((Character)human).m_canSwim = true; ((Character)human).m_swimDepth = ((Character)val).m_swimDepth; ((Character)human).m_swimSpeed = ((Character)val).m_swimSpeed; ((Character)human).m_swimTurnSpeed = ((Character)val).m_swimTurnSpeed; ((Character)human).m_swimAcceleration = ((Character)val).m_swimAcceleration; ((Character)human).m_groundTilt = ((Character)val).m_groundTilt; ((Character)human).m_groundTiltSpeed = ((Character)val).m_groundTiltSpeed; ((Character)human).m_jumpStaminaUsage = ((Character)val).m_jumpStaminaUsage; ((Character)human).m_hitEffects = ((Character)val).m_hitEffects; ((Character)human).m_critHitEffects = ((Character)val).m_critHitEffects; ((Character)human).m_backstabHitEffects = ((Character)val).m_backstabHitEffects; ((Character)human).m_waterEffects = ((Character)val).m_waterEffects; ((Character)human).m_tarEffects = ((Character)val).m_tarEffects; ((Character)human).m_slideEffects = ((Character)val).m_slideEffects; ((Character)human).m_jumpEffects = ((Character)val).m_jumpEffects; ((Character)human).m_flyingContinuousEffect = ((Character)val).m_flyingContinuousEffect; ((Character)human).m_tolerateWater = true; ((Character)human).m_health = 100f; ((Character)human).m_damageModifiers = ((Character)val).m_damageModifiers; ((Character)human).m_staggerWhenBlocked = true; ((Character)human).m_staggerDamageFactor = ((Character)val).m_staggerDamageFactor; ((Humanoid)human).m_defaultItems = ((Humanoid)val).m_defaultItems; ((Humanoid)human).m_randomWeapon = ((Humanoid)val).m_randomWeapon; ((Humanoid)human).m_randomArmor = ((Humanoid)val).m_randomArmor; ((Humanoid)human).m_randomShield = ((Humanoid)val).m_randomShield; ItemSet[] array = new ItemSet[2]; ItemSet val10 = new ItemSet(); val10.m_name = "Leather"; val10.m_items = (GameObject[])(object)new GameObject[3] { ZNetScene.instance.GetPrefab("ArmorLeatherChest"), ZNetScene.instance.GetPrefab("ArmorLeatherLegs"), ZNetScene.instance.GetPrefab("Torch") }; array[0] = val10; val10 = new ItemSet(); val10.m_name = "Bronze"; val10.m_items = (GameObject[])(object)new GameObject[4] { ZNetScene.instance.GetPrefab("ArmorBronzeChest"), ZNetScene.instance.GetPrefab("ArmorBronzeLegs"), ZNetScene.instance.GetPrefab("ShieldBronzeBuckler"), ZNetScene.instance.GetPrefab("KnifeCopper") }; array[1] = val10; ((Humanoid)human).m_randomSets = (ItemSet[])(object)array; ((Humanoid)human).m_randomItems = ((Humanoid)val).m_randomItems; ((Humanoid)human).m_unarmedWeapon = ((Humanoid)val).m_unarmedWeapon; ((Humanoid)human).m_pickupEffects = val.m_autopickupEffects; ((Humanoid)human).m_dropEffects = ((Humanoid)val).m_dropEffects; ((Humanoid)human).m_consumeItemEffects = ((Humanoid)val).m_consumeItemEffects; ((Humanoid)human).m_equipEffects = val.m_equipStartEffects; ((Humanoid)human).m_perfectBlockEffect = ((Humanoid)val).m_perfectBlockEffect; ((BaseAI)val4).m_viewRange = 30f; ((BaseAI)val4).m_viewAngle = 90f; ((BaseAI)val4).m_hearRange = 9999f; ((BaseAI)val4).m_idleSoundInterval = 10f; ((BaseAI)val4).m_idleSoundChance = 0f; ((BaseAI)val4).m_pathAgentType = (AgentType)1; ((BaseAI)val4).m_moveMinAngle = 90f; ((BaseAI)val4).m_smoothMovement = true; ((BaseAI)val4).m_jumpInterval = 10f; ((BaseAI)val4).m_randomCircleInterval = 2f; ((BaseAI)val4).m_randomMoveInterval = 30f; ((BaseAI)val4).m_randomMoveRange = 3f; val4.m_alertRange = 20f; val4.m_circulateWhileCharging = true; val4.m_privateAreaTriggerTreshold = 4; val4.m_interceptTimeMax = 2f; val4.m_maxChaseDistance = 300f; val4.m_circleTargetInterval = 8f; val4.m_circleTargetDuration = 6f; val4.m_circleTargetDistance = 8f; val4.m_consumeRange = 2f; val4.m_consumeSearchRange = 5f; val4.m_consumeSearchInterval = 10f; val4.m_consumeItems = new List<ItemDrop>(); val5.m_drops = new List<Drop> { new Drop { m_prefab = ZNetScene.instance.GetPrefab("Coins"), m_amountMin = 1, m_amountMax = 10, m_chance = 0.25f, m_levelMultiplier = true } }; GameObject prefab2 = ZNetScene.instance.GetPrefab("Boar"); Tameable val11 = default(Tameable); if (prefab2.TryGetComponent<Tameable>(ref val11)) { val6.m_fedDuration = 600f; val6.m_tamingTime = 1800f; val6.m_commandable = true; val6.m_tamedEffect = val11.m_tamedEffect; val6.m_sootheEffect = val11.m_sootheEffect; val6.m_petEffect = val11.m_petEffect; val6.m_commandable = true; val6.m_unsummonDistance = 0f; val6.m_randomStartingName = new List<string>(); } Helpers.RegisterToZNetScene(val2); if (name != "Human") { CreatureManager.m_clones[((Object)val2).name] = val2; } m_newHumans[((Object)val2).name] = val2; return val2; } } public static class Initialization { [HarmonyPriority(0)] [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_Patch { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] private static void Postfix(ObjectDB __instance) { if (!Object.op_Implicit((Object)(object)__instance) || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { return; } HumanMan.Create("Human"); CloneAll(local: true); UpdateAll(local: true); SpawnMan.UpdateSpawnData(); List<string> list = new List<string>(); foreach (StatusEffect statusEffect in __instance.m_StatusEffects) { list.Add(((Object)statusEffect).name); } File.WriteAllLines(m_statusEffectsPath, list); } } [HarmonyPatch(typeof(Game), "Logout")] private static class Game_Logout_Patch { private static void Prefix() { ResetAll(); RemoveAllClones(); SpawnMan.ClearSpawns(); } } [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(1)] private static readonly string m_statusEffectsPath; public static void ReadLocalFiles() { if (!Directory.Exists(CreatureManager.m_folderPath)) { Directory.CreateDirectory(CreatureManager.m_folderPath); } if (!Directory.Exists(CreatureManager.m_creatureFolderPath)) { Directory.CreateDirectory(CreatureManager.m_creatureFolderPath); } if (!Directory.Exists(CreatureManager.m_cloneFolderPath)) { Directory.CreateDirectory(CreatureManager.m_cloneFolderPath); } CreatureManager.Import(); ReadCreatureDirectory(); ReadCloneDirectory(); } private static void ReadCreatureDirectory() { string[] directories = Directory.GetDirectories(CreatureManager.m_creatureFolderPath); int num = 0; string[] array = directories; foreach (string path in array) { string fileName = Path.GetFileName(path); CreatureManager.Read(fileName); num++; } MonsterDBPlugin.MonsterDBLogger.LogDebug((object)$"Registered {num} creature directories"); } private static void ReadCloneDirectory() { int num = 0; string[] directories = Directory.GetDirectories(CreatureManager.m_cloneFolderPath); string[] array = directories; foreach (string path in array) { string fileName = Path.GetFileName(path); CreatureManager.Read(fileName, isClone: true); num++; } MonsterDBPlugin.MonsterDBLogger.LogDebug((object)$"Registered {num} cloned creature directories"); } public static void ResetAll() { int num = 0; foreach (KeyValuePair<string, CreatureData> datum in CreatureManager.m_data) { GameObject val = DataBase.TryGetGameObject(datum.Value.m_characterData.PrefabName); if (!((Object)(object)val == (Object)null)) { CreatureManager.Reset(val); num++; } } MonsterDBPlugin.MonsterDBLogger.LogDebug((object)$"Reset {num} creature data"); } public static void RemoveAllClones() { int num = 0; foreach (KeyValuePair<string, GameObject> clone in CreatureManager.m_clones) { CreatureManager.Delete(clone.Value); num++; } CreatureManager.m_clones.Clear(); MonsterDBPlugin.MonsterDBLogger.LogDebug((object)$"Removed {num} clones"); } public static void CloneAll(bool local = false) { int num = 0; foreach (KeyValuePair<string, CreatureData> item in local ? CreatureManager.m_localData : CreatureManager.m_data) { CloneAllItems(item.Value); string clonedFrom = item.Value.m_characterData.ClonedFrom; if (!Utility.IsNullOrWhiteSpace(clonedFrom)) { GameObject val = DataBase.TryGetGameObject(clonedFrom); if (!((Object)(object)val == (Object)null)) { string prefabName = item.Value.m_characterData.PrefabName; CreatureManager.Clone(val, prefabName, saveToDisk: false, cloneAttacks: false); num++; } } } MonsterDBPlugin.MonsterDBLogger.LogDebug((object)$"Cloned {num} creatures"); } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] private static void CloneAllItems(CreatureData data) { CloneItems(data.m_defaultItems); CloneItems(data.m_randomWeapons); CloneItems(data.m_randomShields); CloneItems(data.m_randomArmors); foreach (RandomItemSetsData randomSet in data.m_randomSets) { CloneItems(randomSet.m_items); } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] private static void CloneItems(List<ItemAttackData> data) { foreach (ItemAttackData datum in data) { if (!Utility.IsNullOrWhiteSpace(datum.m_attackData.OriginalPrefab)) { GameObject val = DataBase.TryGetGameObject(datum.m_attackData.OriginalPrefab); if (!((Object)(object)val == (Object)null)) { ItemDataMethods.Clone(val, datum.m_attackData.Name, write: false); } } } } public static void UpdateAll(bool local = false) { if (!Object.op_Implicit((Object)(object)ZNetScene.instance) || !Object.op_Implicit((Object)(object)ObjectDB.instance)) { return; } int num = 0; foreach (KeyValuePair<string, CreatureData> item in local ? CreatureManager.m_localData : CreatureManager.m_data) { GameObject val = DataBase.TryGetGameObject(item.Value.m_characterData.PrefabName); if (!((Object)(object)val == (Object)null)) { CreatureManager.Update(val, local); num++; } } MonsterDBPlugin.MonsterDBLogger.LogDebug((object)$"Updated {num} creatures"); } static Initialization() { string folderPath = CreatureManager.m_folderPath; char directorySeparatorChar = Path.DirectorySeparatorChar; m_statusEffectsPath = folderPath + directorySeparatorChar + "StatusEffects.txt"; } } [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] public static class SpawnMan { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] [HarmonyPatch(typeof(SpawnSystem), "Awake")] private static class SpawnSystem_Awake_Patch { [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(1)] private static void Postfix(SpawnSystem __instance) { if (Object.op_Implicit((Object)(object)__instance) && !__instance.m_spawnLists.Contains(m_spawnSystemList)) { __instance.m_spawnLists.Add(m_spawnSystemList); } } } [<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] [HarmonyPatch(typeof(ZNet), "Awake")] private static class ZNet_Awake_Patch { private static void Postfix() { UpdateServerFiles(); } } [<391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(0)] private class CreatureSpawnData { public string m_name = ""; public bool m_enabled = false; public bool m_devDisabled; public string m_prefab = null; public string m_biome = null; public string m_biomeArea = "Everything"; public int m_maxSpawned = 1; public float m_spawnInterval = 4f; public float m_spawnChance = 100f; public float m_spawnDistance = 10f; public float m_spawnRadiusMin; public float m_spawnRadiusMax; public string m_requiredGlobalKey = ""; public List<string> m_requiredEnvironments = new List<string>(); public int m_groupSizeMin = 1; public int m_groupSizeMax = 1; public float m_groupRadius = 3f; public bool m_spawnAtNight = true; public bool m_spawnAtDay = true; public float m_minAltitude = -1000f; public float m_maxAltitude = 1000f; public float m_minTilt; public float m_maxTilt = 35f; public bool m_inForest = true; public bool m_outsideForest = true; public bool m_inLava; public bool m_outsideLava = true; public bool m_canSpawnCloseToPlayer; public bool m_insidePlayerBase; public float m_minOceanDepth; public float m_maxOceanDepth; public bool m_huntPlayer; public float m_groundOffset = 0.5f; public float m_groundOffsetRandom; public int m_maxLevel = 1; public int m_minLevel = 1; public float m_levelUpMinCenterDistance; public float m_overrideLevelupChance = -1f; public bool m_foldout; } private static readonly CustomSyncedValue<string> ServerSpawnSystem = new CustomSyncedValue<string>(MonsterDBPlugin.ConfigSync, "MonsterDB_SpawnSystemData", ""); private static readonly string m_spawnFolderPath; private static readonly string m_referenceFolderPath; private static SpawnSystemList m_spawnSystemList; private static Dictionary<string, CreatureSpawnData> m_spawnData; public static void Setup() { m_spawnSystemList = MonsterDBPlugin.m_root.AddComponent<SpawnSystemList>(); ReadSpawnFiles(); string spawnFolderPath = m_spawnFolderPath; char directorySeparatorChar = Path.DirectorySeparatorChar; string path = spawnFolderPath + directorySeparatorChar + "Example.yml"; if (!File.Exists(path)) { CreatureSpawnData graph = new CreatureSpawnData(); ISerializer serializer = new SerializerBuilder().Build(); string contents = serializer.Serialize(graph); File.WriteAllText(path, contents); } ServerSpawnSystem.ValueChanged += delegate { if (Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer()) { UpdateSpawnData(); } }; SetupFileWatch(); if (!Directory.Exists(CreatureManager.m_folderPath)) { Directory.CreateDirectory(CreatureManager.m_folderPath); } if (!Directory.Exists(m_spawnFolderPath)) { Directory.CreateDirectory(m_spawnFolderPath); } } private static void SetupFileWatch() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(m_spawnFolderPath, "*.yml") { EnableRaisingEvents = true, IncludeSubdirectories = false, SynchronizingObject = ThreadingHelper.SynchronizingObject, NotifyFilter = NotifyFilters.LastWrite }; fileSystemWatcher.Created += OnSpawnChange; fileSystemWatcher.Deleted += OnSpawnChange; fileSystemWatcher.Changed += OnSpawnChange; } private static void OnSpawnChange(object sender, FileSystemEventArgs e) { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { string fileName = Path.GetFileName(e.Name); if (!(fileName == "Example.yml")) { MonsterDBPlugin.MonsterDBLogger.LogDebug((object)"Spawn files changed"); ClearSpawnData(); ReadSpawnFiles(); } } } public static void ClearSpawns() { if (!((Object)(object)m_spawnSystemList == (Object)null)) { m_spawnSystemList.m_spawners.Clear(); ServerSpawnSystem.Value = ""; ClearSpawnData(); } } private static void ReadFile(string filePath) { try { IDeserializer deserializer = new DeserializerBuilder().Build(); string input = File.ReadAllText(filePath); CreatureSpawnData creatureSpawnData = deserializer.Deserialize<CreatureSpawnData>(input); m_spawnData[creatureSpawnData.m_name] = creatureSpawnData; UpdateSpawnList(); UpdateServerFiles(); } catch { Helpers.LogParseFailure(filePath); } } private static void ReadSpawnFiles() { if (!Directory.Exists(m_spawnFolderPath)) { Directory.CreateDirectory(m_spawnFolderPath); } string[] files = Directory.GetFiles(m_spawnFolderPath, "*.yml"); IDeserializer deserializer = new DeserializerBuilder().Build(); int num = 0; string[] array = files; foreach (string text in array) { string fileName = Path.GetFileName(text); if (!(fileName == "Example.yml")) { string input = File.ReadAllText(text); try { CreatureSpawnData creatureSpawnData = deserializer.Deserialize<CreatureSpawnData>(input); m_spawnData[creatureSpawnData.m_name] = creatureSpawnData; num++; } catch { Helpers.LogParseFailure(text); } } } MonsterDBPlugin.MonsterDBLogger.LogDebug((object)$"Registered {num} spawn files"); } public static void UpdateSpawnData() { if (Utility.IsNullOrWhiteSpace(ServerSpawnSystem.Value)) { return; } try { IDeserializer deserializer = new DeserializerBuilder().Build(); Dictionary<string, CreatureSpawnData> dictionary = deserializer.Deserialize<Dictionary<string, CreatureSpawnData>>(ServerSpawnSystem.Value); ClearSpawnData(); AddSpawnData(dictionary); UpdateSpawnList(); MonsterDBPlugin.MonsterDBLogger.LogDebug((object)$"Loaded {dictionary.Count} spawn files"); } catch { MonsterDBPlugin.MonsterDBLogger.LogDebug((object)"Failed to parse server spawn files"); } } private static void ClearSpawnData() { m_spawnData.Clear(); } private static void AddSpawnData(Dictionary<string, CreatureSpawnData> data) { m_spawnData = data; } private static void UpdateSpawnList() { m_spawnSystemList.m_spawners = (from info in m_spawnData.Values.Select(FormatSpawnData) where info != null select info).ToList(); } public static bool Write(GameObject critter) { if (!Directory.Exists(m_spawnFolderPath)) { Directory.CreateDirectory(m_spawnFolderPath); } if (!Directory.Exists(m_referenceFolderPath)) { Directory.CreateDirectory(m_referenceFolderPath); } CreatureSpawnData creatureSpawnData = new CreatureSpawnData(); foreach (SpawnSystemList item in SpawnSystem.m_instances.SelectMany([<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] (SpawnSystem instance) => instance.m_spawnLists)) { using IEnumerator<SpawnData> enumerator2 = item.m_spawners.Where([<280c4705-4a7b-4139-8a59-78254fb4951c>NullableContext(0)] (SpawnData stream) => (Object)(object)stream.m_prefab == (Object)(object)critter).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnData current2 = enumerator2.Current; creatureSpawnData.m_name = current2.m_name; creatureSpawnData.m_enabled = current2.m_enabled; creatureSpawnData.m_prefab = ((Object)current2.m_prefab).name; creatureSpawnData.m_biome = ((object)(Biome)(ref current2.m_biome)).ToString(); creatureSpawnData.m_biomeArea = ((object)(BiomeArea)(ref current2.m_biomeArea)).ToString(); creatureSpawnData.m_maxSpawned = current2.m_maxSpawned; creatureSpawnData.m_spawnInterval = current2.m_spawnInterval; creatureSpawnData.m_spawnChance = current2.m_spawnChance; creatureSpawnData.m_spawnDistance = current2.m_spawnDistance; creatureSpawnData.m_spawnRadiusMin = current2.m_spawnRadiusMin; creatureSpawnData.m_spawnRadiusMax = current2.m_spawnRadiusMax; creatureSpawnData.m_requiredGlobalKey = current2.m_requiredGlobalKey; creatureSpawnData.m_requiredEnvironments = current2.m_requiredEnvironments; creatureSpawnData.m_groupSizeMin = current2.m_groupSizeMin; creatureSpawnData.m_groupSizeMax = current2.m_groupSizeMax; creatureSpawnData.m_groupRadius = current2.m_groupRadius; creatureSpawnData.m_spawnAtNight = current2.m_spawnAtNight; creatureSpawnData.m_spawnAtDay = current2.m_spawnAtDay; creatureSpawnData.m_minAltitude = current2.m_minAltitude; creatureSpawnData.m_maxAltitude = current2.m_maxAltitude; creatureSpawnData.m_minTilt = current2.m_minTilt; creatureSpawnData.m_maxTilt = current2.m_maxTilt; creatureSpawnData.m_inForest = current2.m_inForest; creatureSpawnData.m_outsideForest = current2.m_outsideForest; creatureSpawnData.m_inLava = current2.m_inLava; creatureSpawnData.m_outsideLava = current2.m_outsideLava; creatureSpawnData.m_canSpawnCloseToPlayer = current2.m_canSpawnCloseToPlayer; creatureSpawnData.m_insidePlayerBase = current2.m_insidePlayerBase; creatureSpawnData.m_minOceanDepth = current2.m_minOceanDepth; creatureSpawnData.m_maxOceanDepth = current2.m_maxOceanDepth; creatureSpawnData.m_huntPlayer = current2.m_huntPlayer; creatureSpawnData.m_groundOffset = current2.m_groundOffset; creatureSpawnData.m_groundOffsetRandom = current2.m_groundOffsetRandom; creatureSpawnData.m_maxLevel = current2.m_maxLevel; creatureSpawnData.m_minLevel = current2.m_minLevel; creatureSpawnData.m_levelUpMinCenterDistance = current2.m_levelUpMinCenterDistance; creatureSpawnData.m_overrideLevelupChance = current2.m_overrideLevelupChance; creatureSpawnData.m_foldout = current2.m_foldout; } } if (Utility.IsNullOrWhiteSpace(creatureSpawnData.m_prefab)) { return false; } string text = creatureSpawnData.m_prefab + ".yml"; string referenceFolderPath = m_referenceFolderPath; char directorySeparatorChar = Path.DirectorySeparatorChar; string path = referenceFolderPath + directorySeparatorChar + text; ISerializer serializer = new SerializerBuilder().Build(); string contents = serializer.Serialize(creatureSpawnData); File.WriteAllText(path, contents); return true; } [return: <391b7e1c-21ce-4cd7-b9cc-6b18bf5eb6e4>Nullable(2)] private static SpawnData FormatSpawnData(CreatureSpawnData input) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a5: 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) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might b