using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; 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 BalrondIdleActors; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ElvenNPC; using ElvenNPC.Behaviors; using ElvenNPC.Managers; using HarmonyLib; using JetBrains.Annotations; using Managers; using Microsoft.CodeAnalysis; using Norsemen; using PieceManager; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.UI; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyProduct("BalrondElvenFactionsReborn")] [assembly: AssemblyCompany("balrond.astafaraios")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("BalrondElvenFactionsReborn")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyFileVersion("0.1.4")] [assembly: AssemblyConfiguration("")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<581963fb-93f1-4ef0-9568-d5b74dd961e8>Embedded] internal sealed class <581963fb-93f1-4ef0-9568-d5b74dd961e8>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [<581963fb-93f1-4ef0-9568-d5b74dd961e8>Embedded] [CompilerGenerated] internal sealed class <0a129ba9-9b79-4edb-9131-78df17e06315>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <0a129ba9-9b79-4edb-9131-78df17e06315>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <0a129ba9-9b79-4edb-9131-78df17e06315>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [<581963fb-93f1-4ef0-9568-d5b74dd961e8>Embedded] [CompilerGenerated] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public static class BalrondHashCompat { private static readonly MethodInfo _getStableHashCodeStringBool; private static readonly MethodInfo _getStableHashCodeString; private static readonly bool _initialized; static BalrondHashCompat() { try { Type typeFromHandle = typeof(StringExtensionMethods); _getStableHashCodeStringBool = typeFromHandle.GetMethod("GetStableHashCode", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(string), typeof(bool) }, null); _getStableHashCodeString = typeFromHandle.GetMethod("GetStableHashCode", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); _initialized = true; } catch { _initialized = false; } } public static int StableHash(string value) { if (value == null) { return 0; } try { if (_getStableHashCodeStringBool != null) { return (int)_getStableHashCodeStringBool.Invoke(null, new object[2] { value, false }); } if (_getStableHashCodeString != null) { return (int)_getStableHashCodeString.Invoke(null, new object[1] { value }); } } catch { } return FallbackStableHash(value); } private static int FallbackStableHash(string value) { int num = 5381; int num2 = num; for (int i = 0; i < value.Length; i += 2) { num = ((num << 5) + num) ^ value[i]; if (i == value.Length - 1) { break; } num2 = ((num2 << 5) + num2) ^ value[i + 1]; } return num + num2 * 1566083941; } } namespace BalrondIdleActors { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class ShaderReplacment { public static List prefabsToReplaceShader = new List(); public static List materialsInPrefabs = new List(); public string[] shaderlist = new string[49] { "Custom/AlphaParticle", "Custom/Blob", "Custom/Bonemass", "Custom/Clouds", "Custom/Creature", "Custom/Decal", "Custom/Distortion", "Custom/Flow", "Custom/FlowOpaque", "Custom/Grass", "Custom/GuiScroll", "Custom/Heightmap", "Custom/icon", "Custom/InteriorSide", "Custom/LitGui", "Custom/LitParticles", "Custom/mapshader", "Custom/ParticleDecal", "Custom/Piece", "Custom/Player", "Custom/Rug", "Custom/ShadowBlob", "Custom/SkyboxProcedural", "Custom/SkyObject", "Custom/StaticRock", "Custom/Tar", "Custom/Trilinearmap", "Custom/UI/BGBlur", "Custom/Vegetation", "Custom/Water", "Custom/WaterBottom", "Custom/WaterMask", "Custom/Yggdrasil", "Custom/Yggdrasil/root", "Hidden/BlitCopyHDRTonemap", "Hidden/Dof/DepthOfFieldHdr", "Hidden/Dof/DX11Dof", "Hidden/Internal-Loading", "Hidden/Internal-UIRDefaultWorld", "Hidden/SimpleClear", "Hidden/SunShaftsComposite", "Lux Lit Particles/ Bumped", "Lux Lit Particles/ Tess Bumped", "Particles/Standard Surface2", "Particles/Standard Unlit2", "Standard TwoSided", "ToonDeferredShading2017", "Unlit/DepthWrite", "Unlit/Lighting" }; public static List shaders = new List(); private static readonly HashSet CachedShaders = new HashSet(); public static bool debug = true; public static Shader findShader(string name) { Shader[] array = Resources.FindObjectsOfTypeAll(); if (array.Length == 0) { Debug.LogWarning((object)"SHADER LIST IS EMPTY!"); return null; } if (debug) { } return shaders.Find((Shader x) => ((Object)x).name == name); } public static Shader GetShaderByName(string name) { return shaders.Find((Shader x) => ((Object)x).name == name.Trim()); } public static void debugShaderList(List shadersRes) { foreach (Shader shadersRe in shadersRes) { Debug.LogWarning((object)("SHADER NAME IS: " + ((Object)shadersRe).name)); } debug = false; } public static void Replace(GameObject gameObject) { prefabsToReplaceShader.Add(gameObject); GetMaterialsInPrefab(gameObject); } public static void GetMaterialsInPrefab(GameObject gameObject) { Renderer[] componentsInChildren = gameObject.GetComponentsInChildren(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { continue; } Material[] array2 = sharedMaterials; foreach (Material val2 in array2) { if ((Object)(object)val2 != (Object)null) { materialsInPrefabs.Add(val2); } } } } public static void getMeShaders() { AssetBundle[] array = Resources.FindObjectsOfTypeAll(); AssetBundle[] array2 = array; foreach (AssetBundle val in array2) { IEnumerable enumerable3; try { IEnumerable enumerable2; if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val)) { IEnumerable enumerable = val.LoadAllAssets(); enumerable2 = enumerable; } else { enumerable2 = from shader in ((IEnumerable)val.GetAllAssetNames()).Select((Func)val.LoadAsset) where (Object)(object)shader != (Object)null select shader; } enumerable3 = enumerable2; } catch (Exception) { continue; } if (enumerable3 == null) { continue; } foreach (Shader item in enumerable3) { CachedShaders.Add(item); } } } public static void runMaterialFix() { getMeShaders(); shaders.AddRange(CachedShaders); foreach (Material materialsInPrefab in materialsInPrefabs) { Shader shader = materialsInPrefab.shader; if (!((Object)(object)shader == (Object)null)) { string name = ((Object)shader).name; if (!(name == "Standard") && !name.Contains("ScrollingTex") && name.Contains("Balrond")) { setProperValue(materialsInPrefab, name); } } } } private static void setProperValue(Material material, string shaderName) { string name = shaderName.Replace("Balrond", "Custom"); name = checkNaming(name); Shader shaderByName = GetShaderByName(name); if ((Object)(object)shaderByName == (Object)null) { Debug.LogWarning((object)("Shader not found " + name)); } else { material.shader = shaderByName; } } private static string checkNaming(string name) { string result = name; if (name.Contains("Bumped")) { result = name.Replace("Custom", "Lux Lit Particles"); } if (name.Contains("Tess Bumped")) { result = name.Replace("Custom", "Lux Lit Particles"); } if (name.Contains("Standard Surface")) { result = name.Replace("Custom", "Particles"); result = result.Replace("Standard Surface2", "Standard Surface"); } if (name.Contains("Standard Unlit")) { result = name.Replace("Custom", "Particles"); result = result.Replace("Standard Unlit", "Standard Unlit2"); result = result.Replace("Standard Unlit22", "Standard Unlit2"); } return result; } } } namespace PieceManager { [PublicAPI] public enum CraftingTable { None, [InternalName("piece_workbench")] Workbench, [InternalName("piece_cauldron")] Cauldron, [InternalName("forge")] Forge, [InternalName("piece_artisanstation")] ArtisanTable, [InternalName("piece_stonecutter")] StoneCutter, [InternalName("piece_magetable")] MageTable, [InternalName("blackforge")] BlackForge, [InternalName("piece_preptable")] FoodPreparationTable, [InternalName("piece_MeadCauldron")] MeadKetill, Custom } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class InternalName : Attribute { public readonly string internalName; public InternalName(string internalName) { this.internalName = internalName; } } [NullableContext(1)] [PublicAPI] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class ExtensionList { public readonly List ExtensionStations = new List(); public void Set(CraftingTable table, int maxStationDistance = 5) { ExtensionStations.Add(new ExtensionConfig { Table = table, maxStationDistance = maxStationDistance }); } public void Set(string customTable, int maxStationDistance = 5) { ExtensionStations.Add(new ExtensionConfig { Table = CraftingTable.Custom, custom = customTable, maxStationDistance = maxStationDistance }); } } public struct ExtensionConfig { public CraftingTable Table; public float maxStationDistance; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public string custom; } [PublicAPI] [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class CraftingStationList { public readonly List Stations = new List(); public void Set(CraftingTable table) { Stations.Add(new CraftingStationConfig { Table = table }); } public void Set(string customTable) { Stations.Add(new CraftingStationConfig { Table = CraftingTable.Custom, custom = customTable }); } } public struct CraftingStationConfig { public CraftingTable Table; public int level; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public string custom; } [PublicAPI] public enum BuildPieceCategory { Misc = 0, Crafting = 1, BuildingWorkbench = 2, BuildingStonecutter = 3, Furniture = 4, All = 100, Custom = 99 } [NullableContext(1)] [PublicAPI] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class RequiredResourcesList { public readonly List Requirements = new List(); public void Add(string item, int amount, bool recover) { Requirements.Add(new Requirement { itemName = item, amount = amount, recover = recover }); } } public struct Requirement { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(1)] public string itemName; public int amount; public bool recover; } public struct SpecialProperties { [Description("Admins should be the only ones that can build this piece.")] public bool AdminOnly; [Description("Turns off generating a config for this build piece.")] public bool NoConfig; } [PublicAPI] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class BuildingPieceCategory { public BuildPieceCategory Category; public string custom = ""; public void Set(BuildPieceCategory category) { Category = category; } public void Set(string customCategory) { Category = BuildPieceCategory.Custom; custom = customCategory; } } [PublicAPI] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class PieceTool { public readonly HashSet Tools = new HashSet(); public void Add(string tool) { Tools.Add(tool); } } [NullableContext(1)] [PublicAPI] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class BuildPiece { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] internal class PieceConfig { public ConfigEntry craft = null; public ConfigEntry category = null; public ConfigEntry customCategory = null; public ConfigEntry tools = null; public ConfigEntry extensionTable = null; public ConfigEntry customExtentionTable = null; public ConfigEntry maxStationDistance = null; public ConfigEntry table = null; public ConfigEntry customTable = null; } [NullableContext(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] [UsedImplicitly] public string Category; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] [UsedImplicitly] public Action CustomDrawer; } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] private class SerializedRequirements { public readonly List Reqs; public SerializedRequirements(List reqs) { Reqs = reqs; } public SerializedRequirements(string reqs) { Reqs = reqs.Split(new char[1] { ',' }).Select([NullableContext(0)] (string r) => { string[] array = r.Split(new char[1] { ':' }); Requirement result = default(Requirement); result.itemName = array[0]; result.amount = ((array.Length <= 1 || !int.TryParse(array[1], out var result2)) ? 1 : result2); bool result3 = default(bool); result.recover = array.Length <= 2 || !bool.TryParse(array[2], out result3) || result3; return result; }).ToList(); } public override string ToString() { return string.Join(",", Reqs.Select([NullableContext(0)] (Requirement r) => $"{r.itemName}:{r.amount}:{r.recover}")); } [return: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public static ItemDrop fetchByName(ObjectDB objectDB, string name) { GameObject itemPrefab = objectDB.GetItemPrefab(name); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)(((!string.IsNullOrWhiteSpace(((Object)plugin).name)) ? ("[" + ((Object)plugin).name + "]") : "") + " The required item '" + name + "' does not exist.")); } return val; } public static Requirement[] toPieceReqs(SerializedRequirements craft) { Dictionary dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func)([NullableContext(0)] (Requirement r) => r.itemName), (Func)([NullableContext(0)] (Requirement r) => { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) ItemDrop val = ResItem(r); return (val == null) ? ((Requirement)null) : new Requirement { m_amount = r.amount, m_resItem = val, m_recover = r.recover }; })); return dictionary.Values.Where([NullableContext(0)] (Requirement v) => v != null).ToArray(); [NullableContext(2)] static ItemDrop ResItem(Requirement r) { return fetchByName(ObjectDB.instance, r.itemName); } } } internal static readonly List registeredPieces = new List(); private static readonly Dictionary pieceMap = new Dictionary(); public static readonly Dictionary buildPieceMap = new Dictionary(); internal static Dictionary pieceConfigs = new Dictionary(); internal List Conversions = new List(); internal List conversions = new List(); [Description("Disables generation of the configs for your pieces. This is global, this turns it off for all pieces in your mod.")] public static bool ConfigurationEnabled = true; public readonly GameObject Prefab; public List PlaceEffects = new List(); public List HitEffects = new List(); public List DestroyedEffects = new List(); public List SwitchEffects = new List(); public List RandomSpeakEffects = new List(); public List OpenEffects = new List(); public List CloseEffects = new List(); public string CloneDoorEffectsFrom = ""; public string KeyItem = ""; [Description("Specifies the resources needed to craft the piece.\nUse .Add to add resources with their internal ID and an amount.\nUse one .Add for each resource type the building piece should need.")] public readonly RequiredResourcesList RequiredItems = new RequiredResourcesList(); [Description("Sets the category for the building piece.")] public readonly BuildingPieceCategory Category = new BuildingPieceCategory(); [Description("Specifies the tool needed to build your piece.\nUse .Add to add a tool.")] public readonly PieceTool Tool = new PieceTool(); [Description("Specifies the crafting station needed to build your piece.\nUse .Add to add a crafting station, using the CraftingTable enum and a minimum level for the crafting station.")] public CraftingStationList Crafting = new CraftingStationList(); [Description("Makes this piece a station extension")] public ExtensionList Extension = new ExtensionList(); [Description("Change the extended/special properties of your build piece.")] public SpecialProperties SpecialProperties; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] [Description("Specifies a config entry which toggles whether a recipe is active.")] public ConfigEntryBase RecipeIsActive = null; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private LocalizeKey _name; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private LocalizeKey _description; internal string[] activeTools = null; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private static object configManager; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private static Localization _english; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] internal static BaseUnityPlugin _plugin = null; private static bool hasConfigSync = true; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private static object _configSync; public LocalizeKey Name { get { LocalizeKey name = _name; if (name != null) { return name; } Piece component = Prefab.GetComponent(); if (component.m_name.StartsWith("$")) { _name = new LocalizeKey(component.m_name); } else { string text = "$piece_" + ((Object)Prefab).name.Replace(" ", "_"); _name = new LocalizeKey(text).English(component.m_name); component.m_name = text; } return _name; } } public LocalizeKey Description { get { LocalizeKey description = _description; if (description != null) { return description; } Piece component = Prefab.GetComponent(); if (component.m_description.StartsWith("$")) { _description = new LocalizeKey(component.m_description); } else { string text = "$piece_" + ((Object)Prefab).name.Replace(" ", "_") + "_description"; _description = new LocalizeKey(text).English(component.m_description); component.m_description = text; } return _description; } } private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); internal static BaseUnityPlugin plugin { get { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown if (_plugin != null) { return _plugin; } IEnumerable source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); return _plugin; } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private static object configSync { [NullableContext(2)] get { if (_configSync != null || !hasConfigSync) { return _configSync; } Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " PieceManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } return _configSync; } } public void UpdateEffects() { UpdateEffectList(PlaceEffects, ref Prefab.GetComponent().m_placeEffect); RandomSpeak val = default(RandomSpeak); if (Prefab.TryGetComponent(ref val)) { UpdateEffectList(RandomSpeakEffects, ref val.m_speakEffects); } WearNTear val2 = default(WearNTear); if (Prefab.TryGetComponent(ref val2)) { UpdateEffectList(DestroyedEffects, ref val2.m_destroyedEffect); UpdateEffectList(HitEffects, ref val2.m_hitEffect); UpdateEffectList(SwitchEffects, ref val2.m_switchEffect); } Container val3 = default(Container); if (Prefab.TryGetComponent(ref val3)) { UpdateEffectList(OpenEffects, ref val3.m_openEffects); UpdateEffectList(CloseEffects, ref val3.m_closeEffects); } Door val4 = default(Door); if (!Object.op_Implicit((Object)(object)ZNetScene.instance) || Utility.IsNullOrWhiteSpace(CloneDoorEffectsFrom) || !Prefab.TryGetComponent(ref val4)) { return; } GameObject prefab = ZNetScene.instance.GetPrefab(CloneDoorEffectsFrom); Door val5 = default(Door); if (Object.op_Implicit((Object)(object)prefab) && prefab.TryGetComponent(ref val5)) { val4.m_openEffects = val5.m_openEffects; val4.m_closeEffects = val5.m_closeEffects; val4.m_lockedEffects = val5.m_lockedEffects; } if (!Utility.IsNullOrWhiteSpace(KeyItem)) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(KeyItem); ItemDrop keyItem = default(ItemDrop); if (itemPrefab != null && itemPrefab.TryGetComponent(ref keyItem)) { val4.m_keyItem = keyItem; } } } private static void UpdateEffectList(List effects, ref EffectList list) { if (effects.Count != 0 && !((Object)(object)ZNetScene.instance == (Object)null)) { list.m_effectPrefabs = list.m_effectPrefabs.Concat((from effect in ((IEnumerable)effects).Select((Func)ZNetScene.instance.GetPrefab) where (Object)(object)effect != (Object)null select effect).Select((Func)([NullableContext(0)] (GameObject effect) => new EffectData { m_prefab = effect, m_enabled = true }))).ToArray(); } } public BuildPiece(string assetBundleFileName, string prefabName, string folderName = "assets") : this(PiecePrefabManager.RegisterAssetBundle(assetBundleFileName, folderName), prefabName) { } public BuildPiece(AssetBundle bundle, string prefabName) { Prefab = PiecePrefabManager.RegisterPrefab(bundle, prefabName); registeredPieces.Add(this); buildPieceMap[prefabName] = this; } internal static void Patch_FejdStartup(FejdStartup __instance) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Expected O, but got Unknown //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Expected O, but got Unknown //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Expected O, but got Unknown //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_0610: Expected O, but got Unknown //IL_08ea: Unknown result type (might be due to invalid IL or missing references) //IL_08f4: Expected O, but got Unknown //IL_067b: Unknown result type (might be due to invalid IL or missing references) //IL_0685: Expected O, but got Unknown //IL_0721: Unknown result type (might be due to invalid IL or missing references) //IL_072b: Expected O, but got Unknown //IL_095f: Unknown result type (might be due to invalid IL or missing references) //IL_0969: Expected O, but got Unknown //IL_0b7e: Unknown result type (might be due to invalid IL or missing references) //IL_0b88: Expected O, but got Unknown //IL_0c18: Unknown result type (might be due to invalid IL or missing references) //IL_0c22: Expected O, but got Unknown Type configManagerType = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault([NullableContext(0)] (Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager"); configManager = ((configManagerType == null) ? null : Chainloader.ManagerObject.GetComponent(configManagerType)); foreach (BuildPiece registeredPiece in registeredPieces) { registeredPiece.activeTools = registeredPiece.Tool.Tools.DefaultIfEmpty("Hammer").ToArray(); if (registeredPiece.Category.Category != BuildPieceCategory.Custom) { registeredPiece.Prefab.GetComponent().m_category = (PieceCategory)registeredPiece.Category.Category; } else { registeredPiece.Prefab.GetComponent().m_category = PiecePrefabManager.GetCategory(registeredPiece.Category.custom); } } if (!ConfigurationEnabled) { return; } bool saveOnConfigSet = plugin.Config.SaveOnConfigSet; plugin.Config.SaveOnConfigSet = false; foreach (BuildPiece registeredPiece2 in registeredPieces) { BuildPiece piece = registeredPiece2; if (piece.SpecialProperties.NoConfig) { continue; } PieceConfig pieceConfig2 = (pieceConfigs[piece] = new PieceConfig()); PieceConfig cfg = pieceConfig2; Piece piecePrefab2 = piece.Prefab.GetComponent(); string pieceName = piecePrefab2.m_name; string englishName = new Regex("[=\\n\\t\\\\\"\\'\\[\\]]*").Replace(english.Localize(pieceName), "").Trim(); string localizedName = Localization.instance.Localize(pieceName).Trim(); int order = 0; cfg.category = config(englishName, "Build Table Category", piece.Category.Category, new ConfigDescription("Build Category where " + localizedName + " is available.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = (order -= 1), Category = localizedName } })); ConfigurationManagerAttributes customTableAttributes = new ConfigurationManagerAttributes { Order = (order -= 1), Browsable = (cfg.category.Value == BuildPieceCategory.Custom), Category = localizedName }; cfg.customCategory = config(englishName, "Custom Build Category", piece.Category.custom, new ConfigDescription("", (AcceptableValueBase)null, new object[1] { customTableAttributes })); cfg.category.SettingChanged += BuildTableConfigChanged; cfg.customCategory.SettingChanged += BuildTableConfigChanged; if (cfg.category.Value == BuildPieceCategory.Custom) { piecePrefab2.m_category = PiecePrefabManager.GetCategory(cfg.customCategory.Value); } else { piecePrefab2.m_category = (PieceCategory)cfg.category.Value; } cfg.tools = config(englishName, "Tools", string.Join(", ", piece.activeTools), new ConfigDescription("Comma separated list of tools where " + localizedName + " is available.", (AcceptableValueBase)null, new object[1] { customTableAttributes })); piece.activeTools = (from s in cfg.tools.Value.Split(new char[1] { ',' }) select s.Trim()).ToArray(); cfg.tools.SettingChanged += [NullableContext(0)] (object _, EventArgs _) => { Inventory[] source = (from c in Player.s_players.Select([NullableContext(0)] (Player p) => ((Humanoid)p).GetInventory()).Concat(from c in Object.FindObjectsOfType() select c.GetInventory()) where c != null select c).ToArray(); Dictionary> dictionary = (from kv in (from i in (from p in ObjectDB.instance.m_items select p.GetComponent() into c where Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((Component)c).GetComponent()) select c).Concat(ItemDrop.s_instances) select new KeyValuePair(Utils.GetPrefabName(((Component)i).gameObject), i.m_itemData)).Concat(from i in source.SelectMany([NullableContext(0)] (Inventory i) => i.GetAllItems()) select new KeyValuePair(((Object)i.m_dropPrefab).name, i)) where Object.op_Implicit((Object)(object)kv.Value.m_shared.m_buildPieces) group kv by kv.Key).ToDictionary([NullableContext(0)] (IGrouping> g) => g.Key, [NullableContext(0)] (IGrouping> g) => g.Select([NullableContext(0)] (KeyValuePair kv) => kv.Value.m_shared.m_buildPieces).Distinct().ToList()); string[] array5 = piece.activeTools; foreach (string key in array5) { if (dictionary.TryGetValue(key, out var value3)) { foreach (PieceTable item3 in value3) { item3.m_pieces.Remove(piece.Prefab); } } } piece.activeTools = (from s in cfg.tools.Value.Split(new char[1] { ',' }) select s.Trim()).ToArray(); if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { string[] array6 = piece.activeTools; foreach (string key2 in array6) { if (dictionary.TryGetValue(key2, out var value4)) { foreach (PieceTable item4 in value4) { if (!item4.m_pieces.Contains(piece.Prefab)) { item4.m_pieces.Add(piece.Prefab); } } } } if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)Player.m_localPlayer.m_buildPieces)) { PiecePrefabManager.CategoryRefreshNeeded = true; ((Humanoid)Player.m_localPlayer).SetPlaceMode(Player.m_localPlayer.m_buildPieces); } } }; StationExtension pieceExtensionComp; List hideWhenNoneAttributes2; if (piece.Extension.ExtensionStations.Count > 0) { pieceExtensionComp = piece.Prefab.GetOrAddComponent(); PieceConfig pieceConfig3 = cfg; string group = englishName; CraftingTable table = piece.Extension.ExtensionStations.First().Table; string text = "Crafting station that " + localizedName + " extends."; object[] array = new object[1]; ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes(); int num = order - 1; order = num; configurationManagerAttributes.Order = num; array[0] = configurationManagerAttributes; pieceConfig3.extensionTable = config(group, "Extends Station", table, new ConfigDescription(text, (AcceptableValueBase)null, array)); cfg.customExtentionTable = config(englishName, "Custom Extend Station", piece.Extension.ExtensionStations.First().custom ?? "", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { customTableAttributes })); PieceConfig pieceConfig4 = cfg; string group2 = englishName; float maxStationDistance = piece.Extension.ExtensionStations.First().maxStationDistance; string text2 = "Distance from the station that " + localizedName + " can be placed."; object[] array2 = new object[1]; ConfigurationManagerAttributes configurationManagerAttributes2 = new ConfigurationManagerAttributes(); num = order - 1; order = num; configurationManagerAttributes2.Order = num; array2[0] = configurationManagerAttributes2; pieceConfig4.maxStationDistance = config(group2, "Max Station Distance", maxStationDistance, new ConfigDescription(text2, (AcceptableValueBase)null, array2)); hideWhenNoneAttributes2 = new List(); cfg.extensionTable.SettingChanged += ExtensionTableConfigChanged; cfg.customExtentionTable.SettingChanged += ExtensionTableConfigChanged; cfg.maxStationDistance.SettingChanged += ExtensionTableConfigChanged; ConfigurationManagerAttributes configurationManagerAttributes3 = new ConfigurationManagerAttributes(); num = order - 1; order = num; configurationManagerAttributes3.Order = num; configurationManagerAttributes3.Browsable = cfg.extensionTable.Value != CraftingTable.None; ConfigurationManagerAttributes item = configurationManagerAttributes3; hideWhenNoneAttributes2.Add(item); } List hideWhenNoneAttributes; if (piece.Crafting.Stations.Count > 0) { hideWhenNoneAttributes = new List(); PieceConfig pieceConfig5 = cfg; string group3 = englishName; CraftingTable table2 = piece.Crafting.Stations.First().Table; string text3 = "Crafting station where " + localizedName + " is available."; object[] array3 = new object[1]; ConfigurationManagerAttributes configurationManagerAttributes4 = new ConfigurationManagerAttributes(); int num = order - 1; order = num; configurationManagerAttributes4.Order = num; array3[0] = configurationManagerAttributes4; pieceConfig5.table = config(group3, "Crafting Station", table2, new ConfigDescription(text3, (AcceptableValueBase)null, array3)); cfg.customTable = config(englishName, "Custom Crafting Station", piece.Crafting.Stations.First().custom ?? "", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { customTableAttributes })); cfg.table.SettingChanged += TableConfigChanged; cfg.customTable.SettingChanged += TableConfigChanged; ConfigurationManagerAttributes configurationManagerAttributes5 = new ConfigurationManagerAttributes(); num = order - 1; order = num; configurationManagerAttributes5.Order = num; configurationManagerAttributes5.Browsable = cfg.table.Value != CraftingTable.None; ConfigurationManagerAttributes item2 = configurationManagerAttributes5; hideWhenNoneAttributes.Add(item2); } cfg.craft = itemConfig("Crafting Costs", new SerializedRequirements(piece.RequiredItems.Requirements).ToString(), "Item costs to craft " + localizedName); cfg.craft.SettingChanged += [NullableContext(0)] (object _, EventArgs _) => { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && (Object)(object)ObjectDB.instance.GetItemPrefab("YmirRemains") != (Object)null) { Requirement[] resources = SerializedRequirements.toPieceReqs(new SerializedRequirements(cfg.craft.Value)); piecePrefab2.m_resources = resources; Piece[] array4 = Object.FindObjectsOfType(); foreach (Piece val in array4) { if (val.m_name == pieceName) { val.m_resources = resources; } } } }; for (int j = 0; j < piece.Conversions.Count; j++) { string text4 = ((piece.Conversions.Count > 1) ? $"{j + 1}. " : ""); Conversion conversion = piece.Conversions[j]; conversion.config = new Conversion.ConversionConfig(); int index = j; conversion.config.input = config(englishName, text4 + "Conversion Input Item", conversion.Input, new ConfigDescription("Conversion input item within " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName } })); conversion.config.input.SettingChanged += [NullableContext(0)] (object _, EventArgs _) => { if (index < piece.conversions.Count) { ObjectDB instance2 = ObjectDB.instance; if (instance2 != null) { ItemDrop from = SerializedRequirements.fetchByName(instance2, conversion.config.input.Value); piece.conversions[index].m_from = from; } } }; conversion.config.output = config(englishName, text4 + "Conversion Output Item", conversion.Output, new ConfigDescription("Conversion output item within " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName } })); conversion.config.output.SettingChanged += [NullableContext(0)] (object _, EventArgs _) => { if (index < piece.conversions.Count) { ObjectDB instance = ObjectDB.instance; if (instance != null) { ItemDrop to = SerializedRequirements.fetchByName(instance, conversion.config.output.Value); piece.conversions[index].m_to = to; } } }; } void BuildTableConfigChanged(object o, EventArgs e) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (registeredPieces.Count > 0) { if (cfg.category.Value == BuildPieceCategory.Custom) { piecePrefab2.m_category = PiecePrefabManager.GetCategory(cfg.customCategory.Value); } else { piecePrefab2.m_category = (PieceCategory)cfg.category.Value; } if (Object.op_Implicit((Object)(object)Hud.instance)) { PiecePrefabManager.CategoryRefreshNeeded = true; PiecePrefabManager.CreateCategoryTabs(); } } customTableAttributes.Browsable = cfg.category.Value == BuildPieceCategory.Custom; ReloadConfigDisplay(); } void ExtensionTableConfigChanged(object o, EventArgs e) { if (piece.RequiredItems.Requirements.Count > 0) { CraftingTable value2 = cfg.extensionTable.Value; CraftingTable craftingTable = value2; if (craftingTable == CraftingTable.Custom) { StationExtension obj2 = pieceExtensionComp; GameObject prefab2 = ZNetScene.instance.GetPrefab(cfg.customExtentionTable.Value); obj2.m_craftingStation = ((prefab2 != null) ? prefab2.GetComponent() : null); } else { pieceExtensionComp.m_craftingStation = ZNetScene.instance.GetPrefab(((InternalName)typeof(CraftingTable).GetMember(cfg.extensionTable.Value.ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName).GetComponent(); } pieceExtensionComp.m_maxStationDistance = cfg.maxStationDistance.Value; } customTableAttributes.Browsable = cfg.extensionTable.Value == CraftingTable.Custom; foreach (ConfigurationManagerAttributes item5 in hideWhenNoneAttributes2) { item5.Browsable = cfg.extensionTable.Value != CraftingTable.None; } ReloadConfigDisplay(); plugin.Config.Save(); } void TableConfigChanged(object o, EventArgs e) { if (piece.RequiredItems.Requirements.Count > 0) { switch (cfg.table.Value) { case CraftingTable.None: piecePrefab2.m_craftingStation = null; break; case CraftingTable.Custom: { Piece obj = piecePrefab2; GameObject prefab = ZNetScene.instance.GetPrefab(cfg.customTable.Value); obj.m_craftingStation = ((prefab != null) ? prefab.GetComponent() : null); break; } default: piecePrefab2.m_craftingStation = ZNetScene.instance.GetPrefab(((InternalName)typeof(CraftingTable).GetMember(cfg.table.Value.ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName).GetComponent(); break; } } customTableAttributes.Browsable = cfg.table.Value == CraftingTable.Custom; foreach (ConfigurationManagerAttributes item6 in hideWhenNoneAttributes) { item6.Browsable = cfg.table.Value != CraftingTable.None; } ReloadConfigDisplay(); plugin.Config.Save(); } ConfigEntry itemConfig(string name, string value, string desc) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes6 = new ConfigurationManagerAttributes { CustomDrawer = DrawConfigTable, Order = (order -= 1), Category = localizedName }; return config(englishName, name, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes6 })); } } foreach (BuildPiece registeredPiece3 in registeredPieces) { ConfigEntryBase enabledCfg = registeredPiece3.RecipeIsActive; Piece piecePrefab; if (enabledCfg != null) { piecePrefab = registeredPiece3.Prefab.GetComponent(); ConfigChanged(null, null); ((object)enabledCfg).GetType().GetEvent("SettingChanged").AddEventHandler(enabledCfg, new EventHandler(ConfigChanged)); } registeredPiece3.InitializeNewRegisteredPiece(registeredPiece3); [NullableContext(2)] void ConfigChanged(object o, EventArgs e) { piecePrefab.m_enabled = (int)enabledCfg.BoxedValue != 0; } } if (saveOnConfigSet) { plugin.Config.SaveOnConfigSet = true; plugin.Config.Save(); } void ReloadConfigDisplay() { object obj3 = configManagerType?.GetProperty("DisplayingWindow").GetValue(configManager); if (obj3 is bool && (bool)obj3) { configManagerType.GetMethod("BuildSettingList").Invoke(configManager, Array.Empty()); } } } private void InitializeNewRegisteredPiece(BuildPiece piece) { ConfigEntryBase recipeIsActive = piece.RecipeIsActive; PieceConfig cfg; Piece piecePrefab; string pieceName; if (recipeIsActive != null) { pieceConfigs.TryGetValue(piece, out cfg); piecePrefab = piece.Prefab.GetComponent(); pieceName = piecePrefab.m_name; ((object)recipeIsActive).GetType().GetEvent("SettingChanged").AddEventHandler(recipeIsActive, new EventHandler(ConfigChanged)); } void ConfigChanged(object o, EventArgs e) { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && (Object)(object)ObjectDB.instance.GetItemPrefab("YmirRemains") != (Object)null && cfg != null) { Requirement[] resources = SerializedRequirements.toPieceReqs(new SerializedRequirements(cfg.craft.Value)); piecePrefab.m_resources = resources; Piece[] array = Object.FindObjectsOfType(); foreach (Piece val in array) { if (val.m_name == pieceName) { val.m_resources = resources; } } } } } [HarmonyPriority(700)] internal static void Patch_ObjectDBInit(ObjectDB __instance) { //IL_0489: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Expected O, but got Unknown if ((Object)(object)__instance.GetItemPrefab("YmirRemains") == (Object)null) { return; } foreach (BuildPiece registeredPiece in registeredPieces) { pieceConfigs.TryGetValue(registeredPiece, out var value); registeredPiece.Prefab.GetComponent().m_resources = SerializedRequirements.toPieceReqs((value == null) ? new SerializedRequirements(registeredPiece.RequiredItems.Requirements) : new SerializedRequirements(value.craft.Value)); foreach (ExtensionConfig extensionStation in registeredPiece.Extension.ExtensionStations) { switch ((value == null || registeredPiece.Extension.ExtensionStations.Count > 0) ? extensionStation.Table : value.extensionTable.Value) { case CraftingTable.None: registeredPiece.Prefab.GetComponent().m_craftingStation = null; break; case CraftingTable.Custom: { GameObject prefab = ZNetScene.instance.GetPrefab((value == null || registeredPiece.Extension.ExtensionStations.Count > 0) ? extensionStation.custom : value.customExtentionTable.Value); if (prefab != null) { registeredPiece.Prefab.GetComponent().m_craftingStation = prefab.GetComponent(); } else { Debug.LogWarning((object)("Custom crafting station '" + ((value == null || registeredPiece.Extension.ExtensionStations.Count > 0) ? extensionStation.custom : value.customExtentionTable.Value) + "' does not exist")); } break; } default: if (value != null && value.table.Value == CraftingTable.None) { registeredPiece.Prefab.GetComponent().m_craftingStation = null; } else { registeredPiece.Prefab.GetComponent().m_craftingStation = ZNetScene.instance.GetPrefab(((InternalName)typeof(CraftingTable).GetMember(((value == null || registeredPiece.Extension.ExtensionStations.Count > 0) ? extensionStation.Table : value.extensionTable.Value).ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName).GetComponent(); } break; } } foreach (CraftingStationConfig station in registeredPiece.Crafting.Stations) { switch ((value == null || registeredPiece.Crafting.Stations.Count > 0) ? station.Table : value.table.Value) { case CraftingTable.None: registeredPiece.Prefab.GetComponent().m_craftingStation = null; break; case CraftingTable.Custom: { GameObject prefab2 = ZNetScene.instance.GetPrefab((value == null || registeredPiece.Crafting.Stations.Count > 0) ? station.custom : value.customTable.Value); if (prefab2 != null) { registeredPiece.Prefab.GetComponent().m_craftingStation = prefab2.GetComponent(); } else { Debug.LogWarning((object)("Custom crafting station '" + ((value == null || registeredPiece.Crafting.Stations.Count > 0) ? station.custom : value.customTable.Value) + "' does not exist")); } break; } default: if (value != null && value.table.Value == CraftingTable.None) { registeredPiece.Prefab.GetComponent().m_craftingStation = null; } else { registeredPiece.Prefab.GetComponent().m_craftingStation = ZNetScene.instance.GetPrefab(((InternalName)typeof(CraftingTable).GetMember(((value == null || registeredPiece.Crafting.Stations.Count > 0) ? station.Table : value.table.Value).ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName).GetComponent(); } break; } } registeredPiece.conversions = new List(); for (int i = 0; i < registeredPiece.Conversions.Count; i++) { Conversion conversion = registeredPiece.Conversions[i]; registeredPiece.conversions.Add(new ItemConversion { m_from = SerializedRequirements.fetchByName(ObjectDB.instance, conversion.config?.input.Value ?? conversion.Input), m_to = SerializedRequirements.fetchByName(ObjectDB.instance, conversion.config?.output.Value ?? conversion.Output) }); if (registeredPiece.conversions[i].m_from != null && registeredPiece.conversions[i].m_to != null) { registeredPiece.Prefab.GetComponent().m_conversion.Add(registeredPiece.conversions[i]); } } } } public void Snapshot(float lightIntensity = 1.3f, Quaternion? cameraRotation = null) { SnapshotPiece(Prefab, lightIntensity, cameraRotation); } internal void SnapshotPiece(GameObject prefab, float lightIntensity = 1.3f, Quaternion? cameraRotation = null) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Expected O, but got Unknown //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)prefab == (Object)null) && (prefab.GetComponentsInChildren().Any() || prefab.GetComponentsInChildren().Any())) { Camera component = new GameObject("CameraIcon", new Type[1] { typeof(Camera) }).GetComponent(); component.backgroundColor = Color.clear; component.clearFlags = (CameraClearFlags)2; ((Component)component).transform.position = new Vector3(10000f, 10000f, 10000f); ((Component)component).transform.rotation = (Quaternion)(((??)cameraRotation) ?? Quaternion.Euler(0f, 180f, 0f)); component.fieldOfView = 0.5f; component.farClipPlane = 100000f; component.cullingMask = 8; Light component2 = new GameObject("LightIcon", new Type[1] { typeof(Light) }).GetComponent(); ((Component)component2).transform.position = new Vector3(10000f, 10000f, 10000f); ((Component)component2).transform.rotation = Quaternion.Euler(5f, 180f, 5f); component2.type = (LightType)1; component2.cullingMask = 8; component2.intensity = lightIntensity; GameObject val = Object.Instantiate(prefab); Transform[] componentsInChildren = val.GetComponentsInChildren(); foreach (Transform val2 in componentsInChildren) { ((Component)val2).gameObject.layer = 3; } val.transform.position = Vector3.zero; val.transform.rotation = Quaternion.Euler(23f, 51f, 25.8f); ((Object)val).name = ((Object)prefab).name; MeshRenderer[] componentsInChildren2 = val.GetComponentsInChildren(); Vector3 val3 = componentsInChildren2.Aggregate(Vector3.positiveInfinity, [NullableContext(0)] (Vector3 cur, MeshRenderer renderer) => { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Bounds bounds2 = ((Renderer)renderer).bounds; return Vector3.Min(cur, ((Bounds)(ref bounds2)).min); }); Vector3 val4 = componentsInChildren2.Aggregate(Vector3.negativeInfinity, [NullableContext(0)] (Vector3 cur, MeshRenderer renderer) => { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = ((Renderer)renderer).bounds; return Vector3.Max(cur, ((Bounds)(ref bounds)).max); }); val.transform.position = new Vector3(10000f, 10000f, 10000f) - (val3 + val4) / 2f; Vector3 val5 = val4 - val3; TimedDestruction val6 = val.AddComponent(); val6.Trigger(1f); Rect val7 = default(Rect); ((Rect)(ref val7))..ctor(0f, 0f, 128f, 128f); component.targetTexture = RenderTexture.GetTemporary((int)((Rect)(ref val7)).width, (int)((Rect)(ref val7)).height); component.fieldOfView = 20f; float num = Mathf.Max(val5.x, val5.y) + 0.1f; float num2 = num / Mathf.Tan(component.fieldOfView * ((float)Math.PI / 180f)) * 1.1f; ((Component)component).transform.position = new Vector3(10000f, 10000f, 10000f) + new Vector3(0f, 0f, num2); component.Render(); RenderTexture active = RenderTexture.active; RenderTexture.active = component.targetTexture; Texture2D val8 = new Texture2D((int)((Rect)(ref val7)).width, (int)((Rect)(ref val7)).height, (TextureFormat)4, false); val8.ReadPixels(new Rect(0f, 0f, (float)(int)((Rect)(ref val7)).width, (float)(int)((Rect)(ref val7)).height), 0, 0); val8.Apply(); RenderTexture.active = active; prefab.GetComponent().m_icon = Sprite.Create(val8, new Rect(0f, 0f, (float)(int)((Rect)(ref val7)).width, (float)(int)((Rect)(ref val7)).height), Vector2.one / 2f); ((Component)component2).gameObject.SetActive(false); component.targetTexture.Release(); ((Component)component).gameObject.SetActive(false); val.SetActive(false); Object.DestroyImmediate((Object)(object)val); Object.Destroy((Object)(object)component); Object.Destroy((Object)(object)component2); Object.Destroy((Object)(object)((Component)component).gameObject); Object.Destroy((Object)(object)((Component)component2).gameObject); } } private static void DrawConfigTable(ConfigEntryBase cfg) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Expected O, but got Unknown //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select([NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault(); List list = new List(); bool flag = false; int num = (int)(configManager?.GetType().GetProperty("RightColumnWidth", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(nonPublic: true) .Invoke(configManager, Array.Empty()) ?? ((object)130)); GUILayout.BeginVertical(Array.Empty()); foreach (Requirement req in new SerializedRequirements((string)cfg.BoxedValue).Reqs) { GUILayout.BeginHorizontal(Array.Empty()); int num2 = req.amount; if (int.TryParse(GUILayout.TextField(num2.ToString(), new GUIStyle(GUI.skin.textField) { fixedWidth = 40f }, Array.Empty()), out var result) && result != num2 && !valueOrDefault) { num2 = result; flag = true; } string text = GUILayout.TextField(req.itemName, new GUIStyle(GUI.skin.textField) { fixedWidth = num - 40 - 67 - 21 - 21 - 12 }, Array.Empty()); string text2 = (valueOrDefault ? req.itemName : text); flag = flag || text2 != req.itemName; bool flag2 = req.recover; if (GUILayout.Toggle(req.recover, "Recover", new GUIStyle(GUI.skin.toggle) { fixedWidth = 67f }, Array.Empty()) != req.recover) { flag2 = !flag2; flag = true; } if (GUILayout.Button("x", new GUIStyle(GUI.skin.button) { fixedWidth = 21f }, Array.Empty()) && !valueOrDefault) { flag = true; } else { list.Add(new Requirement { amount = num2, itemName = text2, recover = flag2 }); } if (GUILayout.Button("+", new GUIStyle(GUI.skin.button) { fixedWidth = 21f }, Array.Empty()) && !valueOrDefault) { flag = true; list.Add(new Requirement { amount = 1, itemName = "", recover = false }); } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (flag) { cfg.BoxedValue = new SerializedRequirements(list).ToString(); } } private static ConfigEntry config<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] T>(string group, string name, T value, ConfigDescription description) { ConfigEntry val = plugin.Config.Bind(group, name, value, description); configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T)) .Invoke(configSync, new object[1] { val }); return val; } private static ConfigEntry config<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] T>(string group, string name, T value, string description) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty())); } } public static class GoExtensions { [NullableContext(1)] public static T GetOrAddComponent<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] T>(this GameObject gameObject) where T : Component { return gameObject.GetComponent() ?? gameObject.AddComponent(); } } [PublicAPI] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class LocalizeKey { private static readonly List keys = new List(); public readonly string Key; public readonly Dictionary Localizations = new Dictionary(); public LocalizeKey(string key) { Key = key.Replace("$", ""); keys.Add(this); } public void Alias(string alias) { Localizations.Clear(); if (!alias.Contains("$")) { alias = "$" + alias; } Localizations["alias"] = alias; Localization.instance.AddWord(Key, Localization.instance.Localize(alias)); } public LocalizeKey English(string key) { return addForLang("English", key); } public LocalizeKey Swedish(string key) { return addForLang("Swedish", key); } public LocalizeKey French(string key) { return addForLang("French", key); } public LocalizeKey Italian(string key) { return addForLang("Italian", key); } public LocalizeKey German(string key) { return addForLang("German", key); } public LocalizeKey Spanish(string key) { return addForLang("Spanish", key); } public LocalizeKey Russian(string key) { return addForLang("Russian", key); } public LocalizeKey Romanian(string key) { return addForLang("Romanian", key); } public LocalizeKey Bulgarian(string key) { return addForLang("Bulgarian", key); } public LocalizeKey Macedonian(string key) { return addForLang("Macedonian", key); } public LocalizeKey Finnish(string key) { return addForLang("Finnish", key); } public LocalizeKey Danish(string key) { return addForLang("Danish", key); } public LocalizeKey Norwegian(string key) { return addForLang("Norwegian", key); } public LocalizeKey Icelandic(string key) { return addForLang("Icelandic", key); } public LocalizeKey Turkish(string key) { return addForLang("Turkish", key); } public LocalizeKey Lithuanian(string key) { return addForLang("Lithuanian", key); } public LocalizeKey Czech(string key) { return addForLang("Czech", key); } public LocalizeKey Hungarian(string key) { return addForLang("Hungarian", key); } public LocalizeKey Slovak(string key) { return addForLang("Slovak", key); } public LocalizeKey Polish(string key) { return addForLang("Polish", key); } public LocalizeKey Dutch(string key) { return addForLang("Dutch", key); } public LocalizeKey Portuguese_European(string key) { return addForLang("Portuguese_European", key); } public LocalizeKey Portuguese_Brazilian(string key) { return addForLang("Portuguese_Brazilian", key); } public LocalizeKey Chinese(string key) { return addForLang("Chinese", key); } public LocalizeKey Japanese(string key) { return addForLang("Japanese", key); } public LocalizeKey Korean(string key) { return addForLang("Korean", key); } public LocalizeKey Hindi(string key) { return addForLang("Hindi", key); } public LocalizeKey Thai(string key) { return addForLang("Thai", key); } public LocalizeKey Abenaki(string key) { return addForLang("Abenaki", key); } public LocalizeKey Croatian(string key) { return addForLang("Croatian", key); } public LocalizeKey Georgian(string key) { return addForLang("Georgian", key); } public LocalizeKey Greek(string key) { return addForLang("Greek", key); } public LocalizeKey Serbian(string key) { return addForLang("Serbian", key); } public LocalizeKey Ukrainian(string key) { return addForLang("Ukrainian", key); } private LocalizeKey addForLang(string lang, string value) { Localizations[lang] = value; if (Localization.instance.GetSelectedLanguage() == lang) { Localization.instance.AddWord(Key, value); } else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key)) { Localization.instance.AddWord(Key, value); } return this; } [HarmonyPriority(300)] internal static void AddLocalizedKeys(Localization __instance, string language) { foreach (LocalizeKey key in keys) { string value2; if (key.Localizations.TryGetValue(language, out var value) || key.Localizations.TryGetValue("English", out value)) { __instance.AddWord(key.Key, value); } else if (key.Localizations.TryGetValue("alias", out value2)) { __instance.AddWord(key.Key, Localization.instance.Localize(value2)); } } } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static class LocalizationCache { private static readonly Dictionary localizations = new Dictionary(); internal static void LocalizationPostfix(Localization __instance, string language) { string key = localizations.FirstOrDefault([NullableContext(0)] (KeyValuePair l) => l.Value == __instance).Key; if (key != null) { localizations.Remove(key); } if (!localizations.ContainsKey(language)) { localizations.Add(language, __instance); } } public static Localization ForLanguage([<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] string language = null) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out var value)) { return value; } value = new Localization(); if (language != null) { value.SetupLanguage(language); } return value; } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class AdminSyncing { private static bool isServer; internal static bool registeredOnClient; [HarmonyPriority(700)] internal static void AdminStatusSync(ZNet __instance) { isServer = __instance.IsServer(); if (BuildPiece._plugin != null) { if (isServer) { ZRoutedRpc.instance.Register(BuildPiece._plugin.Info.Metadata.Name + " PMAdminStatusSync", (Action)RPC_AdminPieceAddRemove); } else if (!registeredOnClient) { ZRoutedRpc.instance.Register(BuildPiece._plugin.Info.Metadata.Name + " PMAdminStatusSync", (Action)RPC_AdminPieceAddRemove); registeredOnClient = true; } } if (isServer) { ((MonoBehaviour)ZNet.instance).StartCoroutine(WatchAdminListChanges()); } static void SendAdmin(List peers, bool isAdmin) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(isAdmin); ((MonoBehaviour)ZNet.instance).StartCoroutine(sendZPackage(peers, val)); } static IEnumerator WatchAdminListChanges() { List currentList = new List(ZNet.instance.m_adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!ZNet.instance.m_adminList.GetList().SequenceEqual(currentList)) { currentList = new List(ZNet.instance.m_adminList.GetList()); List adminPeer = (from p in ZNet.instance.GetPeers() where ZNet.instance.ListContainsId(ZNet.instance.m_adminList, p.m_rpc.GetSocket().GetHostName()) select p).ToList(); List nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList(); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } private static IEnumerator sendZPackage(List peers, ZPackage package) { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { yield break; } byte[] rawData = package.GetArray(); if (rawData != null && rawData.LongLength > 10000) { ZPackage compressedPackage = new ZPackage(); compressedPackage.Write(4); MemoryStream output = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(output, CompressionLevel.Optimal)) { deflateStream.Write(rawData, 0, rawData.Length); } compressedPackage.Write(output.ToArray()); package = compressedPackage; } List> writers = (from peer in peers where peer.IsReady() select peer into p select TellPeerAdminStatus(p, package)).ToList(); writers.RemoveAll((IEnumerator writer) => !writer.MoveNext()); while (writers.Count > 0) { yield return null; writers.RemoveAll((IEnumerator writer) => !writer.MoveNext()); } } private static IEnumerator TellPeerAdminStatus(ZNetPeer peer, ZPackage package) { ZRoutedRpc rpc = ZRoutedRpc.instance; if (rpc != null) { SendPackage(package); } void SendPackage(ZPackage pkg) { BaseUnityPlugin plugin = BuildPiece._plugin; string text = ((plugin != null) ? plugin.Info.Metadata.Name : null) + " PMAdminStatusSync"; if (isServer) { peer.m_rpc.Invoke(text, new object[1] { pkg }); } else { rpc.InvokeRoutedRPC(peer.m_server ? 0 : peer.m_uid, text, new object[1] { pkg }); } } yield break; } internal static void RPC_AdminPieceAddRemove(long sender, ZPackage package) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown ZNetPeer peer = ZNet.instance.GetPeer(sender); bool flag = false; try { flag = package.ReadBool(); } catch { } if (isServer) { ZRoutedRpc instance = ZRoutedRpc.instance; long everybody = ZRoutedRpc.Everybody; BaseUnityPlugin plugin = BuildPiece._plugin; instance.InvokeRoutedRPC(everybody, ((plugin != null) ? plugin.Info.Metadata.Name : null) + " PMAdminStatusSync", new object[1] { (object)new ZPackage() }); if (ZNet.instance.ListContainsId(ZNet.instance.m_adminList, peer.m_rpc.GetSocket().GetHostName())) { ZPackage val = new ZPackage(); val.Write(true); ZRpc rpc = peer.m_rpc; BaseUnityPlugin plugin2 = BuildPiece._plugin; rpc.Invoke(((plugin2 != null) ? plugin2.Info.Metadata.Name : null) + " PMAdminStatusSync", new object[1] { val }); } return; } foreach (BuildPiece registeredPiece in BuildPiece.registeredPieces) { if (!registeredPiece.SpecialProperties.AdminOnly) { continue; } Piece component = registeredPiece.Prefab.GetComponent(); string name = component.m_name; string text = Localization.instance.Localize(name).Trim(); if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || (Object)(object)ObjectDB.instance.GetItemPrefab("YmirRemains") == (Object)null) { continue; } Piece[] array = Object.FindObjectsOfType(); foreach (Piece val2 in array) { if (flag) { if (val2.m_name == name) { val2.m_enabled = true; } } else if (val2.m_name == name) { val2.m_enabled = false; } } List pieces = ObjectDB.instance.GetItemPrefab("Hammer").GetComponent().m_itemData.m_shared.m_buildPieces.m_pieces; if (flag) { if (!pieces.Contains(ZNetScene.instance.GetPrefab(((Object)component).name))) { pieces.Add(ZNetScene.instance.GetPrefab(((Object)component).name)); } } else if (pieces.Contains(ZNetScene.instance.GetPrefab(((Object)component).name))) { pieces.Remove(ZNetScene.instance.GetPrefab(((Object)component).name)); } } } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [HarmonyPatch(typeof(ZNet), "OnNewConnection")] internal class RegisterClientRPCPatch { private static void Postfix(ZNet __instance, ZNetPeer peer) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown if (!__instance.IsServer()) { ZRpc rpc = peer.m_rpc; BaseUnityPlugin plugin = BuildPiece._plugin; rpc.Register(((plugin != null) ? plugin.Info.Metadata.Name : null) + " PMAdminStatusSync", (Action)RPC_InitialAdminSync); return; } ZPackage val = new ZPackage(); val.Write(__instance.ListContainsId(__instance.m_adminList, peer.m_rpc.GetSocket().GetHostName())); ZRpc rpc2 = peer.m_rpc; BaseUnityPlugin plugin2 = BuildPiece._plugin; rpc2.Invoke(((plugin2 != null) ? plugin2.Info.Metadata.Name : null) + " PMAdminStatusSync", new object[1] { val }); } private static void RPC_InitialAdminSync(ZRpc rpc, ZPackage package) { AdminSyncing.RPC_AdminPieceAddRemove(0L, package); } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public static class PiecePrefabManager { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] private struct BundleId { [UsedImplicitly] public string assetBundleFileName; [UsedImplicitly] public string folderName; } private static readonly Dictionary bundleCache; private static readonly List piecePrefabs; private static readonly Dictionary PieceCategories; private static readonly Dictionary OtherPieceCategories; private static readonly Dictionary VanillaLabels; internal static bool CategoryRefreshNeeded; static PiecePrefabManager() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Expected O, but got Unknown //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Expected O, but got Unknown //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Expected O, but got Unknown //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Expected O, but got Unknown //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Expected O, but got Unknown //IL_02eb: Expected O, but got Unknown //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Expected O, but got Unknown //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Expected O, but got Unknown //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Expected O, but got Unknown //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Expected O, but got Unknown //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Expected O, but got Unknown //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Expected O, but got Unknown bundleCache = new Dictionary(); piecePrefabs = new List(); PieceCategories = new Dictionary(); OtherPieceCategories = new Dictionary(); VanillaLabels = new Dictionary(); Harmony val = new Harmony("org.bepinex.helpers.PieceManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(BuildPiece), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "Patch_ObjectDBInit", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(BuildPiece), "Patch_ObjectDBInit", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ObjectDB), "CopyOtherDB", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "Patch_ObjectDBInit", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNet), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AdminSyncing), "AdminStatusSync", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "Patch_ZNetSceneAwake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "RefFixPatch_ZNetSceneAwake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(PieceTable), "UpdateAvailable", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "UpdateAvailable_Transpiler", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(PieceTable), "UpdateAvailable", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "UpdateAvailable_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "UpdateAvailable_Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Player), "SetPlaceMode", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "Patch_SetPlaceMode", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Hud), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "Hud_AwakeCreateTabs", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Hud), "UpdateBuild", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "RepositionCatsIfNeeded", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Hud), "LateUpdate", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "RepositionCatsIfNeeded", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Enum), "GetValues", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "EnumGetValuesPatch", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Enum), "GetNames", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "EnumGetNamesPatch", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static AssetBundle RegisterAssetBundle(string assetBundleFileName, string folderName = "assets") { BundleId bundleId = default(BundleId); bundleId.assetBundleFileName = assetBundleFileName; bundleId.folderName = folderName; BundleId key = bundleId; if (!bundleCache.TryGetValue(key, out var value)) { Dictionary dictionary = bundleCache; AssetBundle? obj = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)([NullableContext(0)] (AssetBundle a) => ((Object)a).name == assetBundleFileName)) ?? AssetBundle.LoadFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + folderName + "." + assetBundleFileName)); AssetBundle result = obj; dictionary[key] = obj; return result; } return value; } public static IEnumerable FixRefs(AssetBundle assetBundle) { return assetBundle.LoadAllAssets(); } public static GameObject RegisterPrefab(string assetBundleFileName, string prefabName, string folderName = "assets") { return RegisterPrefab(RegisterAssetBundle(assetBundleFileName, folderName), prefabName); } public static GameObject RegisterPrefab(AssetBundle assets, string prefabName) { if ((Object)(object)assets == (Object)null) { Debug.LogError((object)"Failed to load asset bundle. Please make sure to mark all asset bundles as embedded resources."); return null; } GameObject val = assets.LoadAsset(prefabName); if ((Object)(object)val == (Object)null) { Debug.LogError((object)("Failed to load prefab " + prefabName + " from asset bundle " + ((Object)assets).name)); return null; } piecePrefabs.Add(val); return val; } public static Sprite RegisterSprite(string assetBundleFileName, string prefabName, string folderName = "assets") { return RegisterSprite(RegisterAssetBundle(assetBundleFileName, folderName), prefabName); } public static Sprite RegisterSprite(AssetBundle assets, string prefabName) { return assets.LoadAsset(prefabName); } private static void EnumGetValuesPatch(Type enumType, ref Array __result) { if (!(enumType != typeof(PieceCategory)) && PieceCategories.Count != 0) { PieceCategory[] array = (PieceCategory[])(object)new PieceCategory[__result.Length + PieceCategories.Count]; __result.CopyTo(array, 0); PieceCategories.Values.CopyTo(array, __result.Length); __result = array; } } private static void EnumGetNamesPatch(Type enumType, ref string[] __result) { if (!(enumType != typeof(PieceCategory)) && PieceCategories.Count != 0) { __result = CollectionExtensions.AddRangeToArray(__result, PieceCategories.Keys.ToArray()); } } public static Dictionary GetPieceCategoriesMap() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) Array values = Enum.GetValues(typeof(PieceCategory)); string[] names = Enum.GetNames(typeof(PieceCategory)); Dictionary dictionary = new Dictionary(); for (int i = 0; i < values.Length; i++) { dictionary[(PieceCategory)values.GetValue(i)] = names[i]; } return dictionary; } public static PieceCategory GetCategory(string name) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (Enum.TryParse(name, ignoreCase: true, out PieceCategory result)) { return result; } if (PieceCategories.TryGetValue(name, out result)) { return result; } if (OtherPieceCategories.TryGetValue(name, out result)) { return result; } Dictionary pieceCategoriesMap = GetPieceCategoriesMap(); foreach (KeyValuePair item in pieceCategoriesMap) { if (item.Value == name) { result = item.Key; OtherPieceCategories[name] = result; return result; } } result = (PieceCategory)(pieceCategoriesMap.Count - 1); PieceCategories[name] = result; string categoryToken = GetCategoryToken(name); Localization.instance.AddWord(categoryToken, name); return result; } internal static void CreateCategoryTabs() { if (Object.op_Implicit((Object)(object)Hud.instance)) { int num = ModifiedMaxCategory(); for (int i = Hud.instance.m_pieceCategoryTabs.Length; i < num; i++) { GameObject val = CreateCategoryTab(); Hud.instance.m_pieceCategoryTabs = CollectionExtensions.AddItem((IEnumerable)Hud.instance.m_pieceCategoryTabs, val).ToArray(); } if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)Player.m_localPlayer.m_buildPieces)) { RepositionCategories(Player.m_localPlayer.m_buildPieces); Player.m_localPlayer.UpdateAvailablePiecesList(); } } } private static GameObject CreateCategoryTab() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) GameObject val = Hud.instance.m_pieceCategoryTabs[0]; GameObject val2 = Object.Instantiate(Hud.instance.m_pieceCategoryTabs[0], val.transform.parent); val2.SetActive(false); UIInputHandler orAddComponent = val2.GetOrAddComponent(); orAddComponent.m_onLeftDown = (Action)Delegate.Combine(orAddComponent.m_onLeftDown, new Action(Hud.instance.OnLeftClickCategory)); TMP_Text[] componentsInChildren = val2.GetComponentsInChildren(); foreach (TMP_Text val3 in componentsInChildren) { val3.rectTransform.offsetMin = new Vector2(3f, 1f); val3.rectTransform.offsetMax = new Vector2(-3f, -1f); val3.enableAutoSizing = true; val3.fontSizeMin = 12f; val3.fontSizeMax = 20f; val3.lineSpacing = 0.8f; val3.textWrappingMode = (TextWrappingModes)1; val3.overflowMode = (TextOverflowModes)3; } return val2; } private static int ModifiedMaxCategory() { return Enum.GetValues(typeof(PieceCategory)).Length - 1; } private static int GetMaxCategoryOrDefault() { try { return (int)Enum.Parse(typeof(PieceCategory), "Max"); } catch (ArgumentException) { Debug.LogWarning((object)"Could not find Piece.PieceCategory.Max, using fallback value 4"); return 4; } } private static List TranspileMaxCategory(IEnumerable instructions, int maxOffset) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown int num = GetMaxCategoryOrDefault() + maxOffset; List list = new List(); foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.LoadsConstant(instruction, (long)num)) { list.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(PiecePrefabManager), "ModifiedMaxCategory", (Type[])null, (Type[])null))); if (maxOffset != 0) { list.Add(new CodeInstruction(OpCodes.Ldc_I4, (object)maxOffset)); list.Add(new CodeInstruction(OpCodes.Add, (object)null)); } } else { list.Add(instruction); } } return list; } private static IEnumerable UpdateAvailable_Transpiler(IEnumerable instructions) { return TranspileMaxCategory(instructions, 0); } private static HashSet CategoriesInPieceTable(PieceTable pieceTable) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); Piece val = default(Piece); foreach (GameObject item in pieceTable.m_pieces.Where([NullableContext(0)] (GameObject pieceFab) => (Object)(object)pieceFab != (Object)null)) { if (item.TryGetComponent(ref val)) { hashSet.Add(val.m_category); } } return hashSet; } private static void RepositionCatsIfNeeded() { if (CategoryRefreshNeeded) { CategoryRefreshNeeded = false; CreateCategoryTabs(); RepositionCats(); } } private static void RepositionCats() { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)Player.m_localPlayer.m_buildPieces)) { RepositionCategories(Player.m_localPlayer.m_buildPieces); } } private static void RepositionCategories(PieceTable pieceTable) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)Hud.instance.m_pieceCategoryTabs[0].transform; RectTransform val2 = (RectTransform)Hud.instance.m_pieceCategoryRoot.transform; RectTransform val3 = (RectTransform)Hud.instance.m_pieceSelectionWindow.transform; HorizontalLayoutGroup val4 = default(HorizontalLayoutGroup); if (((Component)((Transform)val).parent).TryGetComponent(ref val4)) { Object.DestroyImmediate((Object)(object)val4); } Rect rect = val.rect; Vector2 size = ((Rect)(ref rect)).size; GridLayoutGroup val5 = default(GridLayoutGroup); GridLayoutGroup val6 = (((Component)((Transform)val).parent).TryGetComponent(ref val5) ? val5 : ((Component)((Transform)val).parent).gameObject.AddComponent()); val6.cellSize = size; val6.spacing = new Vector2(0f, 1f); val6.constraint = (Constraint)1; val6.constraintCount = 5; ((LayoutGroup)val6).childAlignment = (TextAnchor)4; HashSet hashSet = CategoriesInPieceTable(pieceTable); UpdatePieceTableCategories(pieceTable, hashSet); rect = val2.rect; int num = Mathf.Max((int)(((Rect)(ref rect)).width / size.x), 1); int count = pieceTable.m_categories.Count; float num2 = (0f - size.x) * (float)num / 2f + size.x / 2f; float num3 = (size.y + 1f) * Mathf.Floor((float)(count - 1) / (float)num) + 5f; Vector2 val7 = default(Vector2); ((Vector2)(ref val7))..ctor(num2, num3); int num4 = Mathf.CeilToInt((float)count / (float)num); float num5 = (size.y + 1f) * (float)num4; RectTransform component = ((Component)((Transform)val).parent).GetComponent(); component.anchoredPosition = new Vector2(component.anchoredPosition.x, num5 / 2f); int num6 = 0; for (int i = 0; i < Hud.instance.m_pieceCategoryTabs.Length; i++) { GameObject val8 = Hud.instance.m_pieceCategoryTabs[i]; if ((Object)(object)val8 == (Object)null) { continue; } if (i >= pieceTable.m_categories.Count) { val8.SetActive(false); continue; } PieceCategory item = pieceTable.m_categories[i]; string text = pieceTable.m_categoryLabels[i]; if (hashSet.Contains(item)) { num6++; } val8.GetComponentInChildren().text = Localization.instance.Localize(text); } Transform obj = ((Transform)val3).Find("Bkg2"); RectTransform val9 = (RectTransform)((obj != null) ? ((Component)obj).transform : null); if (Object.op_Implicit((Object)(object)val9)) { float num7 = (size.y + 1f) * (float)Mathf.Max(0, Mathf.FloorToInt((float)(num6 - 1) / (float)num)); val9.offsetMax = new Vector2(val9.offsetMax.x, num7); } else { Debug.LogWarning((object)"RefreshCategories: Could not find background image"); } ((Component)Hud.instance).GetComponentInParent().RefreshLocalization(); } private static void UpdatePieceTableCategories(PieceTable pieceTable, HashSet visibleCategories) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < GetMaxCategoryOrDefault(); i++) { PieceCategory val = (PieceCategory)i; if (visibleCategories.Contains(val) && !pieceTable.m_categories.Contains(val)) { pieceTable.m_categories.Add(val); pieceTable.m_categoryLabels.Add(GetVanillaLabel(val)); } if (!visibleCategories.Contains(val) && pieceTable.m_categories.Contains(val)) { int index = pieceTable.m_categories.IndexOf(val); pieceTable.m_categories.RemoveAt(index); pieceTable.m_categoryLabels.RemoveAt(index); } } foreach (KeyValuePair pieceCategory in PieceCategories) { string key = pieceCategory.Key; PieceCategory value = pieceCategory.Value; if (visibleCategories.Contains(value) && !pieceTable.m_categories.Contains(value)) { pieceTable.m_categories.Add(value); pieceTable.m_categoryLabels.Add("$" + GetCategoryToken(key)); } if (visibleCategories.Contains(value) && !pieceTable.m_categoryLabels.Contains("$" + GetCategoryToken(key))) { pieceTable.m_categoryLabels.Add("$" + GetCategoryToken(key)); } if (!visibleCategories.Contains(value) && pieceTable.m_categories.Contains(value)) { int index2 = pieceTable.m_categories.IndexOf(value); pieceTable.m_categories.RemoveAt(index2); pieceTable.m_categoryLabels.RemoveAt(index2); } } } private static string GetVanillaLabel(PieceCategory category) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!VanillaLabels.ContainsKey(category)) { SearchVanillaLabels(); } string value; return VanillaLabels.TryGetValue(category, out value) ? value : string.Empty; } private static void SearchVanillaLabels() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) PieceTable[] array = Resources.FindObjectsOfTypeAll(); foreach (PieceTable val in array) { for (int j = 0; j < val.m_categories.Count; j++) { PieceCategory key = val.m_categories[j]; if (j < val.m_categoryLabels.Count && !VanillaLabels.ContainsKey(key) && !string.IsNullOrEmpty(val.m_categoryLabels[j])) { VanillaLabels[key] = val.m_categoryLabels[j]; } } } } private static string GetCategoryToken(string name) { char[] endChars = Localization.instance.m_endChars; string text = string.Concat(name.ToLower().Split(endChars)); return "piecemanager_cat_" + text; } private static void Patch_SetPlaceMode(Player __instance) { if (Object.op_Implicit((Object)(object)__instance.m_buildPieces)) { RepositionCategories(__instance.m_buildPieces); } } private static void UpdateAvailable_Prefix(PieceTable __instance) { if (__instance.m_availablePieces.Count > 0) { int num = ModifiedMaxCategory() - __instance.m_availablePieces.Count; for (int i = 0; i < num; i++) { __instance.m_availablePieces.Add(new List()); } } } private static void UpdateAvailable_Postfix(PieceTable __instance) { Array.Resize(ref __instance.m_selectedPiece, __instance.m_availablePieces.Count); Array.Resize(ref __instance.m_lastSelectedPiece, __instance.m_availablePieces.Count); } [HarmonyPriority(200)] private static void Hud_AwakeCreateTabs() { CreateCategoryTabs(); } [HarmonyPriority(700)] private static void Patch_ZNetSceneAwake(ZNetScene __instance) { foreach (GameObject piecePrefab in piecePrefabs) { if (!__instance.m_prefabs.Contains(piecePrefab)) { __instance.m_prefabs.Add(piecePrefab); } } } [HarmonyPriority(700)] private static void RefFixPatch_ZNetSceneAwake(ZNetScene __instance) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) foreach (GameObject piecePrefab in piecePrefabs) { if (__instance.m_prefabs.Contains(piecePrefab) && Object.op_Implicit((Object)(object)piecePrefab.GetComponent())) { piecePrefab.GetComponent().m_isUpgrade = true; piecePrefab.GetComponent().m_connectionPrefab = __instance.GetPrefab("piece_workbench_ext3").GetComponent().m_connectionPrefab; piecePrefab.GetComponent().m_connectionOffset = __instance.GetPrefab("piece_workbench_ext3").GetComponent().m_connectionOffset; } } } [HarmonyPriority(300)] private static void Patch_ObjectDBInit(ObjectDB __instance) { foreach (BuildPiece registeredPiece in BuildPiece.registeredPieces) { registeredPiece.UpdateEffects(); string[] activeTools = registeredPiece.activeTools; foreach (string text in activeTools) { GameObject itemPrefab = __instance.GetItemPrefab(text); PieceTable val = ((itemPrefab != null) ? itemPrefab.GetComponent().m_itemData.m_shared.m_buildPieces : null); if (val != null && !val.m_pieces.Contains(registeredPiece.Prefab)) { val.m_pieces.Add(registeredPiece.Prefab); } } } } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [PublicAPI] [NullableContext(1)] public class Conversion { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] internal class ConversionConfig { public ConfigEntry input = null; public ConfigEntry output = null; } public string Input = null; public string Output = null; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] internal ConversionConfig config; public Conversion(BuildPiece conversionPiece) { conversionPiece.Conversions.Add(this); } } } namespace Managers { [PublicAPI] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public static class MaterialReplacer { [NullableContext(0)] public enum ShaderType { PieceShader, VegetationShader, RockShader, RugShader, GrassShader, CustomCreature, UseUnityShader } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class MaterialData { public readonly Material m_material = null; public readonly ShaderType m_type; public readonly Dictionary m_floatProperties = new Dictionary(); public MaterialData(AssetBundle assetBundle, string materialName, ShaderType type) { Material val = assetBundle.LoadAsset(materialName); if (val != null) { m_material = val; m_type = type; m_materials.Add(this); } else { Debug.LogWarning((object)(materialName + " is null")); } } public void AddFloatProperty(string propertyName, float value) { m_floatProperties[propertyName] = value; } } private static readonly Dictionary ObjectToSwap; private static readonly Dictionary OriginalMaterials; private static readonly Dictionary ObjectsForShaderReplace; private static readonly HashSet CachedShaders; private static readonly List m_materials; private static readonly Dictionary MaterialsToReplace; private static bool hasRun; public static void SwapMaterial(AssetBundle assetBundle, string materialName, string original) { Material val = assetBundle.LoadAsset(materialName); if (val != null) { MaterialsToReplace[val] = original; } else { Debug.LogWarning((object)(materialName + " is null")); } } static MaterialReplacer() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown CachedShaders = new HashSet(); m_materials = new List(); MaterialsToReplace = new Dictionary(); hasRun = false; OriginalMaterials = new Dictionary(); ObjectToSwap = new Dictionary(); ObjectsForShaderReplace = new Dictionary(); Harmony val = new Harmony("org.bepinex.helpers.PieceManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZoneSystem), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MaterialReplacer), "ReplaceAllMaterialsWithOriginal", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void RegisterGameObjectForShaderSwap(GameObject go, ShaderType type) { if (!ObjectsForShaderReplace.ContainsKey(go)) { ObjectsForShaderReplace.Add(go, type); } } public static void RegisterGameObjectForMatSwap(GameObject go, bool isJotunnMock = false) { if (!ObjectToSwap.ContainsKey(go)) { ObjectToSwap.Add(go, isJotunnMock); } } private static void GetAllMaterials() { Material[] array = Resources.FindObjectsOfTypeAll(); foreach (Material val in array) { OriginalMaterials[((Object)val).name] = val; } } [HarmonyPriority(700)] private static void ReplaceAllMaterialsWithOriginal() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)SystemInfo.graphicsDeviceType == 4 || hasRun) { return; } if (OriginalMaterials.Count == 0) { GetAllMaterials(); } foreach (KeyValuePair item in ObjectToSwap) { GameObject key = item.Key; bool value = item.Value; ProcessGameObjectMaterials(key, value); } AssetBundle[] array = Resources.FindObjectsOfTypeAll(); AssetBundle[] array2 = array; foreach (AssetBundle val in array2) { IEnumerable enumerable3; try { IEnumerable enumerable2; if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val)) { IEnumerable enumerable = val.LoadAllAssets(); enumerable2 = enumerable; } else { enumerable2 = from shader in ((IEnumerable)val.GetAllAssetNames()).Select((Func)val.LoadAsset) where (Object)(object)shader != (Object)null select shader; } enumerable3 = enumerable2; } catch (Exception) { continue; } if (enumerable3 == null) { continue; } foreach (Shader item2 in enumerable3) { CachedShaders.Add(item2); } } foreach (KeyValuePair item3 in ObjectsForShaderReplace) { GameObject key2 = item3.Key; ShaderType value2 = item3.Value; ProcessGameObjectShaders(key2, value2); } ProcessMaterials(); hasRun = true; } public static void ProcessGameObjectMaterials(GameObject go, bool isJotunnMock) { Renderer[] componentsInChildren = go.GetComponentsInChildren(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials.Select([NullableContext(0)] (Material material) => ReplaceMaterial(material, isJotunnMock)).ToArray(); val.sharedMaterials = sharedMaterials; } } private static Material ReplaceMaterial(Material originalMaterial, bool isJotunnMock) { string text = (isJotunnMock ? "JVLmock_" : "_REPLACE_"); if (!((Object)originalMaterial).name.StartsWith(text, StringComparison.Ordinal)) { return originalMaterial; } string text2 = ((Object)originalMaterial).name.Replace(" (Instance)", "").Replace(text, ""); if (OriginalMaterials.TryGetValue(text2, out var value)) { return value; } Debug.LogWarning((object)("No suitable material found to replace: " + text2)); return originalMaterial; } private static void ProcessMaterials() { //IL_016a: Unknown result type (might be due to invalid IL or missing references) foreach (MaterialData material in m_materials) { material.m_material.shader = GetShaderForType(material.m_material.shader, material.m_type, ((Object)material.m_material.shader).name); foreach (KeyValuePair floatProperty in material.m_floatProperties) { if (material.m_material.HasProperty(floatProperty.Key)) { material.m_material.SetFloat(floatProperty.Key, floatProperty.Value); } } } foreach (KeyValuePair item in MaterialsToReplace) { if (OriginalMaterials.TryGetValue(item.Value, out var value)) { item.Key.shader = value.shader; if (((Object)item.Key.shader).name == "Custom/Water" && item.Key.HasProperty("_ColorTop")) { item.Key.SetColor("_ColorTop", value.GetColor("_ColorTop")); } } } } private static void ProcessGameObjectShaders(GameObject go, ShaderType shaderType) { Renderer[] componentsInChildren = go.GetComponentsInChildren(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if ((Object)(object)val2 != (Object)null) { val2.shader = GetShaderForType(val2.shader, shaderType, ((Object)val2.shader).name); if (val2.HasProperty("_ValueNoise")) { val2.SetFloat("_ValueNoise", 0f); } } } } } private static Shader GetShaderForType(Shader orig, ShaderType shaderType, string originalShaderName) { return (Shader)(shaderType switch { ShaderType.PieceShader => FindShaderWithName(orig, "Custom/Piece"), ShaderType.VegetationShader => FindShaderWithName(orig, "Custom/Vegetation"), ShaderType.RockShader => FindShaderWithName(orig, "Custom/StaticRock"), ShaderType.RugShader => FindShaderWithName(orig, "Custom/Rug"), ShaderType.GrassShader => FindShaderWithName(orig, "Custom/Grass"), ShaderType.CustomCreature => FindShaderWithName(orig, "Custom/Creature"), ShaderType.UseUnityShader => FindShaderWithName(orig, ((Object)(object)FindShaderWithName(orig, originalShaderName) != (Object)null) ? originalShaderName : "ToonDeferredShading2017"), _ => FindShaderWithName(orig, "Standard"), }); } public static Shader FindShaderWithName(Shader origShader, string name) { foreach (Shader cachedShader in CachedShaders) { if (((Object)cachedShader).name == name) { return cachedShader; } } return origShader; } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class MusicManager { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class Music { public readonly string m_name = null; public readonly AudioClip m_clip = null; public string m_clonedEnvironment = "Clear"; public float m_volume = 1f; public float m_fadeInTime = 3f; public bool m_alwaysFadeOut = false; public bool m_loop = true; public bool m_resume = false; public bool m_ambientMusic = true; public Music(string name, string searchName, AssetBundle bundle) { AudioClip val = bundle.LoadAsset(name); if (val != null) { m_name = searchName; m_clip = val; m_musics.Add(this); } else { Debug.LogWarning((object)(name + " is null")); } } public void SetEnvironmentCopy(string env) { m_clonedEnvironment = env; } } private static readonly List m_musics; static MusicManager() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown m_musics = new List(); Harmony harmony = ElvenNPCPlugin.instance._harmony; harmony.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZoneSystem), "SetupLocations", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(MusicManager), "RegisterEnvironments", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(MusicMan), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(MusicManager), "RegisterTunes", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } internal static void RegisterEnvironments() { if (!Object.op_Implicit((Object)(object)EnvMan.instance)) { return; } foreach (Music music in m_musics) { EnvSetup env = EnvMan.instance.GetEnv(music.m_clonedEnvironment); if (env != null) { EnvSetup val = env.Clone(); val.m_name = music.m_name; val.m_musicDay = music.m_name; val.m_musicEvening = music.m_name; val.m_musicMorning = music.m_name; val.m_musicNight = music.m_name; EnvMan.instance.m_environments.Add(val); } } } internal static void RegisterTunes(MusicMan __instance) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown foreach (Music music in m_musics) { NamedMusic val = new NamedMusic(); val.m_name = music.m_name; val.m_clips = (AudioClip[])(object)new AudioClip[1] { music.m_clip }; val.m_volume = music.m_volume; val.m_fadeInTime = music.m_fadeInTime; val.m_alwaysFadeout = music.m_alwaysFadeOut; val.m_loop = music.m_loop; val.m_resume = music.m_resume; val.m_ambientMusic = music.m_ambientMusic; NamedMusic val2 = val; __instance.m_music.Add(val2); __instance.m_musicHashes[BalrondHashCompat.StableHash(val2.m_name)] = val2; } } } } namespace Settlers.Managers { [PublicAPI] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class Localizer { private static readonly Dictionary>> PlaceholderProcessors; private static readonly Dictionary> loadedTexts; private static readonly ConditionalWeakTable localizationLanguage; private static readonly List> localizationObjects; private static BaseUnityPlugin _plugin; private static readonly List fileExtensions; private static BaseUnityPlugin plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out var value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out var value2)) { text = value2.Aggregate(text, [NullableContext(0)] (string current, KeyValuePair> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder(string key, string placeholder, ConfigEntry config, [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1, 1 })] Func convertConfigValue = null) { if (convertConfigValue == null) { convertConfigValue = [NullableContext(0)] [return: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(1)] (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary>(); } config.SettingChanged += [NullableContext(0)] (object _, EventArgs _) => { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List> list = new List>(); foreach (WeakReference localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference item in list) { localizationObjects.Remove(item); } } public static void Load() { LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); } private static void LoadLocalization(Localization __instance, string language) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Expected O, but got Unknown if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference(__instance)); } localizationLanguage.Add(__instance, language); Dictionary dictionary = new Dictionary(); foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f) { string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1]; if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary dictionary2 = ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(Encoding.UTF8.GetString(array)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text2 = null; if (language != "English") { if (dictionary.ContainsKey(language)) { text2 = File.ReadAllText(dictionary[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text2 = Encoding.UTF8.GetString(array2); } } } if (text2 == null && dictionary.ContainsKey("English")) { text2 = File.ReadAllText(dictionary["English"]); } if (text2 != null) { foreach (KeyValuePair item2 in ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(text2) ?? new Dictionary()) { dictionary2[item2.Key] = item2.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair item3 in dictionary2) { UpdatePlaceholderText(__instance, item3.Key); } } static Localizer() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown PlaceholderProcessors = new Dictionary>>(); loadedTexts = new Dictionary>(); localizationLanguage = new ConditionalWeakTable(); localizationObjects = new List>(); fileExtensions = new List { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } [return: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private static byte[] LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } [NullableContext(2)] public static byte[] ReadEmbeddedFileBytes([<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(1)] string resourceFileName, Assembly containingAssembly = null) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } namespace Norsemen { [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [PublicAPI] public static class AssetBundleManager { private static readonly Dictionary CachedBundles = new Dictionary(); [return: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public static T LoadAsset<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] T>(string assetBundle, string prefab) where T : Object { AssetBundle assetBundle2 = GetAssetBundle(assetBundle); return (assetBundle2 == null) ? default(T) : assetBundle2.LoadAsset(prefab); } public static AssetBundle GetAssetBundle(string fileName) { if (CachedBundles.TryGetValue(fileName, out var value)) { return value; } AssetBundle val = AssetBundle.GetAllLoadedAssetBundles().FirstOrDefault((Func)([NullableContext(0)] (AssetBundle b) => ((Object)b).name == fileName)); if (val != null) { CachedBundles[fileName] = val; return val; } Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single([NullableContext(0)] (string str) => str.EndsWith(fileName)); using Stream stream = executingAssembly.GetManifestResourceStream(name); AssetBundle val2 = AssetBundle.LoadFromStream(stream); CachedBundles[fileName] = val2; return val2; } } public class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order = null; [UsedImplicitly] public bool? Browsable = null; [UsedImplicitly] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public string Category = null; [UsedImplicitly] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] public Action CustomDrawer = null; } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class EnvList { public static readonly ConfigurationManagerAttributes attributes = new ConfigurationManagerAttributes { CustomDrawer = DrawTable }; public readonly List Envs; public EnvList(List envs) { Envs = envs; if (Envs.Count == 0) { Envs.Add(""); } } public EnvList(string envs) { Envs = envs.Split(new char[1] { ',' }).ToList(); } public EnvList() { Envs = new List { "" }; } public void Add(string env) { Envs.Add(env); } public List GetValidatedList() { return Object.op_Implicit((Object)(object)EnvMan.instance) ? Envs.Where([NullableContext(0)] (string env) => EnvMan.instance.GetEnv(env) != null).ToList() : Envs.Where([NullableContext(0)] (string env) => !Utility.IsNullOrWhiteSpace(env)).ToList(); } public override string ToString() { return string.Join(",", Envs); } public static void DrawTable(ConfigEntryBase cfg) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select([NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault(); List list = new List(); bool flag = false; GUILayout.BeginVertical(Array.Empty()); foreach (string env in new EnvList((string)cfg.BoxedValue).Envs) { GUILayout.BeginHorizontal(Array.Empty()); string text = GUILayout.TextField(env, new GUIStyle(GUI.skin.textField), Array.Empty()); string item = (valueOrDefault ? env : text); bool flag2 = GUILayout.Button("x", new GUIStyle(GUI.skin.button) { fixedWidth = 21f }, Array.Empty()); bool flag3 = GUILayout.Button("+", new GUIStyle(GUI.skin.button) { fixedWidth = 21f }, Array.Empty()); GUILayout.EndHorizontal(); if (flag2 && !valueOrDefault) { flag = true; } else { list.Add(item); } if (flag3 && !valueOrDefault) { flag = true; list.Add(""); } } GUILayout.EndVertical(); if (flag) { cfg.BoxedValue = new EnvList(list).ToString(); } } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class Level { public static readonly ConfigurationManagerAttributes attributes = new ConfigurationManagerAttributes { CustomDrawer = DrawTable }; public readonly int Min; public readonly int Max; public readonly float Chance; public Level(int min, int max, float chance) { Min = min; Max = max; Chance = chance; } public Level(string level) { string[] array = level.Split(new char[1] { ':' }); Min = ((!int.TryParse(array[0], out var result)) ? 1 : result); Max = ((!int.TryParse(array[1], out var result2)) ? 1 : result2); Chance = (float.TryParse(array[2], out var result3) ? result3 : 0.5f); } public static void DrawTable(ConfigEntryBase cfg) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select([NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault(); Level level = new Level((string)cfg.BoxedValue); GUILayout.BeginVertical(Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Min: ", Array.Empty()); int num; if (valueOrDefault) { num = level.Min; } else { int min = level.Min; num = (int.TryParse(GUILayout.TextField(min.ToString(), new GUIStyle(GUI.skin.textField), Array.Empty()), out var result) ? result : level.Min); } int num2 = num; GUILayout.Label("Max: ", Array.Empty()); int num3; if (valueOrDefault) { num3 = level.Max; } else { int min = level.Max; num3 = (int.TryParse(GUILayout.TextField(min.ToString(), new GUIStyle(GUI.skin.textField), Array.Empty()), out var result2) ? result2 : level.Max); } int num4 = num3; GUILayout.Label("LevelUp Chance: ", Array.Empty()); float num5; if (valueOrDefault) { num5 = level.Chance; } else { float chance = level.Chance; num5 = (float.TryParse(GUILayout.TextField(chance.ToString(CultureInfo.InvariantCulture), Array.Empty()), out var result3) ? result3 : level.Chance); } float num6 = num5; GUILayout.EndHorizontal(); GUILayout.EndVertical(); if (num2 != level.Min || num4 != level.Max || Math.Abs(num6 - level.Chance) > 0.01f) { cfg.BoxedValue = new Level(num2, num4, num6).ToString(); } } public override string ToString() { return $"{Min}:{Max}:{Chance}"; } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class MinMax { public static readonly ConfigurationManagerAttributes attributes = new ConfigurationManagerAttributes { CustomDrawer = DrawTable }; public readonly float Min; public readonly float Max; public MinMax(float min, float max) { Min = min; Max = max; } public MinMax(string altitude) { string[] array = altitude.Split(new char[1] { '-' }); Min = (float.TryParse(array[0], out var result) ? result : (-1000f)); Max = (float.TryParse(array[1], out var result2) ? result2 : 1000f); } public static void DrawTable(ConfigEntryBase cfg) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select([NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault(); MinMax minMax = new MinMax((string)cfg.BoxedValue); GUILayout.BeginVertical(Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Min: ", Array.Empty()); float num; if (valueOrDefault) { num = minMax.Min; } else { float min = minMax.Min; num = (float.TryParse(GUILayout.TextField(min.ToString(CultureInfo.InvariantCulture), new GUIStyle(GUI.skin.textField), Array.Empty()), out var result) ? result : minMax.Min); } float num2 = num; GUILayout.Label("Max: ", Array.Empty()); float num3; if (valueOrDefault) { num3 = minMax.Max; } else { float min = minMax.Max; num3 = (float.TryParse(GUILayout.TextField(min.ToString(CultureInfo.InvariantCulture), new GUIStyle(GUI.skin.textField), Array.Empty()), out var result2) ? result2 : minMax.Max); } float num4 = num3; GUILayout.EndHorizontal(); GUILayout.EndVertical(); if (Math.Abs(num2 - minMax.Min) > 0.1f || Math.Abs(num4 - minMax.Max) > 0.1f) { cfg.BoxedValue = new MinMax(num2, num4).ToString(); } } public override string ToString() { return $"{Min}-{Max}"; } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class StringList { public readonly List list; public static readonly ConfigurationManagerAttributes attributes = new ConfigurationManagerAttributes { CustomDrawer = Draw }; public StringList(List prefabs) { list = prefabs; if (list.Count == 0) { list.Add(""); } } public StringList(params string[] prefabs) { list = prefabs.ToList(); if (list.Count == 0) { list.Add(""); } } public StringList(string config) { list = config.Split(new char[1] { ',' }).ToList(); if (list.Count == 0) { list.Add(""); } } public override string ToString() { return string.Join(",", list); } public static void Draw(ConfigEntryBase cfg) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select([NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault(); bool flag = false; List list = new List(); GUILayout.BeginVertical(Array.Empty()); foreach (string item2 in new StringList((string)cfg.BoxedValue).list) { GUILayout.BeginHorizontal(Array.Empty()); string item = item2; string text = GUILayout.TextField(item2, Array.Empty()); if (text != item2 && !valueOrDefault) { flag = true; item = text; } if (GUILayout.Button("x", new GUIStyle(GUI.skin.button) { fixedWidth = 21f }, Array.Empty()) && !valueOrDefault) { flag = true; } else { list.Add(item); } if (GUILayout.Button("+", new GUIStyle(GUI.skin.button) { fixedWidth = 21f }, Array.Empty()) && !valueOrDefault) { list.Add(""); flag = true; } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (flag) { cfg.BoxedValue = new StringList(list).ToString(); } } } [Serializable] [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class ConditionalChanceItem { public string PrefabName = ""; public string RequiredDefeatKey = ""; public float Chance = 0.5f; public int Min = 1; public int Max = 1; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] [YamlIgnore] private ConditionalRandomItem _item; [YamlIgnore] public ConditionalRandomItem item { get { if (_item != null) { return _item; } _item = new ConditionalRandomItem { m_prefab = Helpers.GetPrefab(PrefabName), m_requiredDefeatKey = RequiredDefeatKey, m_chance = Chance, m_min = Min, m_max = Max }; return _item; } } public ConditionalChanceItem(string prefab, int min = 1, int max = 1, float chance = 0.5f, string requiredDefeatKey = "") { PrefabName = prefab; RequiredDefeatKey = requiredDefeatKey; Chance = chance; Min = min; Max = max; } public ConditionalChanceItem() { } } [Serializable] public class ConditionalRandomItem { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public GameObject m_prefab; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(1)] public string m_requiredDefeatKey = ""; public float m_chance = 0.5f; public int m_min = 1; public int m_max = 1; public bool HasKey() { return string.IsNullOrEmpty(m_requiredDefeatKey) || ZoneSystem.instance.GetGlobalKey(m_requiredDefeatKey); } } } namespace ElvenNPC { [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class ElfAI : MonsterAI { public float m_blockTimer; private float m_blockCheckInterval = 2f; private float m_dodgeTimer = 0f; private float m_dodgeCooldown = 5f; private float m_dodgeCheckInterval = 0.2f; private float m_dodgeCheckTimer = 0f; private float m_dodgeDistance = 15f; private float m_dodgeThreatDistance = 5f; public Biome m_currentBiome; public float m_biomeTimer; public float m_lastMoveAwayFromMountainTimer; public bool m_haveNonMountainPosition; public Vector3 m_moveAwayFromMountainPosition; public float m_lastMoveAwayFromTar; public bool m_haveNonTarPosition; public Vector3 m_moveAwayFromTarPosition; public float m_crouchTimer; private float m_crouchCheckInterval = 2f; public Elf m_elf = null; [NullableContext(2)] public bool UpdateAttack(float dt, ItemData itemData, bool doAttack, bool canHearTarget, bool canSeeTarget) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if (itemData == null) { return false; } AiTarget aiTargetType = itemData.m_shared.m_aiTargetType; AiTarget val = aiTargetType; if ((int)val != 0) { if (val - 1 <= 1) { return UpdateFriendAttack(dt, itemData, doAttack); } return false; } return UpdateEnemyAttack(dt, itemData, doAttack, canHearTarget, canSeeTarget); } private bool UpdateEnemyAttack(float dt, ItemData itemData, bool doAttack, bool canHearTarget, bool canSeeTarget) { if ((Object)(object)base.m_targetStatic != (Object)null) { return HandleStaticTarget(dt, itemData, doAttack); } if ((Object)(object)base.m_targetCreature != (Object)null) { return HandleCreatureTarget(dt, itemData, doAttack, canHearTarget, canSeeTarget); } return false; } public static float GetWeaponRange(ItemData itemData) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 SkillType skillType = itemData.m_shared.m_skillType; SkillType val = skillType; if (val - 8 <= 2 || (int)val == 14) { return Random.Range(15f, 30f); } return itemData.m_shared.m_attack.m_attackRange; } private bool HandleStaticTarget(float dt, ItemData itemData, bool doAttack) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Vector3 val = base.m_targetStatic.FindClosestPoint(((Component)this).transform.position); float num = Vector3.Distance(val, ((Component)this).transform.position); bool flag = num < GetWeaponRange(itemData); bool flag2 = ((BaseAI)this).CanSeeTarget(base.m_targetStatic); if (flag && flag2) { Vector3 center = base.m_targetStatic.GetCenter(); ((BaseAI)this).LookAt(center); if ((double)itemData.m_shared.m_aiAttackMaxAngle == 0.0) { ZLog.LogError((object)("AI Attack Max Angle for " + itemData.m_shared.m_name + " is 0!")); } bool flag3 = ((BaseAI)this).IsLookingAt(center, itemData.m_shared.m_aiAttackMaxAngle, itemData.m_shared.m_aiInvertAngleCheck); if (flag3 && doAttack) { DoWeaponAttack(null, isFriend: false); return true; } ((BaseAI)this).StopMoving(); return true; } ((BaseAI)this).MoveTo(dt, val, 0f, ((BaseAI)this).IsAlerted()); ((BaseAI)this).ChargeStop(); return true; } private bool HandleCreatureTarget(float dt, ItemData itemData, bool doAttack, bool canHearTarget, bool canSeeTarget) { if (canHearTarget || canSeeTarget || (((BaseAI)this).HuntPlayer() && base.m_targetCreature.IsPlayer())) { return HandleDetectedCreature(dt, itemData, doAttack, canSeeTarget); } return HandleLostCreature(dt); } private bool HandleDetectedCreature(float dt, ItemData itemData, bool doAttack, bool canSeeTarget) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) base.m_beenAtLastPos = false; base.m_lastKnownTargetPos = ((Component)base.m_targetCreature).transform.position; float num = Vector3.Distance(base.m_lastKnownTargetPos, ((Component)this).transform.position) - base.m_targetCreature.GetRadius(); float num2 = base.m_alertRange * base.m_targetCreature.GetStealthFactor(); if (canSeeTarget && num < num2) { ((BaseAI)this).SetAlerted(true); } float weaponRange = GetWeaponRange(itemData); bool flag = num < weaponRange; if (!flag || !canSeeTarget || !((BaseAI)this).IsAlerted()) { Vector3 val = CalculateInterceptPosition(num); ((BaseAI)this).MoveTo(dt, val, 0f, ((BaseAI)this).IsAlerted()); if ((double)base.m_timeSinceAttacking > 15.0) { base.m_unableToAttackTargetTimer = 15f; } return true; } ((BaseAI)this).StopMoving(); bool flag2 = ((BaseAI)this).IsAlerted(); if (flag && canSeeTarget && flag2) { if (((MonsterAI)this).PheromoneFleeCheck(base.m_targetCreature)) { ((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position); base.m_updateTargetTimer = Random.Range(base.m_fleePheromoneMin, base.m_fleePheromoneMax); base.m_targetCreature = null; } else { ((BaseAI)this).LookAt(base.m_targetCreature.GetTopPoint()); bool flag3 = ((BaseAI)this).IsLookingAt(base.m_lastKnownTargetPos, itemData.m_shared.m_aiAttackMaxAngle, itemData.m_shared.m_aiInvertAngleCheck); if (doAttack && flag3) { DoWeaponAttack(base.m_targetCreature, isFriend: false); return true; } } } else if (flag2) { UpdateDodge(dt, base.m_targetCreature); } return false; } private Vector3 CalculateInterceptPosition(float distanceToTarget) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) Vector3 velocity = base.m_targetCreature.GetVelocity(); Vector3 val = velocity * base.m_interceptTime; Vector3 val2 = base.m_lastKnownTargetPos; if ((double)distanceToTarget > (double)((Vector3)(ref val)).magnitude / 4.0) { val2 += val; } return val2; } private bool HandleLostCreature(float dt) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) ((BaseAI)this).ChargeStop(); if (base.m_beenAtLastPos) { ((BaseAI)this).RandomMovement(dt, base.m_lastKnownTargetPos, false); if ((double)base.m_timeSinceAttacking > 15.0) { base.m_unableToAttackTargetTimer = 15f; } return true; } if (((BaseAI)this).MoveTo(dt, base.m_lastKnownTargetPos, 0f, ((BaseAI)this).IsAlerted())) { base.m_beenAtLastPos = true; return true; } return false; } private bool UpdateFriendAttack(float dt, ItemData itemData, bool doAttack) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) Character val = (((int)itemData.m_shared.m_aiTargetType == 1) ? ((BaseAI)this).HaveHurtFriendInRange(((BaseAI)this).m_viewRange) : ((BaseAI)this).HaveFriendInRange(((BaseAI)this).m_viewRange)); if ((Object)(object)val == (Object)null) { ((BaseAI)this).RandomMovement(dt, ((Component)this).transform.position, true); return false; } float num = Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position); float weaponRange = GetWeaponRange(itemData); if (num < weaponRange) { if (doAttack) { ((BaseAI)this).StopMoving(); ((BaseAI)this).LookAt(((Component)val).transform.position); DoWeaponAttack(val, isFriend: true); return true; } ((BaseAI)this).RandomMovement(dt, ((Component)val).transform.position, false); return true; } ((BaseAI)this).MoveTo(dt, ((Component)val).transform.position, 0f, ((BaseAI)this).IsAlerted()); return true; } [NullableContext(2)] public bool DoWeaponAttack(Character target, bool isFriend) { ItemData currentWeapon = ((Humanoid)m_elf).GetCurrentWeapon(); if (currentWeapon == null || !((BaseAI)this).CanUseAttack(currentWeapon)) { return false; } bool flag = !string.IsNullOrEmpty(currentWeapon.m_shared.m_secondaryAttack.m_attackAnimation) && Random.value > 0.5f; if (!((Character)m_elf).StartAttack(target, flag)) { return false; } base.m_timeSinceAttacking = 0f; return true; } public bool UpdateAvoidFire(float dt) { if (m_elf.IsHoldingTorch()) { return false; } if ((((BaseAI)this).m_afraidOfFire || ((BaseAI)this).m_avoidFire) && ((BaseAI)this).AvoidFire(dt, base.m_targetCreature, ((BaseAI)this).m_afraidOfFire)) { return true; } return false; } public bool UpdateBaseAI(float dt) { if (!((BaseAI)this).m_nview.IsValid()) { return false; } if (!((BaseAI)this).m_nview.IsOwner()) { ((BaseAI)this).m_alerted = ((BaseAI)this).m_nview.GetZDO().GetBool(ZDOVars.s_alert, false); return false; } if ((double)((BaseAI)this).m_jumpInterval > 0.0) { ((BaseAI)this).m_jumpTimer = ((BaseAI)this).m_jumpTimer + dt; } if ((double)((BaseAI)this).m_randomMoveUpdateTimer > 0.0) { ((BaseAI)this).m_randomMoveUpdateTimer = ((BaseAI)this).m_randomMoveUpdateTimer - dt; } ((BaseAI)this).UpdateRegeneration(dt); ((BaseAI)this).m_timeSinceHurt = ((BaseAI)this).m_timeSinceHurt - dt; return true; } [NullableContext(2)] public void UpdateBlock(float dt, Character target, bool canSeeTarget) { m_blockTimer += dt; if (m_blockTimer > m_blockCheckInterval) { m_blockTimer = 0f; UpdateBlockDecision(target, canSeeTarget); } } [NullableContext(2)] public void UpdateBlockDecision(Character target, bool canSeeTarget) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (!((BaseAI)this).IsAlerted()) { m_elf.SetBlocking(block: false); return; } if ((Object)(object)target == (Object)null) { m_elf.SetBlocking(block: false); return; } if (((Character)m_elf).GetHealthPercentage() < 0.25f) { m_elf.SetBlocking(block: true); return; } if (target.IsFlying()) { m_elf.SetBlocking(block: false); return; } float num = Vector3.Distance(((Component)target).transform.position, ((Component)this).transform.position); bool flag = target.m_baseAI.IsAlerted() || target.IsPlayer(); if (canSeeTarget) { if (num < 10f) { if (flag) { m_elf.SetBlocking(Random.value > 0.8f); } else { m_elf.SetBlocking(Random.value > 0.5f); } } else if (target.m_baseAI.IsCharging() || target.IsDrawingBow()) { m_elf.SetBlocking(Random.value > 0.6f); } else { m_elf.SetBlocking(Random.value > 0.25f); } } else { m_elf.SetBlocking(block: false); } } [NullableContext(2)] public void UpdateChargeAttack(float dt, bool hasItem, bool hasTarget, bool doAttack, ItemData itemData) { bool flag = hasItem && hasTarget && doAttack; bool flag2 = !((BaseAI)this).m_character.InAttack(); bool flag3 = itemData?.m_shared.m_attack != null && !itemData.m_shared.m_attack.IsDone() && !string.IsNullOrEmpty(itemData.m_shared.m_attack.m_drawAnimationState); if ((((BaseAI)this).IsCharging() || flag) && flag2 && flag3) { ((BaseAI)this).ChargeStart(itemData?.m_shared.m_attack.m_drawAnimationState); } } public bool UpdateCircleTarget(float dt) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) if ((double)base.m_circleTargetInterval > 0.0 && Object.op_Implicit((Object)(object)base.m_targetCreature)) { base.m_pauseTimer += dt; if ((double)base.m_pauseTimer > (double)base.m_circleTargetInterval) { if ((double)base.m_pauseTimer > (double)base.m_circleTargetInterval + (double)base.m_circleTargetDuration) { base.m_pauseTimer = Random.Range(0f, base.m_circleTargetInterval / 10f); } ((BaseAI)this).RandomMovementArroundPoint(dt, ((Component)base.m_targetCreature).transform.position, base.m_circleTargetDistance, ((BaseAI)this).IsAlerted()); return true; } } return false; } public bool UpdateCirculate(float dt, bool hasItem, bool doAttack) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) bool flag = (((BaseAI)this).m_character.IsFlying() ? base.m_circulateWhileChargingFlying : base.m_circulateWhileCharging); if (flag && hasItem && !doAttack && !((BaseAI)this).m_character.InAttack()) { if ((Object)(object)base.m_targetCreature != (Object)null) { ((BaseAI)this).RandomMovementArroundPoint(dt, ((Component)base.m_targetCreature).transform.position, ((BaseAI)this).m_randomMoveRange, ((BaseAI)this).IsAlerted()); return true; } if ((Object)(object)base.m_targetStatic != (Object)null) { ((BaseAI)this).RandomMovementArroundPoint(dt, ((Component)base.m_targetStatic).transform.position, ((BaseAI)this).m_randomMoveRange, ((BaseAI)this).IsAlerted()); return true; } } return false; } public void UpdateTargets(Elf elf, float dt, out bool canHearTarget, out bool canSeeTarget) { base.m_unableToAttackTargetTimer -= dt; base.m_updateTargetTimer -= dt; if ((double)base.m_updateTargetTimer <= 0.0 && !((BaseAI)this).m_character.InAttack()) { UpdateTargetSearch(); } if ((Object)(object)base.m_targetCreature != (Object)null) { CheckTamedTargetDistance(); } ValidateCurrentTarget(); UpdateTargetSensing(dt, out canHearTarget, out canSeeTarget); CheckGiveUpChase(dt); } private void UpdateTargetSearch() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) base.m_updateTargetTimer = (Player.IsPlayerInRange(((Component)this).transform.position, 50f) ? 2f : 6f); Character val = ((BaseAI)this).FindEnemy(); if (Object.op_Implicit((Object)(object)val)) { base.m_targetCreature = val; base.m_targetStatic = null; } bool hasPlayerTarget = (Object)(object)base.m_targetCreature != (Object)null && base.m_targetCreature.IsPlayer(); bool flag = (Object)(object)base.m_targetCreature != (Object)null && (double)base.m_unableToAttackTargetTimer > 0.0 && !((BaseAI)this).HavePath(((Component)base.m_targetCreature).transform.position); bool flag2 = base.m_attackPlayerObjects && (!((BaseAI)this).m_aggravatable || ((BaseAI)this).IsAggravated()) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)25); bool flag3 = (Object)(object)base.m_targetCreature == (Object)null || flag; if (flag2 && flag3) { FindStaticTargets(hasPlayerTarget); } } private void FindStaticTargets(bool hasPlayerTarget) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) StaticTarget val = ((BaseAI)this).FindClosestStaticPriorityTarget(); if ((Object)(object)val != (Object)null) { base.m_targetStatic = val; base.m_targetCreature = null; } bool flag = false; if ((Object)(object)base.m_targetStatic != (Object)null) { Vector3 val2 = base.m_targetStatic.FindClosestPoint(((Component)((BaseAI)this).m_character).transform.position); flag = ((BaseAI)this).HavePath(val2); } if (((Object)(object)base.m_targetStatic == (Object)null || !flag) && ((BaseAI)this).IsAlerted() && hasPlayerTarget) { StaticTarget val3 = ((BaseAI)this).FindRandomStaticTarget(10f); if ((Object)(object)val3 != (Object)null) { base.m_targetStatic = val3; base.m_targetCreature = null; } } } private void CheckTamedTargetDistance() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)base.m_targetCreature == (Object)null) { return; } float alertRange = base.m_alertRange; Vector3 val = default(Vector3); if (((BaseAI)this).GetPatrolPoint(ref val)) { if (Vector3.Distance(((Component)base.m_targetCreature).transform.position, val) > alertRange) { base.m_targetCreature = null; } } else if ((Object)(object)base.m_follow != (Object)null && Vector3.Distance(((Component)base.m_targetCreature).transform.position, base.m_follow.transform.position) > alertRange) { base.m_targetCreature = null; } } private void ValidateCurrentTarget() { if (!((Object)(object)base.m_targetCreature == (Object)null)) { if (base.m_targetCreature.IsDead()) { base.m_targetCreature = null; } else if (!((BaseAI)this).IsEnemy(base.m_targetCreature)) { base.m_targetCreature = null; } else if (((BaseAI)this).m_skipLavaTargets && base.m_targetCreature.AboveOrInLava()) { base.m_targetCreature = null; } } } private void UpdateTargetSensing(float dt, out bool canHearTarget, out bool canSeeTarget) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) canHearTarget = false; canSeeTarget = false; if ((Object)(object)base.m_targetCreature != (Object)null) { canHearTarget = ((BaseAI)this).CanHearTarget(base.m_targetCreature); canSeeTarget = ((BaseAI)this).CanSeeTarget(base.m_targetCreature); if (canSeeTarget | canHearTarget) { base.m_timeSinceSensedTargetCreature = 0f; } if (base.m_targetCreature.IsPlayer()) { base.m_targetCreature.OnTargeted(canSeeTarget | canHearTarget, ((BaseAI)this).IsAlerted()); } ((BaseAI)this).SetTargetInfo(base.m_targetCreature.GetZDOID()); } else { ((BaseAI)this).SetTargetInfo(ZDOID.None); } base.m_timeSinceSensedTargetCreature += dt; } private void CheckGiveUpChase(float dt) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) if (!((BaseAI)this).IsAlerted() && (Object)(object)base.m_targetCreature == (Object)null) { return; } base.m_timeSinceAttacking += dt; if (!((BaseAI)this).HuntPlayer() || !((Object)(object)base.m_targetCreature != (Object)null) || !base.m_targetCreature.IsPlayer()) { bool flag = (double)base.m_timeSinceSensedTargetCreature > 30.0; float num = 60f; bool flag2 = base.m_timeSinceAttacking > num; bool flag3 = (double)base.m_maxChaseDistance > 0.0 && (double)base.m_timeSinceSensedTargetCreature > 1.0 && Vector3.Distance(((BaseAI)this).m_spawnPoint, ((Component)this).transform.position) > base.m_maxChaseDistance; if (flag || (flag2 && flag3)) { ((BaseAI)this).SetAlerted(false); base.m_targetCreature = null; base.m_targetStatic = null; base.m_timeSinceAttacking = 0f; base.m_updateTargetTimer = 5f; } } } public bool UpdateDespawn(float dt, bool canSeeTarget) { if (((MonsterAI)this).DespawnInDay() && EnvMan.IsDay() && ((Object)(object)base.m_targetCreature == (Object)null || !canSeeTarget)) { ((BaseAI)this).MoveAwayAndDespawn(dt, true); return true; } if (((MonsterAI)this).IsEventCreature() && !RandEventSystem.HaveActiveEvent()) { ((BaseAI)this).SetHuntPlayer(false); if ((Object)(object)base.m_targetCreature == (Object)null && !((BaseAI)this).IsAlerted()) { ((BaseAI)this).MoveAwayAndDespawn(dt, false); return true; } } return false; } [NullableContext(2)] public bool UpdateDodge(float dt, Character target) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) if (m_dodgeTimer > 0f) { m_dodgeTimer -= dt; } m_dodgeCheckTimer -= dt; if (m_dodgeCheckTimer > 0f) { return false; } m_dodgeCheckTimer = m_dodgeCheckInterval; if ((Object)(object)target == (Object)null) { return false; } if (!((BaseAI)this).IsAlerted() || !m_elf.CanDodge()) { return false; } if (m_dodgeTimer > 0f) { return false; } float num = Vector3.Distance(((Component)target).transform.position, ((Component)this).transform.position); if (num > m_dodgeDistance) { return false; } if (ShouldDodgeTarget(target, num)) { Vector3 val = ((Component)target).transform.position - ((Component)this).transform.position; Vector3 dir = CalculateDodgeDirection(((Vector3)(ref val)).normalized, num); m_elf.Dodge(dir); m_dodgeTimer = m_dodgeCooldown; return true; } return false; } private bool ShouldDodgeTarget(Character target, float distance) { if (!target.InAttack() && !target.IsDrawingBow()) { return false; } float num; if (distance < m_dodgeThreatDistance) { num = Mathf.Lerp(0.8f, 0.6f, distance / m_dodgeThreatDistance); } else { float num2 = (distance - m_dodgeThreatDistance) / (m_dodgeDistance - m_dodgeThreatDistance); num = Mathf.Lerp(0.6f, 0.1f, num2); } return Random.value < num; } private Vector3 CalculateDodgeDirection(Vector3 toTargetNormalized, float distance) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (distance < m_dodgeThreatDistance) { return -toTargetNormalized; } Vector3 val = Vector3.Cross(Vector3.up, toTargetNormalized); float num = ((Random.value > 0.5f) ? 1f : (-1f)); Vector3 val2 = -toTargetNormalized + val * num; return ((Vector3)(ref val2)).normalized; } public bool UpdateFlee(float dt, bool isAlerted) { if (UpdateFleeNotAlerted(dt, isAlerted)) { return true; } if (UpdateFleeLowHealth(dt)) { return true; } if (UpdateFleeLava(dt)) { return true; } UpdateBiome(dt); if (UpdateFleeMountain(dt, 50f)) { return true; } if (UpdateFleeTar(dt, 50f)) { return true; } return false; } public bool UpdateFleeNotAlerted(float dt, bool isAlerted) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (base.m_fleeIfNotAlerted && !((BaseAI)this).HuntPlayer() && Object.op_Implicit((Object)(object)base.m_targetCreature) && !isAlerted && Vector3.Distance(((Component)base.m_targetCreature).transform.position, ((Component)this).transform.position) - base.m_targetCreature.GetRadius() > base.m_alertRange) { ((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position); return true; } return false; } public bool UpdateFleeLowHealth(float dt) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) if ((double)base.m_fleeIfLowHealth > 0.0 && ((BaseAI)this).m_timeSinceHurt < base.m_fleeTimeSinceHurt && (Object)(object)base.m_targetCreature != (Object)null && (double)((BaseAI)this).m_character.GetHealthPercentage() < (double)base.m_fleeIfLowHealth) { ((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position); return true; } return false; } public bool UpdateFleeLava(float dt) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (base.m_fleeInLava && ((BaseAI)this).m_character.InLava() && ((Object)(object)base.m_targetCreature == (Object)null || base.m_targetCreature.AboveOrInLava())) { ((BaseAI)this).Flee(dt, ((Component)((BaseAI)this).m_character).transform.position - ((Component)((BaseAI)this).m_character).transform.forward); return true; } return false; } public void UpdateBiome(float dt) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) m_biomeTimer += dt; if (!(m_biomeTimer <= 1f)) { m_biomeTimer = 0f; m_currentBiome = Heightmap.FindBiome(((Component)this).transform.position); } } public bool UpdateFleeMountain(float dt, float maxRange) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Invalid comparison between Unknown and I4 //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) if ((int)m_currentBiome != 4) { return false; } DamageModifiers damageModifiers = ((Character)m_elf).GetDamageModifiers((WeakSpot)null); DamageModifier modifier = ((DamageModifiers)(ref damageModifiers)).GetModifier((DamageType)64); if ((int)modifier == 1 || (int)modifier == 5 || (int)modifier == 3 || (int)modifier == 4) { return false; } float num = (m_haveNonMountainPosition ? 2f : 0.5f); float num2 = Time.time - m_lastMoveAwayFromMountainTimer; if (num2 > num) { m_lastMoveAwayFromMountainTimer = Time.time; m_haveNonMountainPosition = false; for (int i = 0; i < 10; i++) { Vector3 val = ((Component)this).transform.position + Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f) * Vector3.forward * Random.Range(4f, maxRange); Biome val2 = Heightmap.FindBiome(val); if ((int)val2 != 4) { val.y = ZoneSystem.instance.GetSolidHeight(val); m_moveAwayFromMountainPosition = val; m_haveNonMountainPosition = true; } } } if (!m_haveNonMountainPosition) { return false; } ((BaseAI)this).MoveTowards(m_moveAwayFromMountainPosition - ((Component)this).transform.position, true); return true; } public bool UpdateFleeTar(float dt, float maxRange) { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (!((Character)m_elf).GetSEMan().HaveStatusEffect(SEMan.s_statusEffectTared)) { return false; } float num = (m_haveNonTarPosition ? 2f : 0.5f); float num2 = Time.time - m_lastMoveAwayFromTar; if (num2 > num) { m_lastMoveAwayFromTar = Time.time; m_haveNonTarPosition = false; for (int i = 0; i < 10; i++) { Vector3 val = ((Component)this).transform.position + Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f) * Vector3.forward * Random.Range(4f, maxRange); float liquidLevel = Floating.GetLiquidLevel(val, 1f, (LiquidType)1); if (!(val.y < liquidLevel)) { m_moveAwayFromTarPosition = val; m_haveNonTarPosition = true; } } } if (!m_haveNonTarPosition) { return false; } ((BaseAI)this).MoveTowards(m_moveAwayFromTarPosition - ((Component)this).transform.position, true); return true; } public bool UpdateHurt(float dt) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) bool flag = (double)base.m_timeSinceAttacking > 30.0 && (double)((BaseAI)this).m_timeSinceHurt < 20.0; if (base.m_fleeIfHurtWhenTargetCantBeReached && (Object)(object)base.m_targetCreature != (Object)null && flag) { ((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position); base.m_lastKnownTargetPos = ((Component)this).transform.position; base.m_updateTargetTimer = 1f; return true; } return false; } public bool UpdateNoMonsterArea(float dt) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)base.m_targetCreature != (Object)null) { if (Object.op_Implicit((Object)(object)EffectArea.IsPointInsideNoMonsterArea(((Component)base.m_targetCreature).transform.position))) { ((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position); return true; } } else { EffectArea val = EffectArea.IsPointCloseToNoMonsterArea(((Component)this).transform.position); if ((Object)(object)val != (Object)null) { ((BaseAI)this).Flee(dt, ((Component)val).transform.position); return true; } } return false; } [NullableContext(2)] public void UpdateCrouch(float dt, Character target, bool canSeeTarget) { m_crouchTimer += dt; if (m_crouchTimer > m_crouchCheckInterval) { UpdateCrouchDecision(target, canSeeTarget); m_crouchTimer = 0f; } bool flag = m_elf.m_crouchToggled && m_elf.CanCrouch(); ((BaseAI)this).m_animator.SetBool(Player.s_crouching, flag); } [NullableContext(2)] private void UpdateCrouchDecision(Character target, bool canSeeTarget) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { ((Character)m_elf).SetCrouch(false); return; } if (!((BaseAI)this).IsAlerted()) { ((Character)m_elf).SetCrouch(false); return; } float num = Vector3.Distance(((Component)target).transform.position, ((Component)this).transform.position); if (canSeeTarget) { if (num > 20f && num < 40f) { ((Character)m_elf).SetCrouch(Random.value < 0.7f); } else if (num >= 40f) { ((Character)m_elf).SetCrouch(Random.value < 0.8f); } else { ((Character)m_elf).SetCrouch(Random.value < 0.2f); } } else { ((Character)m_elf).SetCrouch(Random.value < 0.6f); } } public override void Awake() { ((MonsterAI)this).Awake(); m_elf = ((Component)this).GetComponent(); bool flag = ((Character)m_elf).IsTamed(); ((BaseAI)this).m_aggravatable = ((BaseAI)this).m_aggravatable && !flag; } public override bool UpdateAI(float dt) { if (!UpdateBaseAI(dt)) { return false; } if (((BaseAI)this).HuntPlayer()) { ((BaseAI)this).SetAlerted(true); } UpdateTargets(m_elf, dt, out var canHearTarget, out var canSeeTarget); if (UpdateDespawn(dt, canSeeTarget)) { return true; } if (UpdateFlee(dt, ((BaseAI)this).IsAlerted())) { return true; } if (UpdateAvoidFire(dt)) { return true; } if (UpdateNoMonsterArea(dt)) { return true; } if (UpdateHurt(dt)) { return true; } bool flag = (Object)(object)base.m_targetStatic != (Object)null || (Object)(object)base.m_targetCreature != (Object)null; if (UpdateCircleTarget(dt)) { return true; } ItemData val = ((MonsterAI)this).SelectBestAttack((Humanoid)(object)m_elf, dt); bool flag2 = val != null; bool flag3 = val != null && Time.time - val.m_lastAttackTime > val.m_shared.m_aiAttackInterval; bool flag4 = ((BaseAI)this).m_character.GetTimeSinceLastAttack() >= base.m_minAttackInterval; bool doAttack = val != null && flag3 && flag4; UpdateChargeAttack(dt, flag2, flag, doAttack, val); if (UpdateCirculate(dt, flag2, doAttack)) { return true; } UpdateCrouch(dt, base.m_targetCreature, canSeeTarget); UpdateBlock(dt, base.m_targetCreature, canSeeTarget); if (UpdateAttack(dt, val, doAttack, canHearTarget, canSeeTarget)) { return true; } ((BaseAI)this).IdleMovement(dt); if (!flag2 || !flag) { ((BaseAI)this).ChargeStop(); } return true; } } public static class ElfVars { public static readonly int isSet = BalrondHashCompat.StableHash("RustyMods.Elf.IsSet"); } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class Elf : Humanoid { [HarmonyPatch(typeof(Attack), "HaveAmmo")] [NullableContext(0)] private static class Attack_HaveAmmo { [NullableContext(1)] private static void Postfix(Humanoid character, ref bool __result) { if (!__result && character is Elf) { __result = true; } } } [NullableContext(0)] [HarmonyPatch(typeof(Attack), "FindAmmo")] private static class Attack_FindAmmo_Patch { [NullableContext(1)] private static void Postfix(Humanoid character, ItemData weapon, [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] ref ItemData __result) { if (__result != null || !(character is Elf elf) || string.IsNullOrEmpty(weapon.m_shared.m_ammoType)) { return; } string ammoType = weapon.m_shared.m_ammoType; string text = ammoType; if (!(text == "$ammo_arrows")) { if (text == "$ammo_bolts") { ItemData val = ((Humanoid)elf).GetInventory().AddItem("BoltBone", 10, 1, 0, 0L, "", false); if (val != null) { __result = val; } } } else { ItemData val2 = ((Humanoid)elf).GetInventory().AddItem("ArrowWood", 10, 1, 0, 0L, "", false); if (val2 != null) { __result = val2; } } } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [HarmonyPatch(typeof(SE_Harpooned), "UpdateStatusEffect")] private static class SE_Harpooned_UpdateStatusEffect_Patch { private static bool Prefix(SE_Harpooned __instance, float dt) { if (!Object.op_Implicit((Object)(object)((StatusEffect)__instance).m_character) || !Object.op_Implicit((Object)(object)__instance.m_attacker) || !(__instance.m_attacker is Elf)) { return true; } BaseUpdateSE(__instance, dt); UpdateSE_Harpooned(__instance, dt); return false; } private static void UpdateSE_Harpooned(SE_Harpooned __instance, float dt) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) Rigidbody val = default(Rigidbody); if (!((Component)((StatusEffect)__instance).m_character).TryGetComponent(ref val)) { return; } float num = Vector3.Distance(((Component)__instance.m_attacker).transform.position, ((Component)((StatusEffect)__instance).m_character).transform.position); if (!((StatusEffect)__instance).m_character.IsAttached()) { float num2 = Utils.Pull(val, ((Component)__instance.m_attacker).transform.position, m_pullTo, 25f, __instance.m_pullForce, __instance.m_smoothDistance, true, true, __instance.m_forcePower); __instance.m_drainStaminaTimer += dt; if (__instance.m_drainStaminaTimer > __instance.m_staminaDrainInterval && (double)num2 > 0.0) { __instance.m_drainStaminaTimer = 0f; __instance.m_attacker.UseStamina(__instance.m_staminaDrain * num2 * ((StatusEffect)__instance).m_character.GetMass()); } } if (Object.op_Implicit((Object)(object)__instance.m_line)) { __instance.m_line.SetSlack((1f - Utils.LerpStep(__instance.m_baseDistance / 2f, __instance.m_baseDistance, num)) * __instance.m_maxLineSlack); } if (num - __instance.m_baseDistance > __instance.m_breakDistance) { __instance.m_broken = true; } } private static void BaseUpdateSE(SE_Harpooned __instance, float dt) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) ((StatusEffect)__instance).m_time = ((StatusEffect)__instance).m_time + dt; if (!((double)((StatusEffect)__instance).m_repeatInterval <= 0.0) && !string.IsNullOrWhiteSpace(((StatusEffect)__instance).m_repeatMessage)) { ((StatusEffect)__instance).m_msgTimer = ((StatusEffect)__instance).m_msgTimer + dt; if (!(((StatusEffect)__instance).m_msgTimer <= ((StatusEffect)__instance).m_repeatInterval)) { ((StatusEffect)__instance).m_msgTimer = 0f; ((StatusEffect)__instance).m_character.Message(((StatusEffect)__instance).m_repeatMessageType, ((StatusEffect)__instance).m_repeatMessage, 0, (Sprite)null); } } } } [HarmonyPatch(typeof(SE_Puke), "Setup")] [NullableContext(0)] private static class SE_Puke_Setup_Patch { [NullableContext(1)] private static void Postfix(SE_Puke __instance) { if (((StatusEffect)__instance).m_character is Elf elf) { elf.m_queuedTexts.Clear(); elf.QueueSay(TalkManager.GetTalk(TalkManager.TalkType.Puke), "", "emote_despair", pukeFX); } } } [HarmonyPatch(typeof(SE_Puke), "UpdateStatusEffect")] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] private static class SE_Puke_Update_Patch { private static bool Prefix(SE_Puke __instance, float dt) { if (!(((StatusEffect)__instance).m_character is Elf)) { return true; } ((StatusEffect)__instance).m_time = ((StatusEffect)__instance).m_time + dt; UpdateStatus(__instance, dt); UpdateStats(__instance, dt); return false; } private static void UpdateStatus(SE_Puke __instance, float dt) { __instance.m_removeTimer += dt; if (!(__instance.m_removeTimer <= __instance.m_removeInterval)) { __instance.m_removeTimer = 0f; } } private static void UpdateStats(SE_Puke __instance, float dt) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ((SE_Stats)__instance).m_tickTimer = ((SE_Stats)__instance).m_tickTimer + dt; if (((SE_Stats)__instance).m_tickTimer >= ((SE_Stats)__instance).m_tickInterval) { ((SE_Stats)__instance).m_tickTimer = 0f; ((StatusEffect)__instance).m_character.Damage(new HitData { m_damage = { m_damage = 1f }, m_point = ((StatusEffect)__instance).m_character.GetTopPoint(), m_hitType = (HitType)14 }); } } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class QueuedSay { public string text = ""; public string trigger = ""; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public EffectListRef m_effect; } public float armor; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public ItemData m_weaponLoaded; public EffectList m_dodgeEffects = new EffectList(); public bool m_crouchToggled; public Vector3 m_hairColor = Vector3.one; public Vector3 m_skinColor = Vector3.one; private static float m_pullTo = 1f; private static readonly EffectListRef pukeFX = new EffectListRef { dataRefs = new List { new EffectListRef.EffectDataRef("fx_Puke") { attach = true, inheritParentRotation = true, childTransform = "Jaw" }, new EffectListRef.EffectDataRef("sfx_Puke_male") { variant = 0, attach = true }, new EffectListRef.EffectDataRef("sfx_Puke_female") { variant = 1, attach = true } } }; private static readonly int EmoteSit = Animator.StringToHash("emote_sit"); public float m_lastTargetUpdate; public float m_maxRange = 15f; public float m_greetRange = 10f; public float m_byeRange = 15f; public float m_offset = 2f; public float m_minTalkInterval = 1.5f; public float m_hideDialogDelay = 5f; public float m_randomTalkInterval = 10f; public float m_randomTalkChance = 1f; public float m_randomTalkTimer; public static readonly EffectListRef talkFX = new EffectListRef("sfx_dverger_vo_idle"); public static readonly EffectListRef greetFX = new EffectListRef("sfx_haldor_greet"); public static readonly EffectListRef goodbyeFX = new EffectListRef("sfx_haldor_laugh"); public static readonly EffectListRef alertedFX = new EffectListRef("sfx_dverger_vo_attack"); public bool m_didGreet; public bool m_didGoodbye; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public Player m_targetPlayer; public bool m_seeTarget; public bool m_hearTarget; public readonly Queue m_queuedTexts = new Queue(); private readonly List m_greetEmotes = new List { "emote_wave", "emote_bow" }; private readonly List m_randomEmote = new List { "emote_dance", "emote_despair", "emote_cry", "emote_point", "emote_flex", "emote_challenge", "emote_cheer", "emote_blowkiss", "emote_comehere", "emote_laugh", "emote_roar", "emote_shrug" }; public static readonly List instances = new List(); public ElfAI m_elfAI = null; public GameObject m_tombstone = null; public AggravatedReason m_aggravatedReason; public EffectList m_spawnEffects = new EffectList(); public EffectList m_skillLevelupEffects = new EffectList(); public EffectList m_equipStartEffects = new EffectList(); public EffectList m_perfectDodgeEffects = new EffectList(); public int m_modelIndex = 0; public bool m_showHair = true; public NorsemanConfigs configs; public float GetArmor() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) armor = configs.BaseArmor; if (base.m_chestItem != null) { armor += base.m_chestItem.GetArmor(); } if (base.m_legItem != null) { armor += base.m_legItem.GetArmor(); } if (base.m_helmetItem != null) { armor += base.m_helmetItem.GetArmor(); } if (base.m_shoulderItem != null) { armor += base.m_shoulderItem.GetArmor(); } ((Character)this).m_seman.ApplyArmorMods(ref armor); if (FactionManager.customFactions.TryGetValue(((Character)this).m_faction, out var value)) { if (EnvMan.IsDay()) { armor *= value.m_dayModifier; } else { armor *= value.m_nightModifier; } } return armor; } public override float GetBodyArmor() { return armor; } [NullableContext(2)] public override bool StartAttack(Character target, bool secondaryAttack) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Invalid comparison between Unknown and I4 //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Invalid comparison between Unknown and I4 if ((((Character)this).InAttack() && !((Humanoid)this).HaveQueuedChain()) || ((Character)this).InDodge() || !((Character)this).CanMove() || ((Character)this).IsKnockedBack() || ((Character)this).IsStaggering() || ((Character)this).InMinorAction()) { return false; } ItemData currentWeapon = ((Humanoid)this).GetCurrentWeapon(); if (currentWeapon == null || (!currentWeapon.HaveSecondaryAttack() && !currentWeapon.HavePrimaryAttack())) { return false; } bool flag = currentWeapon.HaveSecondaryAttack() && (double)Random.value > 0.5; if ((int)currentWeapon.m_shared.m_skillType == 5) { flag = false; } if (base.m_currentAttack != null) { base.m_currentAttack.Stop(); base.m_previousAttack = base.m_currentAttack; base.m_currentAttack = null; } Attack val = ((!flag) ? currentWeapon.m_shared.m_attack.Clone() : currentWeapon.m_shared.m_secondaryAttack.Clone()); if (!val.Start((Humanoid)(object)this, ((Character)this).m_body, ((Character)this).m_zanim, ((Character)this).m_animEvent, base.m_visEquipment, currentWeapon, base.m_previousAttack, base.m_timeSinceLastAttack, Random.Range(0.5f, 1f))) { return false; } if (currentWeapon.m_shared.m_attack.m_requiresReload) { SetWeaponLoaded(null); } if (currentWeapon.m_shared.m_attack.m_bowDraw) { currentWeapon.m_shared.m_attack.m_attackDrawPercentage = 0f; } if ((int)currentWeapon.m_shared.m_itemType != 15) { currentWeapon.m_durability -= 1.5f; } ((Humanoid)this).ClearActionQueue(); ((Humanoid)this).StartAttackGroundCheck(); base.m_currentAttack = val; base.m_currentAttackIsSecondary = flag; base.m_lastCombatTimer = 0f; if (currentWeapon.m_shared.m_name == "$item_stafficeshards") { ((MonoBehaviour)this).Invoke("StopCurrentAttack", 5f); } return true; } private void StopCurrentAttack() { if (base.m_currentAttack != null) { base.m_currentAttack.Stop(); base.m_previousAttack = base.m_currentAttack; base.m_currentAttack = null; } } [NullableContext(2)] private void SetWeaponLoaded(ItemData weapon) { if (weapon != m_weaponLoaded) { m_weaponLoaded = weapon; ((Character)this).m_nview.GetZDO().Set(ZDOVars.s_weaponLoaded, weapon != null); } } public void SetBlocking(bool block) { ((Character)this).m_blocking = block; } public override void SetCrouch(bool crouch) { m_crouchToggled = crouch; } public bool CanCrouch() { if (((Character)this).IsSwimming()) { return false; } if (((Character)this).IsRunning()) { return false; } if (((Character)this).IsBlocking()) { return false; } if (((Character)this).InAttack()) { return false; } if (((Character)this).IsDrawingBow()) { return false; } if (((Character)this).IsDead()) { return false; } if (((Character)this).IsStaggering()) { return false; } return true; } public void SetupCustomization() { base.m_hairItem = ((Character)this).m_nview.GetZDO().GetString(ZDOVars.s_hairItem, ""); base.m_beardItem = ((Character)this).m_nview.GetZDO().GetString(ZDOVars.s_beardItem, ""); if (!((Character)this).m_nview.GetZDO().GetBool(ElfVars.isSet, false)) { SetRandomModel(out var isFemale); SetRandomName(); SetRandomHair(); SetRandomBeard(isFemale); configs.AddLoot(base.m_inventory); SetRandomHairColor(); ((Character)this).m_nview.GetZDO().Set(ElfVars.isSet, true); } base.m_visEquipment.SetHairEquipped((!string.IsNullOrEmpty(base.m_hairItem)) ? BalrondHashCompat.StableHash(base.m_hairItem) : 0); base.m_visEquipment.SetBeardEquipped((!string.IsNullOrEmpty(base.m_beardItem)) ? BalrondHashCompat.StableHash(base.m_beardItem) : 0); } public void SetRandomName() { string text = ((((Character)this).m_nview.GetZDO().GetInt(ZDOVars.s_modelIndex, 0) == 0) ? NameGenerator.names.GenerateMaleName() : NameGenerator.names.GenerateFemaleName()); ((Character)this).m_nview.GetZDO().Set(ZDOVars.s_tamedName, text); } public void SetRandomSkinColor() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Color randomSkinColor = CustomizationManager.GetRandomSkinColor(); Vector3 skinColor = Utils.ColorToVec3(randomSkinColor); SetSkinColor(skinColor); } public void SetSkinColor(Vector3 color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!(m_skinColor == color)) { m_skinColor = color; base.m_visEquipment.SetSkinColor(color); } } public void SetRandomModel(out bool isFemale) { base.m_visEquipment.SetModel(m_modelIndex); isFemale = m_modelIndex != 0; } public void SetRandomBeard(bool isFemale) { if (isFemale) { ((Humanoid)this).SetBeard(""); } else if (CustomizationManager.beards.Count > 0) { string beard = CustomizationManager.beards[Random.Range(0, CustomizationManager.beards.Count)]; ((Humanoid)this).SetBeard(beard); } } public void SetRandomHair() { if (m_showHair && CustomizationManager.hairs.Count > 0) { string hair = CustomizationManager.hairs[Random.Range(0, CustomizationManager.hairs.Count)]; ((Humanoid)this).SetHair(hair); } } public void SetRandomHairColor() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Color val = CustomizationManager.hairColors[Random.Range(0, CustomizationManager.hairColors.Count)]; SetHairColor(Utils.ColorToVec3(val)); } public void SetHairColor(Vector3 color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!(m_hairColor == color)) { m_hairColor = color; base.m_visEquipment.SetHairColor(m_hairColor); } } public override void ApplyArmorDamageMods(ref DamageModifiers mods) { if (base.m_chestItem != null) { ((DamageModifiers)(ref mods)).Apply(base.m_chestItem.m_shared.m_damageModifiers); } if (base.m_legItem != null) { ((DamageModifiers)(ref mods)).Apply(base.m_legItem.m_shared.m_damageModifiers); } if (base.m_helmetItem != null) { ((DamageModifiers)(ref mods)).Apply(base.m_helmetItem.m_shared.m_damageModifiers); } if (base.m_shoulderItem != null) { ((DamageModifiers)(ref mods)).Apply(base.m_shoulderItem.m_shared.m_damageModifiers); } } public void Dodge(Vector3 dir) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.rotation = Quaternion.LookRotation(dir); ((Character)this).m_body.rotation = ((Component)this).transform.rotation; ((Character)this).m_zanim.SetTrigger("dodge"); ((Character)this).AddNoise(5f); m_dodgeEffects.Create(((Component)this).transform.position, Quaternion.identity, ((Component)this).transform, 1f, -1); } public bool CanDodge() { return !((Character)this).IsBlocking() && !((Character)this).IsRunning() && !((Character)this).IsSwimming(); } public override float GetMaxEitr() { return 9999f; } public void AddRandomShield() { GameObject[] randomShield = base.m_randomShield; if (randomShield != null && randomShield.Length > 0) { int num = Random.Range(0, base.m_randomShield.Length); GameObject val = base.m_randomShield[num]; if ((Object)(object)val != (Object)null) { ((Humanoid)this).GiveDefaultItem(val); } } } public void AddRandomWeapon() { GameObject[] randomWeapon = base.m_randomWeapon; if (randomWeapon != null && randomWeapon.Length > 0) { int num = Random.Range(0, base.m_randomWeapon.Length); GameObject val = base.m_randomWeapon[num]; if ((Object)(object)val != (Object)null) { ((Humanoid)this).GiveDefaultItem(val); } } } public void AddRandomArmor() { GameObject[] randomArmor = base.m_randomArmor; if (randomArmor != null && randomArmor.Length > 0) { int num = Random.Range(0, base.m_randomArmor.Length); GameObject val = base.m_randomArmor[num]; if ((Object)(object)val != (Object)null) { ((Humanoid)this).GiveDefaultItem(val); } } } public void AddDefaults() { GameObject[] defaultItems = base.m_defaultItems; if (defaultItems == null || defaultItems.Length <= 0) { return; } GameObject[] defaultItems2 = base.m_defaultItems; foreach (GameObject val in defaultItems2) { if (!((Object)(object)val == (Object)null)) { ((Humanoid)this).GiveDefaultItem(val); } } } public void AddRandomItems() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected I4, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected I4, but got Unknown RandomItem[] randomItems = base.m_randomItems; if (randomItems == null || randomItems.Length <= 0) { return; } int num = (int)Enum.GetValues(typeof(ItemType)).Cast().Max(); base.m_randomItemSlotFilled = new bool[num]; RandomItem[] randomItems2 = base.m_randomItems; foreach (RandomItem val in randomItems2) { if ((Object)(object)val.m_prefab == (Object)null) { continue; } float value = Random.value; if (!(value <= val.m_chance)) { int num2 = (int)val.m_prefab.GetComponent().m_itemData.m_shared.m_itemType; if (!base.m_randomItemSlotFilled[num2]) { base.m_randomItemSlotFilled[num2] = true; ((Humanoid)this).GiveDefaultItem(val.m_prefab); } } } } public void AddDefaultItems() { if (!((Character)this).m_nview.GetZDO().GetBool(ZDOVars.s_addedDefaultItems, false)) { AddDefaults(); } } [return: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 1, 2 })] public List GetEquipment() { return new List { base.m_helmetItem, base.m_legItem, base.m_shoulderItem, base.m_chestItem, base.m_utilityItem, base.m_leftItem, base.m_rightItem, base.m_ammoItem, base.m_trinketItem }; } public void EquipItems() { UnequipIfNotInInventory(); List allItemsInGridOrder = base.m_inventory.GetAllItemsInGridOrder(); for (int i = 0; i < allItemsInGridOrder.Count; i++) { ItemData val = allItemsInGridOrder[i]; if (val.IsEquipable()) { EquipIfBetter(val); } } ((Humanoid)this).SetupVisEquipment(base.m_visEquipment, false); GetArmor(); } public override void SetupVisEquipment(VisEquipment visEq, bool isRagdoll) { //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) if (!isRagdoll) { visEq.SetLeftItem((base.m_leftItem != null) ? ((Object)base.m_leftItem.m_dropPrefab).name : "", (base.m_leftItem != null) ? base.m_leftItem.m_variant : 0); visEq.SetRightItem((base.m_rightItem != null) ? ((Object)base.m_rightItem.m_dropPrefab).name : ""); visEq.SetLeftBackItem((base.m_hiddenLeftItem != null) ? ((Object)base.m_hiddenLeftItem.m_dropPrefab).name : "", (base.m_hiddenLeftItem != null) ? base.m_hiddenLeftItem.m_variant : 0); visEq.SetRightBackItem((base.m_hiddenRightItem != null) ? ((Object)base.m_hiddenRightItem.m_dropPrefab).name : ""); } visEq.SetChestItem((base.m_chestItem != null) ? ((Object)base.m_chestItem.m_dropPrefab).name : ""); visEq.SetLegItem((base.m_legItem != null) ? ((Object)base.m_legItem.m_dropPrefab).name : ""); visEq.SetHelmetItem((base.m_helmetItem != null) ? ((Object)base.m_helmetItem.m_dropPrefab).name : ""); visEq.SetShoulderItem((base.m_shoulderItem != null) ? ((Object)base.m_shoulderItem.m_dropPrefab).name : "", (base.m_shoulderItem != null) ? base.m_shoulderItem.m_variant : 0); visEq.SetUtilityItem((base.m_utilityItem != null) ? ((Object)base.m_utilityItem.m_dropPrefab).name : ""); visEq.SetTrinketItem((base.m_trinketItem != null) ? ((Object)base.m_trinketItem.m_dropPrefab).name : ""); visEq.SetBeardItem(base.m_beardItem); visEq.SetHairItem(base.m_hairItem); visEq.SetHairColor(m_hairColor); visEq.SetSkinColor(m_skinColor); } public void EquipIfBetter(ItemData item) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected I4, but got Unknown ItemType itemType = item.m_shared.m_itemType; ItemType val = itemType; switch (val - 5) { case 1: if (base.m_helmetItem == null || base.m_helmetItem.IsItemBetter(item)) { ((Humanoid)this).EquipItem(item, true); } break; case 2: if (base.m_chestItem == null || base.m_chestItem.IsItemBetter(item)) { ((Humanoid)this).EquipItem(item, true); } break; case 12: if (base.m_shoulderItem == null || base.m_shoulderItem.IsItemBetter(item)) { ((Humanoid)this).EquipItem(item, true); } break; case 6: if (base.m_legItem == null || base.m_legItem.IsItemBetter(item)) { ((Humanoid)this).EquipItem(item, true); } break; case 13: if (base.m_utilityItem == null) { ((Humanoid)this).EquipItem(item, true); } break; case 0: case 10: if (base.m_leftItem == null || base.m_leftItem.IsItemBetter(item)) { ((Humanoid)this).EquipItem(item, true); } break; case 4: if (base.m_ammoItem == null || base.m_ammoItem.IsItemBetter(item)) { ((Humanoid)this).EquipItem(item, true); } break; default: if (base.m_rightItem == null || base.m_rightItem.IsItemBetter(item)) { ((Humanoid)this).EquipItem(item, true); } break; } } public void UnequipIfNotInInventory() { List equipment = GetEquipment(); for (int i = 0; i < equipment.Count; i++) { ItemData val = equipment[i]; if (val != null && !base.m_inventory.ContainsItem(val)) { ((Humanoid)this).UnequipItem(val, true); } } } public bool IsHoldingTorch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 if (base.m_rightItem != null && (int)base.m_rightItem.m_shared.m_itemType == 15) { return true; } if (base.m_leftItem != null && (int)base.m_leftItem.m_shared.m_itemType == 15) { return true; } return false; } public override void OnRagdollCreated(Ragdoll ragdoll) { VisEquipment component = ((Component)ragdoll).GetComponent(); ((Humanoid)this).SetupVisEquipment(component, true); } public void LookTowardsTarget() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (((Character)this).m_nview.IsOwner() && !((Object)(object)m_targetPlayer == (Object)null)) { Vector3 val = ((Character)this).GetVelocity(); if ((double)((Vector3)(ref val)).magnitude < 0.5 && !((Character)this).InAttack()) { val = ((Character)m_targetPlayer).GetEyePoint() - ((Character)this).GetEyePoint(); Vector3 normalized = ((Vector3)(ref val)).normalized; ((Character)this).SetLookDir(normalized, 0f); } } } public void UpdateTalk(float dt) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (((BaseAI)m_elfAI).IsAlerted()) { return; } m_randomTalkTimer += dt; if (m_randomTalkTimer < m_randomTalkInterval) { return; } m_randomTalkTimer = 0f; float value = Random.value; if (value > m_randomTalkChance) { return; } UpdateTarget(); if ((Object)(object)m_targetPlayer != (Object)null) { if (m_seeTarget) { float num = Vector3.Distance(((Component)m_targetPlayer).transform.position, ((Component)this).transform.position); if (!m_didGreet && num < m_greetRange) { m_didGreet = true; string trigger = m_greetEmotes[Random.Range(0, m_greetEmotes.Count)]; QueueSay(TalkManager.GetTalk(TalkManager.TalkType.Greets), "", trigger, greetFX); } if (m_didGreet && !m_didGoodbye && num > m_byeRange) { m_didGoodbye = true; string trigger2 = m_greetEmotes[Random.Range(0, m_greetEmotes.Count)]; QueueSay(TalkManager.GetTalk(TalkManager.TalkType.Farewells), "", trigger2, goodbyeFX); } if (m_didGreet && m_didGoodbye) { QueueSay(TalkManager.GetTalk(TalkManager.TalkType.Generic), "", "", talkFX); } } else if (InPlayerBase()) { QueueSay(TalkManager.GetTalk(TalkManager.TalkType.PlayerBase), "", "", talkFX); } } UpdateSayQueue(); } public void UpdateTarget() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if ((double)(Time.time - m_lastTargetUpdate) <= 1.0) { return; } m_lastTargetUpdate = Time.time; m_targetPlayer = null; Player closestPlayer = Player.GetClosestPlayer(((Component)this).transform.position, m_maxRange); if (!((Object)(object)closestPlayer == (Object)null) && !((BaseAI)m_elfAI).IsEnemy((Character)(object)closestPlayer)) { m_seeTarget = ((BaseAI)m_elfAI).CanSeeTarget((Character)(object)closestPlayer); m_hearTarget = ((BaseAI)m_elfAI).CanHearTarget((Character)(object)closestPlayer); if (m_seeTarget || m_hearTarget) { m_targetPlayer = closestPlayer; } } } public bool QueueSay(List texts, string context = "", string trigger = "", [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] EffectListRef effect = null) { if (texts.Count == 0 || m_queuedTexts.Count >= 3) { return false; } string text = texts[Random.Range(0, texts.Count)]; if (!string.IsNullOrEmpty(context)) { text = string.Format(text, context); } QueuedSay item = new QueuedSay { text = text, trigger = trigger, m_effect = effect }; m_queuedTexts.Enqueue(item); return true; } public bool Say(List texts, string trigger = "", [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] EffectListRef effect = null) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (texts.Count == 0) { return false; } Say(texts[Random.Range(0, texts.Count)], trigger); effect?.Create(((Component)this).transform.position, Quaternion.identity, null, 1f, base.m_visEquipment.GetModelIndex()); return true; } public void QueueEmote(string trigger) { QueuedSay item = new QueuedSay { text = string.Empty, trigger = trigger }; m_queuedTexts.Enqueue(item); } public void UpdateSayQueue() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (m_queuedTexts.Count > 0 && !(Time.time - NpcTalk.m_lastTalkTime < m_minTalkInterval)) { QueuedSay queuedSay = m_queuedTexts.Dequeue(); Say(queuedSay.text, queuedSay.trigger); queuedSay.m_effect?.Create(((Component)this).transform.position, Quaternion.identity, null, 1f, base.m_visEquipment.GetModelIndex()); } } public void Say(string text, string trigger) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) NpcTalk.m_lastTalkTime = Time.time; if (!string.IsNullOrEmpty(text)) { Chat.instance.SetNpcText(((Component)this).gameObject, Vector3.up * m_offset, 20f, m_hideDialogDelay, "", text, false); } if (!string.IsNullOrEmpty(trigger)) { ((Character)this).m_animator.SetTrigger(trigger); } } public bool InPlayerBase() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Object.op_Implicit((Object)(object)EffectArea.IsPointInsideArea(((Component)this).transform.position, (Type)4, 30f)); } public string GetName() { return Localization.instance.Localize(GetText()); } public string GetText() { if (!((Character)this).m_nview.IsValid()) { return string.Empty; } string @string = ((Character)this).m_nview.GetZDO().GetString(ZDOVars.s_tamedName, ""); return string.IsNullOrEmpty(@string) ? ((Character)this).m_name : @string; } public void DropItems() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; float num = 0.5f; foreach (ItemData allItem in ((Humanoid)this).GetInventory().GetAllItems()) { if (allItem.IsEquipable()) { continue; } Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f); Vector3 val2 = Random.insideUnitSphere * num; Vector3 val3 = position + Vector3.up * 0.5f + val2; ItemDrop val4 = ItemDrop.DropItem(allItem, allItem.m_stack, val3, val); Rigidbody component = ((Component)val4).GetComponent(); if (!((Object)(object)component == (Object)null)) { Vector3 insideUnitSphere = Random.insideUnitSphere; if ((double)insideUnitSphere.y < 0.0) { insideUnitSphere.y = 0f - insideUnitSphere.y; } component.AddForce(insideUnitSphere * 5f, (ForceMode)2); } } } public override void Awake() { instances.Add(this); configs = NorsemanConfigs.configs[((Object)this).name.Replace("(Clone)", "")]; base.m_inventory.m_name = "NorsemanInventory"; ((Character)this).m_health = configs.BaseHealth; m_elfAI = ((Component)this).GetComponent(); ((Humanoid)this).Awake(); if (((Character)this).m_nview.IsValid()) { SetupCustomization(); } ElfAI elfAI = m_elfAI; ((BaseAI)elfAI).m_onBecameAggravated = (Action)Delegate.Combine(((BaseAI)elfAI).m_onBecameAggravated, new Action(OnAggravated)); base.m_visEquipment.m_isPlayer = true; } public override void OnDeath() { DropItems(); ((Character)this).OnDeath(); } public override void OnDestroy() { instances.Remove(this); ((Humanoid)this).OnDestroy(); } public override void Start() { if (((Character)this).m_nview.IsValid()) { if (!((Character)this).m_nview.GetZDO().GetBool(ZDOVars.s_addedDefaultItems, false)) { AddDefaultItems(); AddRandomItems(); AddRandomArmor(); AddRandomWeapon(); AddRandomShield(); ((Character)this).m_nview.GetZDO().Set(ZDOVars.s_addedDefaultItems, true); } EquipItems(); } } public void Update() { if (((Character)this).m_nview.IsValid() && ((Character)this).m_nview.IsOwner()) { float deltaTime = Time.deltaTime; UpdateTalk(deltaTime); } } public override string GetHoverName() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (!FactionManager.customFactions.TryGetValue(((Character)this).m_faction, out var value)) { return GetName(); } return "" + GetName() + ""; } public override void OnDamaged(HitData hit) { } public void OnAggravated(AggravatedReason reason) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 m_aggravatedReason = reason; if ((int)reason != 0) { if ((int)reason == 2) { Say(TalkManager.GetTalk(TalkManager.TalkType.Thieved), "emote_roar", alertedFX); } } else { Say(TalkManager.GetTalk(TalkManager.TalkType.Damaged), "emote_roar", alertedFX); } } public static List GetAllElves() { return instances; } public static List GetElves(Vector3 pos, float range) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List allElves = GetAllElves(); for (int i = 0; i < allElves.Count; i++) { Elf elf = allElves[i]; float num = Vector3.Distance(pos, ((Component)elf).transform.position); if (num < range) { list.Add(elf); } } return list; } [NullableContext(2)] public static Elf GetNearestElf(Vector3 pos, float maxRange) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) float num = float.MaxValue; Elf result = null; List allElves = GetAllElves(); for (int i = 0; i < allElves.Count; i++) { Elf elf = allElves[i]; float num2 = Vector3.Distance(pos, ((Component)elf).transform.position); if (num2 < num && num2 < maxRange) { result = elf; num = num2; } } return result; } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class Clone { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private GameObject Prefab; private readonly string PrefabName; private readonly string NewName; private bool Loaded; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] [method: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] [field: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] public event Action OnCreated; public Clone(string prefabName, string newName) { PrefabName = prefabName; NewName = newName; PrefabManager.Clones.Add(this); } internal void Create() { if (!Loaded) { GameObject prefab = Helpers.GetPrefab(PrefabName); if (prefab != null) { Prefab = Object.Instantiate(prefab, CloneManager.GetRootTransform(), false); ((Object)Prefab).name = NewName; PrefabManager.RegisterPrefab(Prefab); this.OnCreated?.Invoke(Prefab); CloneManager.clones[((Object)Prefab).name] = Prefab; Loaded = true; } } } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public static class CloneManager { public static GameObject root; internal static readonly Dictionary clones; internal static readonly Dictionary norsemen; static CloneManager() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown clones = new Dictionary(); norsemen = new Dictionary(); root = new GameObject("BalrondElvenFactionsReborn_prefab_root"); Object.DontDestroyOnLoad((Object)(object)root); root.SetActive(false); } public static Transform GetRootTransform() { return root.transform; } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static class CommandManager { [Serializable] [CompilerGenerated] private sealed class <>c { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static readonly <>c <>9 = new <>c(); [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static ConsoleEventFailable <>9__3_0; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static Func, bool> <>9__3_1; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static Func, string> <>9__3_2; [NullableContext(0)] internal object b__3_0(ConsoleEventArgs args) { if (args.Length < 2) { return false; } if (!commands.TryGetValue(args[1], out var value)) { return false; } return value.Run(args); } [NullableContext(0)] internal bool b__3_1(KeyValuePair x) { return !x.Value.IsSecret(); } [NullableContext(0)] internal string b__3_2(KeyValuePair x) { return x.Key; } } private static readonly string startCommand; public static readonly Dictionary commands; static CommandManager() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown commands = new Dictionary(); Harmony harmony = ElvenNPCPlugin.instance._harmony; startCommand = "BalrondElvenFactionsReborn".ToLower(); harmony.Patch((MethodBase)AccessTools.Method(typeof(Terminal), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(CommandManager), "Patch_Terminal_Awake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(Terminal), "updateSearch", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(CommandManager), "Patch_Terminal_UpdateSearch", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(Terminal), "tabCycle", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(CommandManager), "Patch_Terminal_TabCycle", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void Patch_Terminal_Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) string text = startCommand; object obj = <>c.<>9__3_0; if (obj == null) { ConsoleEventFailable val = [NullableContext(0)] (ConsoleEventArgs args) => { if (args.Length < 2) { return false; } ElvenCommand value; return (!commands.TryGetValue(args[1], out value)) ? ((object)false) : ((object)value.Run(args)); }; <>c.<>9__3_0 = val; obj = (object)val; } new ConsoleCommand(text, "use help to find available commands", (ConsoleEventFailable)obj, false, false, false, false, false, new ConsoleOptionsFetcher(Enumerable.ToList), false, false, false); } private static bool Patch_Terminal_UpdateSearch(Terminal __instance, string word) { 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] != startCommand) { return true; } return HandleSearch(__instance, word, array); } private static bool HandleSearch(Terminal __instance, string word, string[] strArray) { if (!commands.TryGetValue(strArray[1], out var value)) { return true; } if (value.HasOptions() && strArray.Length == 3) { List list = value.FetchOptions(); string currentSearch = strArray[2]; List list2; if (!Utility.IsNullOrWhiteSpace(currentSearch)) { int num = list.IndexOf(currentSearch); list2 = ((num != -1) ? list.GetRange(num, list.Count - num) : list); list2 = list2.FindAll((string x) => x.ToLower().Contains(currentSearch.ToLower())); } else { list2 = list; } if (list2.Count <= 0) { __instance.m_search.text = value.m_description; } else { __instance.m_lastSearch.Clear(); __instance.m_lastSearch.AddRange(list2); __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 text = __instance.m_lastSearch[i]; TMP_Text search = __instance.m_search; search.text = search.text + text + " "; } if (__instance.m_lastSearch.Count <= num2) { return false; } int num4 = __instance.m_lastSearch.Count - num2; TMP_Text search2 = __instance.m_search; search2.text += $"... {num4} more."; } } else { __instance.m_search.text = value.m_description; } return false; } private static bool Patch_Terminal_TabCycle(Terminal __instance, string word, [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] List options, bool usePrefix) { if (options == null || options.Count == 0) { return true; } usePrefix = usePrefix && __instance.m_tabPrefix > '\0'; if (usePrefix) { if (word.Length < 1 || word[0] != __instance.m_tabPrefix) { return true; } word = word.Substring(1); } return HandleTabCycle(__instance, word, options, usePrefix); } private static bool HandleTabCycle(Terminal __instance, string word, List options, bool usePrefix) { string text = ((TMP_InputField)__instance.m_input).text; string[] array = text.Split(new char[1] { ' ' }); if (array.Length < 2 || !string.Equals(array[0], startCommand, StringComparison.CurrentCultureIgnoreCase) || !commands.ContainsKey(array[1].ToLower())) { return true; } if (__instance.m_tabCaretPosition == -1) { __instance.m_tabOptions.Clear(); __instance.m_tabCaretPosition = ((TMP_InputField)__instance.m_input).caretPosition; word = word.ToLower(); __instance.m_tabLength = word.Length; if (__instance.m_tabLength == 0) { __instance.m_tabOptions.AddRange(options); } else { foreach (string option in options) { if (option != null && option.Length > __instance.m_tabLength && option.Substring(0, __instance.m_tabLength).ToLower() == word) { __instance.m_tabOptions.Add(option); } } } __instance.m_tabOptions.Sort(); __instance.m_tabIndex = -1; } if (__instance.m_tabOptions.Count == 0) { __instance.m_tabOptions.AddRange(__instance.m_lastSearch); } if (__instance.m_tabOptions.Count == 0) { return false; } if (++__instance.m_tabIndex >= __instance.m_tabOptions.Count) { __instance.m_tabIndex = 0; } if (__instance.m_tabCaretPosition - __instance.m_tabLength >= 0) { int num = 0; int num2 = 0; for (int i = 0; i < text.Length; i++) { if (text[i] == ' ') { num++; if (num == 2) { num2 = i + 1; break; } } } if (array.Length >= 3 && num2 > 0) { string text2 = text.Substring(0, num2); ((TMP_InputField)__instance.m_input).text = text2 + __instance.m_tabOptions[__instance.m_tabIndex]; } else if (array.Length == 2) { ((TMP_InputField)__instance.m_input).text = text + " " + __instance.m_tabOptions[__instance.m_tabIndex]; } } int tabCaretPositionEnd = (((TMP_InputField)__instance.m_input).caretPosition = ((TMP_InputField)__instance.m_input).text.Length); __instance.m_tabCaretPositionEnd = tabCaretPositionEnd; return false; } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class ElvenCommand { public readonly string m_description; private readonly bool m_isSecret; private readonly bool m_adminOnly; private readonly Func m_command; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1, 1 })] private readonly Func> m_optionFetcher; public bool Run(ConsoleEventArgs args) { return !IsAdmin() || m_command(args); } private bool IsAdmin() { if (!Object.op_Implicit((Object)(object)ZNet.m_instance)) { return true; } if (!m_adminOnly || ZNet.m_instance.LocalPlayerIsAdminOrHost()) { return true; } ElvenNPCPlugin.LogWarning("Admin only"); return false; } public bool IsSecret() { return m_isSecret; } public List FetchOptions() { return (m_optionFetcher == null) ? new List() : m_optionFetcher(); } public bool HasOptions() { return m_optionFetcher != null; } public ElvenCommand(string input, string description, Func command, [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1, 1 })] Func> optionsFetcher = null, bool isSecret = false, bool adminOnly = false) { m_description = description; m_command = command; m_isSecret = isSecret; CommandManager.commands[input] = this; m_optionFetcher = optionsFetcher; m_adminOnly = adminOnly; } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static class ConfigManager { [Flags] [NullableContext(0)] public enum LogLevel { None = 0, Debug = 1, Warning = 2, Error = 4, Info = 8 } public static readonly ISerializer serializer; public static readonly IDeserializer deserializer; private static readonly ConfigFile Config; public static readonly ConfigSync ConfigSync; private static readonly string ConfigFileName; private static readonly string ConfigFileFullPath; public static readonly string DirectoryPath; private static readonly ConfigEntry logLevels; public static bool ShouldLog(LogLevel type) { return logLevels.Value.HasFlag(type); } static ConfigManager() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown serializer = ((BuilderSkeleton)(object)new SerializerBuilder().ConfigureDefaultValuesHandling((DefaultValuesHandling)7).DisableAliases()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); deserializer = ((BuilderSkeleton)(object)new DeserializerBuilder().IgnoreUnmatchedProperties()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); Config = ((BaseUnityPlugin)ElvenNPCPlugin.instance).Config; ConfigFileName = "balrond.astafaraios.BalrondElvenFactionsReborn.cfg"; ConfigFileFullPath = Path.Combine(Paths.ConfigPath, ConfigFileName); ConfigSync = new ConfigSync("balrond.astafaraios.BalrondElvenFactionsReborn") { DisplayName = "BalrondElvenFactionsReborn", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4" }; DirectoryPath = Path.Combine(Paths.ConfigPath, "BalrondElvenFactionsReborn"); if (!Directory.Exists(DirectoryPath)) { Directory.CreateDirectory(DirectoryPath); } ConfigEntry lockingConfig = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only."); ConfigSync.AddLockingConfigEntry(lockingConfig); logLevels = config("1 - General", "Log Levels", LogLevel.Error, "Set log levels", synchronizedSetting: false); Harmony harmony = ElvenNPCPlugin.instance._harmony; harmony.Patch((MethodBase)AccessTools.Method(typeof(ZNet), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ConfigManager), "Patch_ZNet_Awake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void Patch_ZNet_Awake(ZNet __instance) { TalkManager.UpdateSync(__instance); NameGenerator.UpdateSync(__instance); } public static 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 static void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { ElvenNPCPlugin.LogDebug("ReadConfigValues called"); Config.Reload(); } catch { ElvenNPCPlugin.LogError("There was an issue loading your " + ConfigFileName); ElvenNPCPlugin.LogError("Please check your config entries for spelling and format!"); } } public static ConfigEntry config<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags); ConfigEntry val2 = Config.Bind(group, name, value, val); SyncedConfigEntry syncedConfigEntry = ConfigSync.AddConfigEntry(val2); syncedConfigEntry.SynchronizedConfig = synchronizedSetting; return val2; } public static ConfigEntry config<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), synchronizedSetting); } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static class CustomizationManager { public static readonly List beards = new List(); public static readonly List hairs = new List(); public static readonly List hairColors = new List { Color.black, new Color(0.98f, 0.94f, 0.75f, 1f), new Color(0.63f, 0.36f, 0f, 1f), new Color(0.15f, 0.08f, 0.05f, 1f), new Color(0.35f, 0.25f, 0.15f, 1f), new Color(0.55f, 0.45f, 0.35f, 1f), new Color(0.95f, 0.87f, 0.51f, 1f), new Color(0.85f, 0.75f, 0.45f, 1f), new Color(0.72f, 0.65f, 0.52f, 1f), new Color(0.45f, 0.18f, 0.08f, 1f), new Color(0.55f, 0.12f, 0.05f, 1f), new Color(0.72f, 0.25f, 0.12f, 1f), new Color(0.4f, 0.4f, 0.4f, 1f), new Color(0.65f, 0.65f, 0.65f, 1f), new Color(0.88f, 0.88f, 0.9f, 1f), new Color(0.25f, 0.25f, 0.28f, 1f) }; public static readonly List skinColors = new List { new Color(1f, 1f, 1f, 1f), new Color(1f, 0.95f, 0.92f, 1f), new Color(1f, 0.92f, 0.86f, 1f), new Color(1f, 0.94f, 0.88f, 1f), new Color(1f, 0.9f, 0.82f, 1f), new Color(1f, 0.88f, 0.78f, 1f), new Color(0.98f, 0.85f, 0.72f, 1f), new Color(0.95f, 0.82f, 0.68f, 1f), new Color(0.92f, 0.78f, 0.62f, 1f), new Color(0.88f, 0.72f, 0.56f, 1f), new Color(0.85f, 0.68f, 0.52f, 1f), new Color(0.78f, 0.62f, 0.48f, 1f), new Color(1f, 0.88f, 0.75f, 1f), new Color(0.98f, 0.9f, 0.8f, 1f), new Color(0.95f, 0.86f, 0.76f, 1f) }; public static Color GetRandomSkinColor() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) int index = Random.Range(0, skinColors.Count); return skinColors[index]; } public static void GetHairAndBeards(ObjectDB db) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 foreach (GameObject item in db.m_items) { ItemDrop component = item.GetComponent(); if ((int)component.m_itemData.m_shared.m_itemType == 10) { if (Utils.CustomStartsWith(((Object)item).name, "Beard")) { beards.Add(((Object)item).name); } else if (Utils.CustomStartsWith(((Object)item).name, "Hair")) { hairs.Add(((Object)item).name); } } } beards.RemoveAll((string x) => x.Contains("_")); hairs.RemoveAll((string x) => x.Contains("_")); } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class DatabaseAddMethods { public void AddItems(List items) { foreach (GameObject item in items) { AddItem(item); } } public void AddRecipes(List recipes) { foreach (Recipe recipe in recipes) { AddRecipe(recipe); } } public void AddStatuseffects(List statusEffects) { foreach (StatusEffect statusEffect in statusEffects) { AddStatus(statusEffect); } } private bool IsObjectDBValid() { return (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count != 0 && ObjectDB.instance.m_recipes.Count != 0 && (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null; } private void AddStatus(StatusEffect status) { if (!IsObjectDBValid()) { return; } if ((Object)(object)status != (Object)null) { if ((Object)(object)ObjectDB.instance.GetStatusEffect(status.m_nameHash) == (Object)null) { ObjectDB.instance.m_StatusEffects.Add(status); } else { Debug.Log((object)("BalrondElvenFactionsReborn: " + ((Object)status).name + " - Status already in the game")); } } else { Debug.LogError((object)("BalrondElvenFactionsReborn: " + ((Object)status).name + " - Status not found")); } } private void AddRecipe(Recipe recipe) { if (!IsObjectDBValid()) { return; } if ((Object)(object)recipe != (Object)null) { if ((Object)(object)ObjectDB.instance.m_recipes.Find([NullableContext(0)] (Recipe x) => ((Object)x).name == ((Object)recipe).name) == (Object)null) { if ((Object)(object)recipe.m_item != (Object)null) { ObjectDB.instance.m_recipes.Add(recipe); } } else { Debug.Log((object)("BalrondElvenFactionsReborn: " + ((Object)recipe).name + " - Recipe with this name already in the Game")); } } else { Debug.LogError((object)("BalrondElvenFactionsReborn: " + ((Object)recipe).name + " - Recipe not found")); } } private void AddItem(GameObject newPrefab) { if (!IsObjectDBValid()) { return; } ItemDrop component = newPrefab.GetComponent(); if ((Object)(object)component != (Object)null) { if ((Object)(object)ObjectDB.instance.GetItemPrefab(((Object)newPrefab).name) == (Object)null) { ObjectDB.instance.m_items.Add(newPrefab); Dictionary dictionary = (Dictionary)typeof(ObjectDB).GetField("m_itemByHash", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(ObjectDB.instance); dictionary[BalrondHashCompat.StableHash(((Object)newPrefab).name)] = newPrefab; } else { Debug.Log((object)("BalrondElvenFactionsReborn: " + ((Object)newPrefab).name + " - ItemDrop already exist")); } } } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class EffectListRef { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class EffectDataRef { public readonly string prefabName; public int variant; public bool attach; public bool follow; public bool inheritParentRotation; public bool inheritParentScale; public bool multiplyParentVisualScale; public bool randomRotation; public bool scale; public string childTransform = string.Empty; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private EffectData _data; public EffectDataRef(string prefabName) { this.prefabName = prefabName; } public EffectData ToEffectData() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown if (_data != null) { return _data; } GameObject prefab = Helpers.GetPrefab(prefabName); if (prefab == null) { ElvenNPCPlugin.LogError("Effect Data Reference invalid: " + prefabName); return new EffectData(); } _data = new EffectData { m_prefab = prefab, m_variant = variant, m_attach = attach, m_follow = follow, m_inheritParentRotation = inheritParentRotation, m_inheritParentScale = inheritParentScale, m_multiplyParentVisualScale = multiplyParentVisualScale, m_randomRotation = randomRotation, m_scale = scale, m_childTransform = childTransform }; return _data; } } public List dataRefs = new List(); private readonly List data = new List(); [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] private EffectList _effects; public EffectList Effects { get { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown if (_effects != null) { return _effects; } foreach (EffectDataRef dataRef in dataRefs) { data.Add(dataRef.ToEffectData()); } _effects = new EffectList(); _effects.m_effectPrefabs = data.ToArray(); return _effects; } } public GameObject[] Create(Vector3 basePos, Quaternion baseRot, [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] Transform baseParent = null, float scale = 1f, int variant = -1) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Effects.Create(basePos, baseRot, baseParent, scale, variant); } public EffectListRef(params string[] effects) { Add(effects); } public EffectListRef(params EffectDataRef[] refs) { dataRefs.AddRange(refs); } public EffectListRef() { } public void Add(params string[] effects) { foreach (string prefabName in effects) { dataRefs.Add(new EffectDataRef(prefabName)); } } public void Add(params EffectDataRef[] refs) { dataRefs.AddRange(refs); } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class Faction { public readonly string name; public int hash; private readonly bool friendly; public readonly bool targetTames = false; public readonly Faction faction; public float m_dayModifier = 1f; public float m_nightModifier = 1f; public readonly ConfigEntry isFriendly; public readonly ConfigEntry hoverColor; public Faction(string name, bool friendly, string HoverColor) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) this.name = name; this.friendly = friendly; hash = BalrondHashCompat.StableHash(name); faction = FactionManager.GetFaction(name); isFriendly = ConfigManager.config(name + " Faction", "Friendly", friendly ? Toggle.On : Toggle.Off, "If on, " + name + " are friendly unless aggravated"); hoverColor = ConfigManager.config(name + " Faction", "Hover Color", HoverColor, "Set hover color"); FactionManager.customFactions[faction] = this; } public bool IsFriendly() { return isFriendly.Value == Toggle.On; } public string GetHoverColorString() { return hoverColor.Value; } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static class FactionManager { public static readonly Dictionary customFactions; public static readonly Dictionary factions; static FactionManager() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown customFactions = new Dictionary(); factions = new Dictionary(); Harmony harmony = ElvenNPCPlugin.instance._harmony; harmony.Patch((MethodBase)AccessTools.Method(typeof(Enum), "GetValues", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(FactionManager), "Patch_Enum_GetValues", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(Enum), "GetNames", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(FactionManager), "Patch_Enum_GetNames", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(BaseAI), "IsEnemy", new Type[2] { typeof(Character), typeof(Character) }, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(FactionManager), "Patch_BaseAI_IsEnemy", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool Patch_BaseAI_IsEnemy(Character a, Character b, ref bool __result) { if (!(a is Elf) && !(b is Elf)) { return true; } __result = IsEnemy(a, b); return false; } public static bool IsEnemy(Character a, Character b) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)a == (Object)(object)b) { return false; } if (a is Elf elf) { return IsEnemy(elf, b); } if (b is Elf elf2) { return IsEnemy(elf2, a); } return a.GetFaction() != b.GetFaction(); } public static bool IsEnemy(Elf elf, Character character) { if (character is Elf b) { return IsEnemyToOtherViking(elf, b); } if (character.IsPlayer()) { return IsEnemyToPlayers(elf); } return IsEnemyToCreatures(elf, character); } public static bool IsEnemyToCreatures(Elf elf, Character character) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected I4, but got Unknown if (!customFactions.TryGetValue(((Character)elf).GetFaction(), out var value)) { return true; } bool flag = ((Character)elf).IsTamed(); bool flag2 = character.IsTamed(); if (flag && flag2) { return false; } Faction faction = character.GetFaction(); Faction val = faction; if ((int)val != 1) { switch (val - 8) { case 0: return flag; case 2: return character.m_baseAI.IsAggravated(); case 3: return false; default: { bool flag3 = Object.op_Implicit((Object)(object)((Component)character).GetComponent()); bool flag4 = character.m_baseAI.IsAlerted(); if (flag3) { return value.targetTames || flag4; } return true; } } } return !flag; } public static bool IsEnemyToPlayers(Elf elf) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 if (!customFactions.TryGetValue(((Character)elf).GetFaction(), out var value)) { return true; } if (((Character)elf).IsTamed()) { return false; } if (!value.IsFriendly()) { return true; } return ((BaseAI)elf.m_elfAI).m_aggravated && (int)elf.m_aggravatedReason != 1; } public static bool IsEnemyToOtherViking(Elf a, Elf b) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!customFactions.TryGetValue(((Character)a).GetFaction(), out var value)) { return true; } if (!customFactions.TryGetValue(((Character)b).GetFaction(), out var value2)) { return true; } if (((Character)a).IsTamed() && ((Character)b).IsTamed()) { return false; } return value != value2; } private static void Patch_Enum_GetValues(Type enumType, ref Array __result) { if (!(enumType != typeof(Faction)) && factions.Count != 0) { Faction[] array = (Faction[])(object)new Faction[__result.Length + factions.Count]; __result.CopyTo(array, 0); factions.Values.CopyTo(array, __result.Length); __result = array; } } private static void Patch_Enum_GetNames(Type enumType, ref string[] __result) { if (!(enumType != typeof(Faction)) && factions.Count != 0) { __result = CollectionExtensions.AddRangeToArray(__result, factions.Keys.ToArray()); } } public static Faction GetFaction(string name) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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) if (Enum.TryParse(name, ignoreCase: true, out Faction result)) { return result; } if (factions.TryGetValue(name, out result)) { return result; } Dictionary factionMap = GetFactionMap(); foreach (KeyValuePair item in factionMap) { if (item.Value == name) { result = item.Key; factions[name] = result; return result; } } result = (Faction)BalrondHashCompat.StableHash(name); factions[name] = result; return result; } private static Dictionary GetFactionMap() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) Array values = Enum.GetValues(typeof(Faction)); string[] names = Enum.GetNames(typeof(Faction)); Dictionary dictionary = new Dictionary(); for (int i = 0; i < values.Length; i++) { dictionary[(Faction)values.GetValue(i)] = names[i]; } return dictionary; } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static class Helpers { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] internal static ZNetScene _ZNetScene; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] internal static ObjectDB _ObjectDB; [return: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] internal static GameObject GetPrefab(string prefabName) { GameObject val = PrefabManager.PrefabsToRegister.Find((GameObject x) => ((Object)x).name == prefabName); if ((Object)(object)val != (Object)null) { return val; } if ((Object)(object)ObjectDB.instance != (Object)null) { GameObject val2 = ObjectDB.instance.m_items.Find([NullableContext(0)] (GameObject x) => ((Object)x).name == prefabName); if ((Object)(object)val2 != (Object)null) { return val2; } } if ((Object)(object)_ZNetScene == (Object)null) { Debug.LogWarning((object)"ZnetScene is null"); return null; } GameObject val3 = _ZNetScene.m_prefabs.Find([NullableContext(0)] (GameObject prefab) => ((Object)prefab).name == prefabName); if ((Object)(object)val3 != (Object)null) { return val3; } GameObject value; return CloneManager.clones.TryGetValue(prefabName, out value) ? value : val3; } public static void Add<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] T>(this List list, params T[] values) { list.AddRange(values); } public static void Remove<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] T>(this GameObject prefab) where T : Component { T val = default(T); if (prefab.TryGetComponent(ref val)) { Object.Destroy((Object)(object)val); } } public static void AddRange<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] T, [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] V>(this Dictionary dict, Dictionary other) { foreach (KeyValuePair item in other) { dict[item.Key] = item.Value; } } public static void ClearEquipment(this VisEquipment visEq) { ZDO zDO = visEq.m_nview.GetZDO(); if (zDO != null) { zDO.Set(ZDOVars.s_leftItem, 0, false); zDO.Set(ZDOVars.s_rightItem, 0, false); zDO.Set(ZDOVars.s_chestItem, 0, false); zDO.Set(ZDOVars.s_legItem, 0, false); zDO.Set(ZDOVars.s_helmetItem, 0, false); zDO.Set(ZDOVars.s_shoulderItem, 0, false); zDO.Set(ZDOVars.s_utilityItem, 0, false); zDO.Set(ZDOVars.s_trinketItem, 0, false); visEq.m_leftItem = ""; visEq.m_rightItem = ""; visEq.m_chestItem = ""; visEq.m_legItem = ""; visEq.m_helmetItem = ""; visEq.m_shoulderItem = ""; visEq.m_utilityItem = ""; visEq.m_trinketItem = ""; } } public static void CopyFieldsFrom<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] T, [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] V>(this T target, V source) where T : Humanoid where V : Humanoid { Dictionary dictionary = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToDictionary([NullableContext(0)] (FieldInfo f) => f.Name); FieldInfo[] fields = typeof(V).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { if (dictionary.TryGetValue(fieldInfo.Name, out var value) && value.FieldType.IsAssignableFrom(fieldInfo.FieldType)) { value.SetValue(target, fieldInfo.GetValue(source)); } } } public static void Copy<[<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] T>(this T target, T source) { FieldInfo[] fields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { object value = fieldInfo.GetValue(source); if (value != null) { fieldInfo.SetValue(target, value); } } } public static bool IsItemBetter(this ItemData item, ItemData other) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected I4, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Invalid comparison between Unknown and I4 //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Invalid comparison between Unknown and I4 SkillType skillType = item.m_shared.m_skillType; SkillType val = skillType; if ((int)val != 7) { if ((int)val == 12 && (int)other.m_shared.m_skillType == 12) { goto IL_003d; } } else if ((int)other.m_shared.m_skillType == 7) { goto IL_003d; } ItemType itemType = item.m_shared.m_itemType; ItemType val2 = itemType; switch (val2 - 3) { default: if ((int)val2 != 22) { if ((int)val2 != 24) { break; } return item.m_shared.m_maxAdrenaline < other.m_shared.m_maxAdrenaline; } goto case 0; case 12: return false; case 0: case 1: case 6: case 9: case 11: { DamageTypes damage = item.GetDamage(); float totalDamage = ((DamageTypes)(ref damage)).GetTotalDamage(); damage = other.GetDamage(); return totalDamage < ((DamageTypes)(ref damage)).GetTotalDamage(); } case 2: return item.m_shared.m_blockPower < other.m_shared.m_blockPower; case 3: case 4: case 5: case 7: case 8: case 10: break; } return item.GetArmor() < other.GetArmor(); IL_003d: return item.m_shared.m_toolTier < other.m_shared.m_toolTier; } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class Elven { public GameObject Prefab = null; public readonly string name; private bool Loaded; public Elf m_elf = null; public ElfAI m_ai = null; public readonly Faction faction; public List defaultItems = new List(); public List randomArmors = new List(); public List randomWeapon = new List(); public List randomShield = new List(); public readonly Biome biome; public readonly NorsemanConfigs configs; public readonly SpawnManager.SpawnInfo spawnInfo; public float baseHealth = 50f; public float baseArmor = 0f; public string Music = ""; public int modelIndex = 0; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] [method: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] [field: <0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] public event Action OnCreated; public void SetupConfigs() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown configs.baseHealth = ConfigManager.config(name, "Base Health", baseHealth, new ConfigDescription("Set base health", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 1000f), Array.Empty())); ((Character)m_elf).m_health = configs.baseHealth.Value; spawnInfo.SetupConfigs(); configs.baseArmor = ConfigManager.config(name, "Base Armor", baseArmor, "Set base armor"); configs.drops = ConfigManager.config(name, "Items", "Coins:50:100:0.5,Wood:25:50:0.5", "Set drops"); } public Elven(Biome biome, string name, Faction faction) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) this.biome = biome; this.name = name; this.faction = faction; configs = new NorsemanConfigs(name); spawnInfo = new SpawnManager.SpawnInfo(this) { m_spawnInterval = 1000f, m_spawnDistance = 50f, m_maxLevel = 3, m_minAltitude = 10f, m_spawnChance = 5f }; PrefabManager.Norsemen.Add(this); } internal void Create(string factionName) { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Expected O, but got Unknown //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Expected O, but got Unknown //IL_0307: Unknown result type (might be due to invalid IL or missing references) if (!Loaded) { GameObject val = ElvenNPCPlugin.elfTemplate1; if (factionName == "DrowElf") { val = ElvenNPCPlugin.elfTemplateDrow; } if (factionName == "HighElf") { val = ElvenNPCPlugin.elfTemplateHigh; } if (factionName == "TreeElf") { val = ElvenNPCPlugin.elfTemplateTree; } Player component = val.GetComponent(); Prefab = Object.Instantiate(val, CloneManager.GetRootTransform(), false); ((SpawnData)spawnInfo).m_prefab = Prefab; ((Object)Prefab).name = name; Prefab.Remove(); Prefab.GetComponent().m_persistent = true; m_elf = Prefab.AddComponent(); m_elf.CopyFieldsFrom(component); ((Character)m_elf).m_eye = Utils.FindChild(Prefab.transform, "EyePos", (IterativeSearchType)0); ((Character)m_elf).m_faction = faction.faction; ((Character)m_elf).m_health = 50f; m_elf.m_modelIndex = modelIndex; ((Character)m_elf).m_bossEvent = Music; if (defaultItems.Count > 0) { ((Humanoid)m_elf).m_defaultItems = defaultItems.Select(Helpers.GetPrefab).ToArray(); } if (randomArmors.Count > 0) { ((Humanoid)m_elf).m_randomArmor = randomArmors.Select(Helpers.GetPrefab).ToArray(); } if (randomWeapon.Count > 0) { ((Humanoid)m_elf).m_randomWeapon = randomWeapon.Select(Helpers.GetPrefab).ToArray(); } if (randomShield.Count > 0) { ((Humanoid)m_elf).m_randomShield = randomShield.Select(Helpers.GetPrefab).ToArray(); } ((Character)m_elf).m_name = "$enemy_elf_rs"; m_ai = Prefab.AddComponent(); ((MonsterAI)m_ai).m_attackPlayerObjects = false; ((BaseAI)m_ai).m_aggravatable = true; ((BaseAI)m_ai).m_passiveAggresive = true; ((BaseAI)m_ai).m_avoidWater = true; ((BaseAI)m_ai).m_alertedEffects.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { new EffectData { m_prefab = Helpers.GetPrefab("sfx_dverger_vo_alerted") } }; ((BaseAI)m_ai).m_idleSound.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { new EffectData { m_prefab = Helpers.GetPrefab("sfx_dverger_vo_idle") } }; ((BaseAI)m_ai).m_idleSoundInterval = 20f; ((BaseAI)m_ai).m_idleSoundChance = 0.5f; ((BaseAI)m_ai).m_pathAgentType = (AgentType)6; ((BaseAI)m_ai).m_moveMinAngle = 90f; ((BaseAI)m_ai).m_smoothMovement = true; ((BaseAI)m_ai).m_randomCircleInterval = 2f; ((BaseAI)m_ai).m_randomMoveInterval = 15f; ((BaseAI)m_ai).m_randomMoveRange = 20f; ((BaseAI)m_ai).m_skipLavaTargets = true; ((BaseAI)m_ai).m_avoidLava = true; ((BaseAI)m_ai).m_avoidLavaFlee = true; ((BaseAI)m_ai).m_avoidFire = true; ((BaseAI)m_ai).m_fleeRange = 25f; ((BaseAI)m_ai).m_fleeAngle = 45f; ((BaseAI)m_ai).m_fleeInterval = 2f; ((MonsterAI)m_ai).m_alertRange = 20f; ((MonsterAI)m_ai).m_fleeIfHurtWhenTargetCantBeReached = true; ((MonsterAI)m_ai).m_fleeUnreachableSinceAttacking = 30f; ((MonsterAI)m_ai).m_fleeUnreachableSinceHurt = 30f; ((MonsterAI)m_ai).m_fleeIfLowHealth = 0.2f; ((MonsterAI)m_ai).m_fleeTimeSinceHurt = 20f; ((MonsterAI)m_ai).m_fleeInLava = true; ((MonsterAI)m_ai).m_circulateWhileCharging = true; ((MonsterAI)m_ai).m_privateAreaTriggerTreshold = 4; ((MonsterAI)m_ai).m_interceptTimeMax = 2f; ((MonsterAI)m_ai).m_interceptTimeMin = 0f; ((MonsterAI)m_ai).m_maxChaseDistance = 200f; ((MonsterAI)m_ai).m_minAttackInterval = 1.5f; ((MonsterAI)m_ai).m_circleTargetInterval = 8f; ((MonsterAI)m_ai).m_circleTargetDuration = 6f; ((MonsterAI)m_ai).m_circleTargetDistance = 8f; ((MonsterAI)m_ai).m_consumeRange = 1f; ((MonsterAI)m_ai).m_consumeSearchRange = 10f; ((MonsterAI)m_ai).m_consumeSearchInterval = 10f; ((BaseAI)m_ai).m_patrol = true; SetupConfigs(); this.OnCreated?.Invoke(this); CloneManager.norsemen[((Object)Prefab).name] = Prefab; PrefabManager.RegisterPrefab(Prefab); Loaded = true; } } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class NorsemanConfigs { public static readonly Dictionary configs = new Dictionary(); public ConfigEntry baseHealth = null; public ConfigEntry baseArmor = null; public ConfigEntry drops = null; public float BaseHealth => baseHealth.Value; public float BaseArmor => baseArmor.Value; public NorsemanConfigs(string vikingName) { configs[vikingName] = this; } public void AddLoot(Inventory inventory) { if (string.IsNullOrEmpty(drops.Value)) { return; } string[] array = drops.Value.Split(new char[1] { ',' }); string[] array2 = array; foreach (string text in array2) { string[] array3 = text.Split(new char[1] { ':' }); if (array3.Length == 4) { string text2 = array3[0].Trim(); int result; int num = ((!int.TryParse(array3[1].Trim(), out result)) ? 1 : result); int result2; int num2 = ((!int.TryParse(array3[2].Trim(), out result2)) ? 1 : result2); float result3; float num3 = (float.TryParse(array3[3].Trim(), out result3) ? result3 : 1f); float value = Random.value; if (num3 > value) { inventory.AddItem(text2, Random.Range(num, num2), 1, 0, 0L, "", false); } } } } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [PublicAPI] public static class PrefabManager { [NullableContext(0)] [HarmonyPriority(700)] [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_Patch { public static void Postfix() { if (IsObjectDBValid()) { DatabaseAddMethods.AddItems(PrefabsToRegister); } } } [NullableContext(0)] [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] [HarmonyPriority(700)] public static class Object_CopyOtherDB_Patch { public static void Postfix() { if (IsObjectDBValid()) { DatabaseAddMethods.AddItems(PrefabsToRegister); } } } internal static List PrefabsToRegister; internal static List Clones; internal static List Norsemen; internal static DatabaseAddMethods DatabaseAddMethods; static PrefabManager() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown PrefabsToRegister = new List(); Clones = new List(); Norsemen = new List(); DatabaseAddMethods = new DatabaseAddMethods(); Harmony harmony = ElvenNPCPlugin.instance._harmony; harmony.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PrefabManager), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PrefabManager), "Patch_ZNetScene_Awake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } [NullableContext(2)] public static void RegisterPrefab(GameObject prefab) { if (!((Object)(object)prefab == (Object)null)) { PrefabsToRegister.Add(prefab); } } public static void RegisterPrefab(string assetBundleName, string prefabName) { RegisterPrefab(AssetBundleManager.LoadAsset(assetBundleName, prefabName)); } public static void RegisterPrefab(AssetBundle assetBundle, string prefabName) { RegisterPrefab(assetBundle.LoadAsset(prefabName)); } [HarmonyPriority(700)] internal static void Patch_ZNetScene_Awake(ZNetScene __instance) { foreach (GameObject item in PrefabsToRegister) { if (Object.op_Implicit((Object)(object)item.GetComponent())) { __instance.m_prefabs.Add(item); } } ShaderReplacment.runMaterialFix(); } [HarmonyPriority(100)] internal static void Patch_FejdStartup(FejdStartup __instance) { Helpers._ZNetScene = __instance.m_objectDBPrefab.GetComponent(); Helpers._ObjectDB = __instance.m_objectDBPrefab.GetComponent(); CustomizationManager.GetHairAndBeards(Helpers._ObjectDB); foreach (Clone clone in Clones) { clone.Create(); } foreach (Elven norseman in Norsemen) { norseman.Create(norseman.faction.name); } ConfigManager.SetupWatcher(); } private static bool IsObjectDBValid() { ObjectDB instance = ObjectDB.instance; return (Object)(object)instance != (Object)null && instance.m_items.Count != 0 && instance.m_recipes.Count != 0 && (Object)(object)instance.GetItemPrefab("Amber") != (Object)null; } public static void FixTemplateNpc(GameObject prefab) { Player component = prefab.GetComponent(); Humanoid target = prefab.AddComponent(); target.CopyFieldsFrom(component); prefab.Remove(); prefab.GetComponent().m_persistent = true; } } public enum Toggle { On = 1, Off = 0 } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [BepInPlugin("balrond.astafaraios.BalrondElvenFactionsReborn", "BalrondElvenFactionsReborn", "0.1.4")] public class ElvenNPCPlugin : BaseUnityPlugin { internal const string ModName = "BalrondElvenFactionsReborn"; internal const string ModVersion = "0.1.4"; internal const string Author = "balrond.astafaraios"; public const string ModGUID = "balrond.astafaraios.BalrondElvenFactionsReborn"; public static string ConnectionError = ""; public readonly Harmony _harmony = new Harmony("balrond.astafaraios.BalrondElvenFactionsReborn"); public static readonly ManualLogSource ElvenNPCLogger = Logger.CreateLogSource("BalrondElvenFactionsReborn"); public static ElvenNPCPlugin instance = null; public static ConfigEntry _envOverride = null; public static GameObject RS_HelmetDrowElfRogue = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "RS_HelmetDrowElfRogue"); public static GameObject RS_HelmetHighElfCommander = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "RS_HelmetHighElfCommander"); public static GameObject dwarfTemplate1 = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "DwarfT1"); public static GameObject elfTemplate1 = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "Template_Elf_Base_bal"); public static GameObject elfTemplateDrow = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "Templete_Elf_Drow_bal"); public static GameObject elfTemplateHigh = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "Templete_Elf_High_bal"); public static GameObject elfTemplateTree = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "Templete_Elf_Tree_bal"); public static GameObject elfNpcTemplateDrow = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcTemplete_Elf_Drow_bal"); public static GameObject elfNpcTemplateHigh = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcTemplete_Elf_High_bal"); public static GameObject elfNpcTemplateTree = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcTemplete_Elf_Tree_bal"); public static GameObject elfNpcTemplateDrowFemale = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcTemplete_Elf_DrowFemale_bal"); public static GameObject elfNpcTemplateHighFemale = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcTemplete_Elf_HighFemale_bal"); public static GameObject elfNpcTemplateTreeFemale = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcTemplete_Elf_TreeFemale_bal"); public static GameObject elfTemplateRagdoll = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "Template_Elf_base_ragdoll_bal"); public static GameObject elfTemplateDrowRagdoll = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "Template_Elf_drow_ragdoll_bal"); public static GameObject elfTemplateHighRagdoll = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "Template_Elf_high_ragdoll_bal"); public static GameObject elfTemplateTreeRagdoll = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "Template_Elf_tree_ragdoll_bal"); public static GameObject armorElfHighHeavy = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcArmorHighElfHeavyChest_bal"); public static GameObject armorElfHighRanger = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcArmorHighElfRangerChest_bal"); public static GameObject armorElfHighLegs = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcArmorHighElfRangerLegs_bal"); public static GameObject armorElfHighHelmet = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "HelmetHighElf_bal"); public static GameObject armorElfHighHelmet2 = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "HelmetHighElfHood_bal"); public static GameObject armorElfHighCape = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "CapeHighElf_bal"); public static GameObject armorElfDrowHeavy = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcArmorDrowElfHeavyChest_bal"); public static GameObject armorElfDrowRanger = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcArmorDrowElfRangerChest_bal"); public static GameObject armorElfDrowLegs = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcArmorDrowElfRangerLegs_bal"); public static GameObject armorElfDrowLegs2 = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "NpcArmorDrowElfPlateLegs_bal"); public static GameObject armorElfDrowHelmet = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "HelmetDrowElf_bal"); public static GameObject armorElfDrowHelmet2 = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "HelmetDrowElfHood_bal"); public static GameObject armorElfDrowHelmet3 = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "HelmetDrowElfHood2_bal"); public static GameObject armorElfDrowCape = AssetBundleManager.LoadAsset("balrondplainwalkerselfsnpc", "CapeDrow_bal"); public static List highHelmets = new List { "", "HelmetHighElfHood_bal", "HelmetTrollLeather", "HelmetDverger", "HelmetLeather", "" }; public static List highWeapon = new List { "SwordBronze", "SwordMistwalker", "KnifeCopper", "MaceSilver", "AxeBerzerkrLightning", "AxeJotunBane", "BattleaxeCrystal", "SpearSplitner_Lightning", "StaffIceShards" }; public static List highShields = new List { "", "ShieldBronzeBuckler", "ShieldSerpentscale", "ShieldSilver", "", "ShieldBronzeBuckler", "ShieldSerpentscale", "ShieldSilver" }; public static List highItemSet1 = new List { "NpcArmorHighElfRangerLegs_bal", "NpcArmorHighElfRangerChest_bal", "BowAshlandsStorm", "CapeTrollHide" }; public static List highItemSet2 = new List { "HelmetHighElf_bal", "NpcArmorHighElfRangerLegs_bal", "NpcArmorHighElfHeavyChest_bal", "CrossbowRipperLightning", "CapeHighElf_bal" }; public static List[] highItemSetArray = new List[2] { highItemSet1, highItemSet2 }; public static List drowHelmets = new List { "", "HelmetMage", "HelmetOdin", "HelmetSweatBand", "HelmetDrowElfHood_bal", "HelmetDrowElfHood2_bal", "" }; public static List drowWeapon = new List { "SwordBlackmetal", "KnifeBlackMetal", "MaceNeedle", "AxeBlackMetal", "AxeBerzerkrBlood", "BattleaxeBlackmetal", "SpearSplitner_Blood", "StaffFireball" }; public static List drowShields = new List { "", "ShieldFlametal", "ShieldFlametalTower", "ShieldBoneTower", "", "ShieldFlametal", "ShieldFlametalTower", "ShieldBoneTower" }; public static List drowItemSet1 = new List { "NpcArmorDrowElfRangerLegs_bal", "NpcArmorDrowElfRangerChest_bal", "BowAshlandsBlood", "CapeDrow_bal" }; public static List drowItemSet2 = new List { "HelmetDrowElf_bal", "NpcArmorDrowElfPlateLegs_bal", "NpcArmorDrowElfHeavyChest_bal", "CrossbowRipperBlood", "CapeOdin" }; public static List[] drowItemSetArray = new List[2] { drowItemSet1, drowItemSet2 }; private static void InitConfigs() { _envOverride = ConfigManager.config("2 - Settings", "Banner Environments", Toggle.Off, "If on, when banners are on, they override the local environment"); } public static void LogDebug(string msg) { if (ConfigManager.ShouldLog(ConfigManager.LogLevel.Debug)) { ElvenNPCLogger.LogDebug((object)msg); } } public static void LogError(string msg) { if (ConfigManager.ShouldLog(ConfigManager.LogLevel.Error)) { ElvenNPCLogger.LogError((object)msg); } } public static void LogWarning(string msg) { if (ConfigManager.ShouldLog(ConfigManager.LogLevel.Warning)) { ElvenNPCLogger.LogWarning((object)msg); } } public static void LogInfo(string msg) { if (ConfigManager.ShouldLog(ConfigManager.LogLevel.Info)) { ElvenNPCLogger.LogInfo((object)msg); } } public void Awake() { instance = this; preparePrefab(RS_HelmetDrowElfRogue); preparePrefab(RS_HelmetHighElfCommander); ShaderReplacment.Replace(dwarfTemplate1); preparePrefab(dwarfTemplate1); ShaderReplacment.Replace(elfTemplate1); ShaderReplacment.Replace(elfTemplateDrow); ShaderReplacment.Replace(elfTemplateHigh); ShaderReplacment.Replace(elfTemplateTree); preparePrefab(elfTemplateRagdoll); preparePrefab(elfTemplateDrowRagdoll); preparePrefab(elfTemplateHighRagdoll); preparePrefab(elfTemplateTreeRagdoll); PrefabManager.FixTemplateNpc(elfNpcTemplateDrow); PrefabManager.FixTemplateNpc(elfNpcTemplateHigh); PrefabManager.FixTemplateNpc(elfNpcTemplateTree); PrefabManager.FixTemplateNpc(elfNpcTemplateDrowFemale); PrefabManager.FixTemplateNpc(elfNpcTemplateHighFemale); PrefabManager.FixTemplateNpc(elfNpcTemplateTreeFemale); preparePrefab(elfNpcTemplateDrow); preparePrefab(elfNpcTemplateHigh); preparePrefab(elfNpcTemplateTree); preparePrefab(elfNpcTemplateDrowFemale); preparePrefab(elfNpcTemplateHighFemale); preparePrefab(elfNpcTemplateTreeFemale); preparePrefab(armorElfHighHeavy); preparePrefab(armorElfHighRanger); preparePrefab(armorElfHighLegs); preparePrefab(armorElfHighHelmet); preparePrefab(armorElfHighHelmet2); preparePrefab(armorElfHighCape); preparePrefab(armorElfDrowHeavy); preparePrefab(armorElfDrowRanger); preparePrefab(armorElfDrowLegs); preparePrefab(armorElfDrowLegs2); preparePrefab(armorElfDrowHelmet); preparePrefab(armorElfDrowHelmet2); preparePrefab(armorElfDrowHelmet3); preparePrefab(armorElfDrowCape); SetupElves(); SetupMusic(); SetupBanners(); InitConfigs(); NameGenerator.Setup(); TalkManager.Setup(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); } private static void preparePrefab(GameObject prefab) { PrefabManager.RegisterPrefab(prefab); ShaderReplacment.Replace(prefab); } private static void SetupElves() { Faction faction = new Faction("DrowElf", friendly: true, "#7130aa"); faction.m_dayModifier = 1.1f; Faction faction2 = new Faction("HighElf", friendly: true, "#33e6ff"); faction2.m_nightModifier = 1.1f; Faction faction3 = new Faction("TreeElf", friendly: true, "#e69138"); faction3.m_nightModifier = 1.1f; CreateDrows(faction); CreateHighElves(faction2); CreateTreeElves(faction3); } private static void CreateTreeElves(Faction TreeFaction) { Elven elven = new Elven((Biome)537, "TreeElfFemale_1", TreeFaction); elven.defaultItems.Add("ArmorRootLegs", "ArmorRootChest", "BowAshlandsRoot", "CapeAsksvin"); elven.randomArmors.Add("HelmetTrollLeather", "", ""); elven.randomWeapon.Add("MaceBronze", "SwordNiedhoggNature", "SpearElderbark", "AxeBerzerkrNature", "SledgeStagbreaker", "StaffGreenRoots"); elven.randomShield.Add("ShieldWood", "ShieldWoodTower", ""); elven.Music = "TreeElvesFortress"; elven.modelIndex = 1; Elven elven2 = new Elven((Biome)537, "TreeElfMale_1", TreeFaction); elven2.defaultItems.Add("ArmorRootLegs", "ArmorRootChest", "BowAshlandsRoot", "CapeAsksvin"); elven2.randomArmors.Add("HelmetTrollLeather", "", ""); elven2.randomWeapon.Add("MaceBronze", "SwordNiedhoggNature", "SpearElderbark", "AxeBerzerkrNature", "SledgeStagbreaker", "StaffGreenRoots"); elven2.randomShield.Add("ShieldWood", "ShieldWoodTower", ""); elven2.Music = "TreeElvesFortress"; elven2.modelIndex = 0; } private static void CreateHighElves(Faction HighFaction) { CreateElfBase("HighElfFemale_1", HighFaction, "HighElvesFortress", 1); CreateElfBase("HighElfMale_1", HighFaction, "HighElvesFortress"); CreateElfBase("HighElfFemale_2", HighFaction, "HighElvesFortress", 1, 1); CreateElfBase("HighElfMale_2", HighFaction, "HighElvesFortress", 0, 1); } private static void CreateDrows(Faction DrowFaction) { CreateElfBase("DrowElfFemale_1", DrowFaction, "DarkElvesFortress", 1); CreateElfBase("DrowElfMale_1", DrowFaction, "DarkElvesFortress"); CreateElfBase("DrowElfFemale_2", DrowFaction, "DarkElvesFortress", 1, 1); CreateElfBase("DrowElfMale_2", DrowFaction, "DarkElvesFortress", 0, 1); } private static void CreateElfBase(string prefabName, Faction faction, string music, int gender = 0, int itemset = 0) { Elven elven = new Elven((Biome)639, prefabName, faction); if (faction.name == "DrowElf") { elven.defaultItems = drowItemSetArray[itemset]; elven.randomArmors = drowHelmets; elven.randomWeapon = drowWeapon; elven.randomShield = drowShields; } if (faction.name == "HighElf") { elven.defaultItems = highItemSetArray[itemset]; elven.randomArmors = highHelmets; elven.randomWeapon = highWeapon; elven.randomShield = highShields; } if (faction.name == "TreeElf") { elven.defaultItems = drowItemSetArray[itemset]; elven.randomArmors = drowHelmets; elven.randomWeapon = drowWeapon; elven.randomShield = drowShields; } elven.Music = music; elven.modelIndex = gender; } private static void SetupMusic() { MusicManager.Music music = new MusicManager.Music("Dark_Elves_Fortress_Theme", "DarkElvesFortress", AssetBundleManager.GetAssetBundle("balrondplainwalkerselfsnpc")); music.SetEnvironmentCopy("Fader"); music.m_loop = true; MusicManager.Music music2 = new MusicManager.Music("High_Elf_Fortress_Theme", "HighElvesFortress", AssetBundleManager.GetAssetBundle("balrondplainwalkerselfsnpc")); music2.m_loop = true; MusicManager.Music music3 = new MusicManager.Music("Wood_Elf_Theme", "TreeElvesFortress", AssetBundleManager.GetAssetBundle("balrondplainwalkerselfsnpc")); music3.SetEnvironmentCopy("Clear"); music3.m_loop = true; } private static void SetupBanners() { BuildPiece buildpiece = new BuildPiece(AssetBundleManager.GetAssetBundle("balrondplainwalkerselfsnpc"), "DrowBannerPost_RS"); setupVFX("Drow Elf Banner", buildpiece); BuildPiece buildpiece2 = new BuildPiece(AssetBundleManager.GetAssetBundle("balrondplainwalkerselfsnpc"), "HighBannerPost_RS"); setupVFX("High Elf Banner", buildpiece2); BuildPiece buildpiece3 = new BuildPiece(AssetBundleManager.GetAssetBundle("balrondplainwalkerselfsnpc"), "TreeBannerPost_RS"); setupVFX("Tree Elf Banner", buildpiece3); } private static void setupVFX(string name, BuildPiece buildpiece) { buildpiece.Prefab.GetComponent().m_name = name; buildpiece.PlaceEffects.Add("vfx_Place_workbench"); buildpiece.PlaceEffects.Add("sfx_build_hammer_wood"); buildpiece.DestroyedEffects.Add("vfx_SawDust"); buildpiece.DestroyedEffects.Add("sfx_wood_destroyed"); buildpiece.HitEffects.Add("vfx_SawDust"); buildpiece.Prefab.AddComponent(); buildpiece.Category.Set(BuildPieceCategory.Furniture); buildpiece.SpecialProperties = new SpecialProperties { AdminOnly = true }; } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] public static class RegisterAndCheckVersion { [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 ElvenNPCPlugin.ElvenNPCLogger.LogDebug((object)"Registering version RPC handler"); peer.m_rpc.Register("BalrondElvenFactionsReborn_VersionCheck", (Action)RpcHandlers.RPC_ElvenNPC_Version); ElvenNPCPlugin.ElvenNPCLogger.LogInfo((object)"Invoking version check"); ZPackage val = new ZPackage(); val.Write("0.1.4"); peer.m_rpc.Invoke("BalrondElvenFactionsReborn_VersionCheck", new object[1] { val }); } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [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; } ElvenNPCPlugin.ElvenNPCLogger.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(), "BalrondElvenFactionsRebornRequestAdminSync", new object[1] { (object)new ZPackage() }); } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] public class ShowConnectionError { [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" + ElvenNPCPlugin.ConnectionError; } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] public static class RemoveDisconnectedPeerFromVerified { [NullableContext(1)] private static void Prefix(ZNetPeer peer, ref ZNet __instance) { if (__instance.IsServer()) { ElvenNPCPlugin.ElvenNPCLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list")); RpcHandlers.ValidatedPeers.Remove(peer.m_rpc); } } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static class RpcHandlers { public static readonly List ValidatedPeers = new List(); public static void RPC_ElvenNPC_Version(ZRpc rpc, ZPackage pkg) { string text = pkg.ReadString(); ElvenNPCPlugin.ElvenNPCLogger.LogInfo((object)("Version check, local: 0.1.4, remote: " + text)); if (text != "0.1.4") { ElvenNPCPlugin.ConnectionError = "BalrondElvenFactionsReborn Installed: 0.1.4\n Needed: " + text; if (ZNet.instance.IsServer()) { ElvenNPCPlugin.ElvenNPCLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting...")); rpc.Invoke("Error", new object[1] { 3 }); } } else if (!ZNet.instance.IsServer()) { ElvenNPCPlugin.ElvenNPCLogger.LogInfo((object)"Received same version from server!"); } else { ElvenNPCPlugin.ElvenNPCLogger.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 ElvenNPC.Managers { [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static class EmbeddedResourceManager { private static readonly Assembly asm = typeof(EmbeddedResourceManager).Assembly; public static string GetFile(string fileName, string directory = "Files") { string suffix = "." + directory + "." + fileName; string text = asm.GetManifestResourceNames().FirstOrDefault([NullableContext(0)] (string n) => n.EndsWith(suffix, StringComparison.Ordinal)); if (text == null) { throw new FileNotFoundException("Embedded resource '" + suffix + "' not found. Available: " + string.Join(", ", asm.GetManifestResourceNames())); } using Stream stream = asm.GetManifestResourceStream(text); if (stream == null) { throw new FileNotFoundException("Embedded resource stream '" + text + "' could not be opened."); } using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } } [NullableContext(1)] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public static class NameGenerator { [Serializable] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class Names { private static readonly Random rng = new Random(); public List MaleNames = new List(); public List FemaleNames = new List(); public string GenerateMaleName() { return names.MaleNames[rng.Next(names.MaleNames.Count)]; } public string GenerateFemaleName() { return names.FemaleNames[rng.Next(names.FemaleNames.Count)]; } } public static Names names = new Names(); public static CustomSyncedValue sync = new CustomSyncedValue(ConfigManager.ConfigSync, "RustyMods.ElvenNPC.Names.Sync", ""); public static string FileName = "Names.yml"; public static string FilePath = Path.Combine(ConfigManager.DirectoryPath, FileName); public static void Setup() { GetOrSerialize(); SetupFileWatcher(); sync.ValueChanged += OnConfigChange; } public static void SetupFileWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(ConfigManager.DirectoryPath, FileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } public static void OnConfigChange() { if (!Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.IsServer()) { return; } string value = sync.Value; if (!string.IsNullOrEmpty(value)) { Names names = ConfigManager.deserializer.Deserialize(value); if (names.MaleNames.Count > 0) { NameGenerator.names.MaleNames = names.MaleNames; } if (names.FemaleNames.Count > 0) { NameGenerator.names.FemaleNames = names.FemaleNames; } } } public static void ReadConfigValues(object sender, FileSystemEventArgs e) { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { Read(); UpdateSync(ZNet.instance); ElvenNPCPlugin.LogDebug(FileName + " changed"); } } public static void UpdateSync(ZNet net) { if (net.IsServer()) { string value = ConfigManager.serializer.Serialize((object)names); sync.Value = value; } } public static void GetOrSerialize() { if (File.Exists(FilePath)) { Read(); return; } string file = EmbeddedResourceManager.GetFile("Names.yml"); names = ConfigManager.deserializer.Deserialize(file); File.WriteAllText(FilePath, file); } public static void Read() { try { string text = File.ReadAllText(FilePath); Names names = ConfigManager.deserializer.Deserialize(text); if (names.MaleNames.Count > 0) { NameGenerator.names.MaleNames = names.MaleNames; } if (names.FemaleNames.Count > 0) { NameGenerator.names.FemaleNames = names.FemaleNames; } } catch { ElvenNPCPlugin.LogError("Failed to deserialize " + FileName); } } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public static class SpawnManager { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class SpawnInfo : SpawnData { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] public class Configs { public ConfigEntry Enabled = null; public ConfigEntry Biome = null; public ConfigEntry Area = null; public ConfigEntry MaxSpawned = null; public ConfigEntry Interval = null; public ConfigEntry Chance = null; public ConfigEntry Distance = null; public ConfigEntry RequiredKey = null; public ConfigEntry RequiredEnvs = null; public ConfigEntry TOD = null; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] public ConfigEntry Altitude; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(2)] public ConfigEntry Forest; [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 2, 1 })] public ConfigEntry Level; } [NullableContext(0)] public enum TimeOfDay { Both, Night, Day } [NullableContext(0)] public enum Region { Both, InForest, OutForest } private readonly string PrefabName; public readonly Biome Biome; public readonly Configs configs; [NullableContext(2)] private void ConfigChanged(object o, EventArgs e) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) base.m_enabled = configs.Enabled.Value == Toggle.On; base.m_biome = configs.Biome.Value; base.m_biomeArea = configs.Area.Value; base.m_maxSpawned = configs.MaxSpawned.Value; base.m_spawnInterval = configs.Interval.Value; base.m_spawnChance = configs.Chance.Value; base.m_spawnDistance = configs.Distance.Value; base.m_requiredGlobalKey = configs.RequiredKey.Value; base.m_requiredEnvironments = new EnvList(configs.RequiredEnvs.Value).GetValidatedList(); TimeOfDay value = configs.TOD.Value; base.m_spawnAtDay = value == TimeOfDay.Both || value == TimeOfDay.Day; value = configs.TOD.Value; base.m_spawnAtNight = value == TimeOfDay.Both || value == TimeOfDay.Night; base.m_minAltitude = ((configs.Altitude != null) ? new MinMax(configs.Altitude.Value).Min : (-1000f)); base.m_maxAltitude = ((configs.Altitude != null) ? new MinMax(configs.Altitude.Value).Max : 1000f); int inForest; if (configs.Forest != null) { Region value2 = configs.Forest.Value; inForest = ((value2 == Region.Both || value2 == Region.InForest) ? 1 : 0); } else { inForest = 1; } base.m_inForest = (byte)inForest != 0; int outsideForest; if (configs.Forest != null) { Region value2 = configs.Forest.Value; outsideForest = ((value2 == Region.Both || value2 == Region.OutForest) ? 1 : 0); } else { outsideForest = 1; } base.m_outsideForest = (byte)outsideForest != 0; base.m_minLevel = ((configs.Level == null) ? 1 : new Level(configs.Level.Value).Min); base.m_maxLevel = ((configs.Level == null) ? 1 : new Level(configs.Level.Value).Max); base.m_overrideLevelupChance = ((configs.Level != null) ? new Level(configs.Level.Value).Chance : 0f); } public void SetupConfigs() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Expected O, but got Unknown //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Expected O, but got Unknown //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Expected O, but got Unknown configs.Enabled = ConfigManager.config(PrefabName, "Enabled", Toggle.On, "If on, viking can spawn"); configs.Enabled.SettingChanged += ConfigChanged; configs.Biome = ConfigManager.config(PrefabName, "Biome", Biome, "Set biomes viking can spawn in"); configs.Biome.SettingChanged += ConfigChanged; configs.Area = ConfigManager.config(PrefabName, "Biome Area", (BiomeArea)3, "Set particular part of biome viking can spawn in"); configs.Area.SettingChanged += ConfigChanged; configs.MaxSpawned = ConfigManager.config(PrefabName, "Max Spawned", base.m_maxSpawned, "Set maximum amount allowed spawned in a zone"); configs.MaxSpawned.SettingChanged += ConfigChanged; configs.Interval = ConfigManager.config(PrefabName, "Spawn Interval", base.m_spawnInterval, "Set how often vikings will try to spawn"); configs.Interval.SettingChanged += ConfigChanged; configs.Chance = ConfigManager.config(PrefabName, "Spawn Chance", base.m_spawnChance, new ConfigDescription("Set chance to spawn", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); configs.Chance.SettingChanged += ConfigChanged; configs.Distance = ConfigManager.config(PrefabName, "Spawn Distance", base.m_spawnDistance, "Spawn range, 0 = use global settings"); configs.Distance.SettingChanged += ConfigChanged; configs.RequiredKey = ConfigManager.config(PrefabName, "Required Key", "", "Only spawn if this key is present"); configs.RequiredKey.SettingChanged += ConfigChanged; configs.RequiredEnvs = ConfigManager.config(PrefabName, "Required Envs", new EnvList().ToString(), new ConfigDescription("List of required environments for viking to spawn", (AcceptableValueBase)null, new object[1] { EnvList.attributes })); configs.RequiredEnvs.SettingChanged += ConfigChanged; configs.TOD = ConfigManager.config(PrefabName, "Spawn Time Of Day", TimeOfDay.Both, "Set time of day requirement"); configs.TOD.SettingChanged += ConfigChanged; configs.Altitude = ConfigManager.config(PrefabName, "Spawn Altitude", new MinMax(base.m_minAltitude, base.m_maxAltitude).ToString(), new ConfigDescription("Set [min]-[max] altitude", (AcceptableValueBase)null, new object[1] { MinMax.attributes })); configs.Altitude.SettingChanged += ConfigChanged; configs.Forest = ConfigManager.config(PrefabName, "Spawn Region", Region.Both, "Set which region viking can spawn in"); configs.Forest.SettingChanged += ConfigChanged; configs.Level = ConfigManager.config(PrefabName, "Spawn Level", new Level(base.m_minLevel, base.m_maxLevel, base.m_overrideLevelupChance).ToString(), new ConfigDescription("Set [min]:[max]:[chanceToLevel]", (AcceptableValueBase)null, new object[1] { Level.attributes })); configs.Level.SettingChanged += ConfigChanged; ConfigChanged(null, null); } public SpawnInfo(Elven viking) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) PrefabName = viking.name; base.m_name = viking.name; Biome = viking.biome; configs = new Configs(); ((Behaviour)SpawnList).enabled = true; base.m_groupSizeMin = 0; base.m_groupSizeMax = 1; base.m_levelUpMinCenterDistance = 1f; base.m_minTilt = 0f; base.m_maxTilt = 50f; base.m_groupRadius = 50f; SpawnList.m_spawners.Add((SpawnData)(object)this); } } public static readonly SpawnSystemList SpawnList; static SpawnManager() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown SpawnList = ((Component)ElvenNPCPlugin.instance).gameObject.AddComponent(); Harmony harmony = ElvenNPCPlugin.instance._harmony; harmony.Patch((MethodBase)AccessTools.Method(typeof(SpawnSystem), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(SpawnManager), "Patch_SpawnSystem_Awake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void Patch_SpawnSystem_Awake(SpawnSystem __instance) { __instance.m_spawnLists.Add(SpawnList); } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public static class StatusEffectManager { private static readonly List statusEffects; public static void Register(this StatusEffect statusEffect) { statusEffects.Add(statusEffect); } static StatusEffectManager() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown statusEffects = new List(); Harmony harmony = ElvenNPCPlugin.instance._harmony; harmony.Patch((MethodBase)AccessTools.Method(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(StatusEffectManager), "Patch_ObjectDB_Awake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void Patch_ObjectDB_Awake(ObjectDB __instance) { __instance.m_StatusEffects.AddRange(statusEffects); } } [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public static class TalkManager { [NullableContext(0)] public enum TalkType { Generic, PlayerBase, Greets, Farewells, Damaged, Thieved, Puke, Eat } [Serializable] [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(new byte[] { 0, 1, 1 })] public class Talks : Dictionary> { } public static string FileName; public static string FilePath; public static Talks talks; public static CustomSyncedValue sync; static TalkManager() { talks = new Talks(); FileName = "RandomTalks.yml"; FilePath = Path.Combine(ConfigManager.DirectoryPath, FileName); sync = new CustomSyncedValue(ConfigManager.ConfigSync, "RustyMods.ElvenNPC.RandomTalk.Sync"); sync.ValueChanged += OnConfigChanged; } public static List GetTalk(TalkType type) { List value; return talks.TryGetValue(type, out value) ? value : new List(); } public static void OnConfigChanged() { if (!Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.IsServer()) { return; } string value = sync.Value; if (string.IsNullOrEmpty(value)) { return; } try { Talks talks = ConfigManager.deserializer.Deserialize(value); TalkManager.talks = talks; } catch { ElvenNPCPlugin.LogError("Failed to deserialize server's random talks"); } } public static void UpdateSync(ZNet net) { if (net.IsServer()) { string value = ConfigManager.serializer.Serialize((object)talks); sync.Value = value; } } public static void Setup() { GetOrSerialize(); } public static void GetOrSerialize() { if (File.Exists(FilePath)) { Read(FilePath); return; } string file = EmbeddedResourceManager.GetFile(FileName); talks = ConfigManager.deserializer.Deserialize(file); File.WriteAllText(FilePath, file); } public static void Read(string filePath) { try { string text = File.ReadAllText(filePath); Talks talks = ConfigManager.deserializer.Deserialize(text); TalkManager.talks = talks; } catch { ElvenNPCPlugin.LogError("Failed to deserialize random talks"); } } public static void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(ConfigManager.DirectoryPath, FileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } public static void ReadConfigValues(object sender, FileSystemEventArgs e) { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { Read(FilePath); UpdateSync(ZNet.instance); ElvenNPCPlugin.LogInfo(FileName + " file changed"); } } } } namespace ElvenNPC.Behaviors { [<0a129ba9-9b79-4edb-9131-78df17e06315>Nullable(0)] [NullableContext(1)] public class ToggleLight : MonoBehaviour, Interactable, Hoverable { [NullableContext(0)] [HarmonyPatch(typeof(EnvZone), "OnTriggerStay")] private static class EnvZone_OnTriggerStay_Patch { [NullableContext(1)] private static bool Prefix(EnvZone __instance, Collider collider) { ToggleLight componentInParent = ((Component)__instance).GetComponentInParent(); if (componentInParent == null) { return true; } if (ElvenNPCPlugin._envOverride.Value == Toggle.Off) { return false; } if (componentInParent.IsOn()) { return true; } __instance.OnTriggerExit(collider); return false; } } public ZNetView m_nview = null; private readonly string m_enabledKey = "RustyEnabled"; public List m_objectsToEnable = new List(); public void Awake() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown m_nview = ((Component)this).GetComponent(); if (!m_nview.IsValid()) { return; } foreach (Transform item in ((Component)this).transform) { Transform val = item; if (!((Component)val).gameObject.activeInHierarchy) { m_objectsToEnable.Add(((Component)val).gameObject); } } m_nview.Register("RPC_Enable", (Action)RPC_Enable); bool @bool = m_nview.GetZDO().GetBool(m_enabledKey, true); m_nview.InvokeRPC("RPC_Enable", new object[1] { @bool }); } private bool IsOn() { return m_nview.IsValid() && m_nview.GetZDO().GetBool(m_enabledKey, false); } private void SetEnable(bool enable) { foreach (GameObject item in m_objectsToEnable) { item.SetActive(enable); } } private void RPC_Enable(long sender, bool enable) { m_nview.GetZDO().Set(m_enabledKey, enable); SetEnable(enable); } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold || alt) { return false; } if (!m_nview.IsValid()) { return false; } m_nview.InvokeRPC("RPC_Enable", new object[1] { !m_nview.GetZDO().GetBool(m_enabledKey, false) }); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } public string GetHoverText() { if (!m_nview.IsValid()) { return ""; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendFormat("[$KEY_Use] {0}", m_nview.GetZDO().GetBool(m_enabledKey, false) ? "$hover_off" : "$hover_on"); return Localization.instance.Localize(stringBuilder.ToString()); } public string GetHoverName() { return ""; } } } namespace Microsoft.CodeAnalysis { [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [Microsoft.CodeAnalysis.Embedded] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ServerSync { [PublicAPI] internal abstract class OwnConfigEntryBase { public object? LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [PublicAPI] internal class SyncedConfigEntry : OwnConfigEntryBase { public readonly ConfigEntry SourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public SyncedConfigEntry(ConfigEntry sourceConfig) { SourceConfig = sourceConfig; } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } internal abstract class CustomSyncedValueBase { public object? LocalBaseValue; public readonly string Identifier; public readonly Type Type; private object? boxedValue; protected bool localIsOwner; public readonly int Priority; public object? BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action? ValueChanged; protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [PublicAPI] internal sealed class CustomSyncedValue : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [PublicAPI] internal class ConfigSync { [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { public static ZRpc? currentRpc; [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class RegisterRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register(configSync2.Name + " ConfigSync", (Action)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges()); } static void SendAdmin(List peers, bool isAdmin) { ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1] { new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = isAdmin } }); ConfigSync configSync = configSyncs.First(); if (configSync != null) { ((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package)); } } static IEnumerator WatchAdminListChanges() { MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); List CurrentList = new List(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!adminList.GetList().SequenceEqual(CurrentList)) { CurrentList = new List(adminList.GetList()); List adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p) { string hostName = p.m_rpc.GetSocket().GetHostName(); return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName })); }).ToList(); List nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList(); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class RegisterClientRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { return; } foreach (ConfigSync configSync in configSyncs) { peer.m_rpc.Register(configSync.Name + " ConfigSync", (Action)configSync.RPC_FromServerConfigSync); } } } private class ParsedConfigs { public readonly Dictionary configValues = new Dictionary(); public readonly Dictionary customValues = new Dictionary(); } [HarmonyPatch(typeof(ZNet), "Shutdown")] private class ResetConfigsOnShutdown { [HarmonyPostfix] private static void Postfix() { ProcessingServerUpdate = true; foreach (ConfigSync configSync in configSyncs) { configSync.resetConfigsFromServer(); configSync.IsSourceOfTruth = true; configSync.InitialSyncDone = false; } ProcessingServerUpdate = false; } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private class SendConfigsAfterLogin { private class BufferingSocket : ISocket { public volatile bool finished = false; public volatile int versionMatchQueued = -1; public readonly List Package = new List(); public readonly ISocket Original; public BufferingSocket(ISocket original) { Original = original; } public bool IsConnected() { return Original.IsConnected(); } public ZPackage Recv() { return Original.Recv(); } public int GetSendQueueSize() { return Original.GetSendQueueSize(); } public int GetCurrentSendRate() { return Original.GetCurrentSendRate(); } public bool IsHost() { return Original.IsHost(); } public void Dispose() { Original.Dispose(); } public bool GotNewData() { return Original.GotNewData(); } public void Close() { Original.Close(); } public string GetEndPointString() { return Original.GetEndPointString(); } public void GetAndResetStats(out int totalSent, out int totalRecv) { Original.GetAndResetStats(ref totalSent, ref totalRecv); } public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec) { Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec); } public ISocket Accept() { return Original.Accept(); } public int GetHostPort() { return Original.GetHostPort(); } public bool Flush() { return Original.Flush(); } public string GetHostName() { return Original.GetHostName(); } public void VersionMatch() { if (finished) { Original.VersionMatch(); } else { versionMatchQueued = Package.Count; } } public void Send(ZPackage pkg) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown int pos = pkg.GetPos(); pkg.SetPos(0); int num = pkg.ReadInt(); if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished) { ZPackage val = new ZPackage(pkg.GetArray()); val.SetPos(pos); Package.Add(val); } else { pkg.SetPos(pos); Original.Send(pkg); } } } [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(ref Dictionary? __state, ZNet __instance, ZRpc rpc) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 if (__instance.IsServer()) { BufferingSocket value = new BufferingSocket(rpc.GetSocket()); AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, value); object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc }); ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (val != null && (int)ZNet.m_onlineBackend > 0) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, value); } if (__state == null) { __state = new Dictionary(); } __state[Assembly.GetExecutingAssembly()] = value; } } [HarmonyPostfix] private static void Postfix(Dictionary __state, ZNet __instance, ZRpc rpc) { ZRpc rpc2 = rpc; ZNet __instance2 = __instance; Dictionary __state2 = __state; ZNetPeer peer; if (__instance2.IsServer()) { object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (peer == null) { SendBufferedData(); } else { ((MonoBehaviour)__instance2).StartCoroutine(sendAsync()); } } void SendBufferedData() { if (rpc2.GetSocket() is BufferingSocket bufferingSocket) { AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original); object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null); if (val != null) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original); } } BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()]; bufferingSocket2.finished = true; for (int i = 0; i < bufferingSocket2.Package.Count; i++) { if (i == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } bufferingSocket2.Original.Send(bufferingSocket2.Package[i]); } if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } } IEnumerator sendAsync() { foreach (ConfigSync configSync in configSyncs) { List entries = new List(); if (configSync.CurrentVersion != null) { entries.Add(new PackageEntry { section = "Internal", key = "serverversion", type = typeof(string), value = configSync.CurrentVersion }); } MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); entries.Add(new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2] { adminList, rpc2.GetSocket().GetHostName() })) }); ZPackage package = ConfigsToPackage(configSync.allConfigs.Select((OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false); yield return ((MonoBehaviour)__instance2).StartCoroutine(configSync.sendZPackage(new List { peer }, package)); } SendBufferedData(); } } } private class PackageEntry { public string section = null; public string key = null; public Type type = null; public object? value; } [HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")] private static class PreventSavingServerInfo { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, ref string __result) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase)) { return true; } __result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType); return false; } } [HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")] private static class PreventConfigRereadChangingValues { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, string value) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null) { return true; } try { ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType); } catch (Exception ex) { Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}"); } return false; } } private class InvalidDeserializationTypeException : Exception { public string expected = null; public string received = null; public string field = ""; } public static bool ProcessingServerUpdate; public readonly string Name; public string? DisplayName; public string? CurrentVersion; public string? MinimumRequiredVersion; public bool ModRequired = false; private bool? forceConfigLocking; private bool isSourceOfTruth = true; private static readonly HashSet configSyncs; private readonly HashSet allConfigs = new HashSet(); private HashSet allCustomValues = new HashSet(); private static bool isServer; private static bool lockExempt; private OwnConfigEntryBase? lockedConfig = null; private const byte PARTIAL_CONFIGS = 1; private const byte FRAGMENTED_CONFIG = 2; private const byte COMPRESSED_CONFIG = 4; private readonly Dictionary> configValueCache = new Dictionary>(); private readonly List> cacheExpirations = new List>(); private static long packageCounter; public bool IsLocked { get { bool? flag = forceConfigLocking; bool num; if (!flag.HasValue) { if (lockedConfig == null) { goto IL_0052; } num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0; } else { num = flag.GetValueOrDefault(); } if (!num) { goto IL_0052; } int result = ((!lockExempt) ? 1 : 0); goto IL_0053; IL_0053: return (byte)result != 0; IL_0052: result = 0; goto IL_0053; } set { forceConfigLocking = value; } } public bool IsAdmin => lockExempt || isSourceOfTruth; public bool IsSourceOfTruth { get { return isSourceOfTruth; } private set { if (value != isSourceOfTruth) { isSourceOfTruth = value; this.SourceOfTruthChanged?.Invoke(value); } } } public bool InitialSyncDone { get; private set; } = false; public event Action? SourceOfTruthChanged; private event Action? lockedConfigChanged; static ConfigSync() { ProcessingServerUpdate = false; configSyncs = new HashSet(); lockExempt = false; packageCounter = 0L; RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle); } public ConfigSync(string name) { Name = name; configSyncs.Add(this); new VersionCheck(this); } public SyncedConfigEntry AddConfigEntry(ConfigEntry configEntry) { ConfigEntry configEntry2 = configEntry; OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2); SyncedConfigEntry syncedEntry = ownConfigEntryBase as SyncedConfigEntry; if (syncedEntry == null) { syncedEntry = new SyncedConfigEntry(configEntry2); AccessTools.DeclaredField(typeof(ConfigDescription), "k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, new object[1] { new ConfigurationManagerAttributes() }.Concat(((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty()).Concat(new SyncedConfigEntry[1] { syncedEntry }).ToArray()); configEntry2.SettingChanged += delegate { if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig) { Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2); } }; allConfigs.Add(syncedEntry); } return syncedEntry; } public SyncedConfigEntry AddLockingConfigEntry(ConfigEntry lockingConfig) where T : IConvertible { if (lockedConfig != null) { throw new Exception("Cannot initialize locking ConfigEntry twice"); } lockedConfig = AddConfigEntry(lockingConfig); lockingConfig.SettingChanged += delegate { this.lockedConfigChanged?.Invoke(); }; return (SyncedConfigEntry)lockedConfig; } internal void AddCustomValue(CustomSyncedValueBase customValue) { CustomSyncedValueBase customValue2 = customValue; if (allCustomValues.Select((CustomSyncedValueBase v) => v.Identifier).Concat(new string[1] { "serverversion" }).Contains(customValue2.Identifier)) { throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)"); } allCustomValues.Add(customValue2); allCustomValues = new HashSet(allCustomValues.OrderByDescending((CustomSyncedValueBase v) => v.Priority)); customValue2.ValueChanged += delegate { if (!ProcessingServerUpdate) { Broadcast(ZRoutedRpc.Everybody, customValue2); } }; } private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package) { lockedConfigChanged += serverLockedSettingChanged; IsSourceOfTruth = false; if (HandleConfigSyncRPC(0L, package, clientUpdate: false)) { InitialSyncDone = true; } } private void RPC_FromOtherClientConfigSync(long sender, ZPackage package) { HandleConfigSyncRPC(sender, package, clientUpdate: true); } private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown try { if (isServer && IsLocked) { ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc; object obj; if (currentRpc == null) { obj = null; } else { ISocket socket = currentRpc.GetSocket(); obj = ((socket != null) ? socket.GetHostName() : null); } string text = (string)obj; if (text != null) { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2] { val, text })))) { return false; } } } cacheExpirations.RemoveAll(delegate(KeyValuePair kv) { if (kv.Key < DateTimeOffset.Now.Ticks) { configValueCache.Remove(kv.Value); return true; } return false; }); byte b = package.ReadByte(); if ((b & 2u) != 0) { long num = package.ReadLong(); string text2 = sender.ToString() + num; if (!configValueCache.TryGetValue(text2, out SortedDictionary value)) { value = new SortedDictionary(); configValueCache[text2] = value; cacheExpirations.Add(new KeyValuePair(DateTimeOffset.Now.AddSeconds(60.0).Ticks, text2)); } int key = package.ReadInt(); int num2 = package.ReadInt(); value.Add(key, package.ReadByteArray()); if (value.Count < num2) { return false; } configValueCache.Remove(text2); package = new ZPackage(value.Values.SelectMany((byte[] a) => a).ToArray()); b = package.ReadByte(); } ProcessingServerUpdate = true; if ((b & 4u) != 0) { byte[] buffer = package.ReadByteArray(); MemoryStream stream = new MemoryStream(buffer); MemoryStream memoryStream = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) { deflateStream.CopyTo(memoryStream); } package = new ZPackage(memoryStream.ToArray()); b = package.ReadByte(); } if ((b & 1) == 0) { resetConfigsFromServer(); } ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package); ConfigFile val2 = null; bool saveOnConfigSet = false; foreach (KeyValuePair configValue in parsedConfigs.configValues) { if (!isServer && configValue.Key.LocalBaseValue == null) { configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue; } if (val2 == null) { val2 = configValue.Key.BaseConfig.ConfigFile; saveOnConfigSet = val2.SaveOnConfigSet; val2.SaveOnConfigSet = false; } configValue.Key.BaseConfig.BoxedValue = configValue.Value; } if (val2 != null) { val2.SaveOnConfigSet = saveOnConfigSet; } foreach (KeyValuePair customValue in parsedConfigs.customValues) { if (!isServer) { CustomSyncedValueBase key2 = customValue.Key; if (key2.LocalBaseValue == null) { key2.LocalBaseValue = customValue.Key.BoxedValue; } } customValue.Key.BoxedValue = customValue.Value; } Debug.Log((object)string.Format("Received {0} configs and {1} custom values from {2} for mod {3}", parsedConfigs.configValues.Count, parsedConfigs.customValues.Count, (isServer || clientUpdate) ? $"client {sender}" : "the server", DisplayName ?? Name)); if (!isServer) { serverLockedSettingChanged(); } return true; } finally { ProcessingServerUpdate = false; } } private ParsedConfigs ReadConfigsFromPackage(ZPackage package) { ParsedConfigs parsedConfigs = new ParsedConfigs(); Dictionary dictionary = allConfigs.Where((OwnConfigEntryBase c) => c.SynchronizedConfig).ToDictionary((OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c); Dictionary dictionary2 = allCustomValues.ToDictionary((CustomSyncedValueBase c) => c.Identifier, (CustomSyncedValueBase c) => c); int num = package.ReadInt(); for (int i = 0; i < num; i++) { string text = package.ReadString(); string text2 = package.ReadString(); string text3 = package.ReadString(); Type type = Type.GetType(text3); if (text3 == "" || type != null) { object obj; try { obj = ((text3 == "") ? null : ReadValueWithTypeFromZPackage(package, type)); } catch (InvalidDeserializationTypeException ex) { Debug.LogWarning((object)("Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + ex.expected)); continue; } OwnConfigEntryBase value2; if (text == "Internal") { CustomSyncedValueBase value; if (text2 == "serverversion") { if (obj?.ToString() != CurrentVersion) { Debug.LogWarning((object)("Received server version is not equal: server version = " + (obj?.ToString() ?? "null") + "; local version = " + (CurrentVersion ?? "unknown"))); } } else if (text2 == "lockexempt") { if (obj is bool flag) { lockExempt = flag; } } else if (dictionary2.TryGetValue(text2, out value)) { if ((text3 == "" && (!value.Type.IsValueType || Nullable.GetUnderlyingType(value.Type) != null)) || GetZPackageTypeString(value.Type) == text3) { parsedConfigs.customValues[value] = obj; continue; } Debug.LogWarning((object)("Got unexpected type " + text3 + " for internal value " + text2 + " for mod " + (DisplayName ?? Name) + ", expecting " + value.Type.AssemblyQualifiedName)); } } else if (dictionary.TryGetValue(text + "_" + text2, out value2)) { Type type2 = configType(value2.BaseConfig); if ((text3 == "" && (!type2.IsValueType || Nullable.GetUnderlyingType(type2) != null)) || GetZPackageTypeString(type2) == text3) { parsedConfigs.configValues[value2] = obj; continue; } Debug.LogWarning((object)("Got unexpected type " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName)); } else { Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match.")); } continue; } Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs")); return new ParsedConfigs(); } return parsedConfigs; } private static bool isWritableConfig(OwnConfigEntryBase config) { OwnConfigEntryBase config2 = config; ConfigSync configSync = configSyncs.FirstOrDefault((ConfigSync cs) => cs.allConfigs.Contains(config2)); if (configSync == null) { return true; } return configSync.IsSourceOfTruth || !config2.SynchronizedConfig || config2.LocalBaseValue == null || (!configSync.IsLocked && (config2 != configSync.lockedConfig || lockExempt)); } private void serverLockedSettingChanged() { foreach (OwnConfigEntryBase allConfig in allConfigs) { configAttribute(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig); } } private void resetConfigsFromServer() { ConfigFile val = null; bool saveOnConfigSet = false; foreach (OwnConfigEntryBase item in allConfigs.Where((OwnConfigEntryBase config) => config.LocalBaseValue != null)) { if (val == null) { val = item.BaseConfig.ConfigFile; saveOnConfigSet = val.SaveOnConfigSet; val.SaveOnConfigSet = false; } item.BaseConfig.BoxedValue = item.LocalBaseValue; item.LocalBaseValue = null; } if (val != null) { val.SaveOnConfigSet = saveOnConfigSet; } foreach (CustomSyncedValueBase item2 in allCustomValues.Where((CustomSyncedValueBase config) => config.LocalBaseValue != null)) { item2.BoxedValue = item2.LocalBaseValue; item2.LocalBaseValue = null; } lockedConfigChanged -= serverLockedSettingChanged; serverLockedSettingChanged(); } private IEnumerator distributeConfigToPeers(ZNetPeer peer, ZPackage package) { ZNetPeer peer2 = peer; ZRoutedRpc rpc = ZRoutedRpc.instance; if (rpc == null) { yield break; } byte[] data = package.GetArray(); if (data != null && data.LongLength > 250000) { int fragments = (int)(1 + (data.LongLength - 1) / 250000); long packageIdentifier = ++packageCounter; int fragment = 0; while (fragment < fragments) { foreach (bool item in waitForQueue()) { yield return item; } if (peer2.m_socket.IsConnected()) { ZPackage fragmentedPackage = new ZPackage(); fragmentedPackage.Write((byte)2); fragmentedPackage.Write(packageIdentifier); fragmentedPackage.Write(fragment); fragmentedPackage.Write(fragments); fragmentedPackage.Write(data.Skip(250000 * fragment).Take(250000).ToArray()); SendPackage(fragmentedPackage); if (fragment != fragments - 1) { yield return true; } int num = fragment + 1; fragment = num; continue; } break; } yield break; } foreach (bool item2 in waitForQueue()) { yield return item2; } SendPackage(package); void SendPackage(ZPackage pkg) { string text = Name + " ConfigSync"; if (isServer) { peer2.m_rpc.Invoke(text, new object[1] { pkg }); } else { rpc.InvokeRoutedRPC(peer2.m_server ? 0 : peer2.m_uid, text, new object[1] { pkg }); } } IEnumerable waitForQueue() { float timeout = Time.time + 30f; while (peer2.m_socket.GetSendQueueSize() > 20000) { if (Time.time > timeout) { Debug.Log((object)$"Disconnecting {peer2.m_uid} after 30 seconds config sending timeout"); peer2.m_rpc.Invoke("Error", new object[1] { (object)(ConnectionStatus)5 }); ZNet.instance.Disconnect(peer2); break; } yield return false; } } } private IEnumerator sendZPackage(long target, ZPackage package) { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return Enumerable.Empty().GetEnumerator(); } List list = (List)AccessTools.DeclaredField(typeof(ZRoutedRpc), "m_peers").GetValue(ZRoutedRpc.instance); if (target != ZRoutedRpc.Everybody) { list = list.Where((ZNetPeer p) => p.m_uid == target).ToList(); } return sendZPackage(list, package); } private IEnumerator sendZPackage(List peers, ZPackage package) { ZPackage package2 = package; if (!Object.op_Implicit((Object)(object)ZNet.instance)) { yield break; } byte[] rawData = package2.GetArray(); if (rawData != null && rawData.LongLength > 10000) { ZPackage compressedPackage = new ZPackage(); compressedPackage.Write((byte)4); MemoryStream output = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(output, CompressionLevel.Optimal)) { deflateStream.Write(rawData, 0, rawData.Length); } compressedPackage.Write(output.ToArray()); package2 = compressedPackage; } List> writers = (from peer in peers where peer.IsReady() select peer into p select distributeConfigToPeers(p, package2)).ToList(); writers.RemoveAll((IEnumerator writer) => !writer.MoveNext()); while (writers.Count > 0) { yield return null; writers.RemoveAll((IEnumerator writer) => !writer.MoveNext()); } } private void Broadcast(long target, params ConfigEntryBase[] configs) { if (!IsLocked || isServer) { ZPackage package = ConfigsToPackage(configs); ZNet instance = ZNet.instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package)); } } } private void Broadcast(long target, params CustomSyncedValueBase[] customValues) { if (!IsLocked || isServer) { ZPackage package = ConfigsToPackage(null, customValues); ZNet instance = ZNet.instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package)); } } } private static OwnConfigEntryBase? configData(ConfigEntryBase config) { return config.Description.Tags?.OfType().SingleOrDefault(); } public static SyncedConfigEntry? ConfigData(ConfigEntry config) { return ((ConfigEntryBase)config).Description.Tags?.OfType>().SingleOrDefault(); } private static T configAttribute(ConfigEntryBase config) { return config.Description.Tags.OfType().First(); } private static Type configType(ConfigEntryBase config) { return configType(config.SettingType); } private static Type configType(Type type) { return type.IsEnum ? Enum.GetUnderlyingType(type) : type; } private static ZPackage ConfigsToPackage(IEnumerable? configs = null, IEnumerable? customValues = null, IEnumerable? packageEntries = null, bool partial = true) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown List list = configs?.Where((ConfigEntryBase config) => configData(config).SynchronizedConfig).ToList() ?? new List(); List list2 = customValues?.ToList() ?? new List(); ZPackage val = new ZPackage(); val.Write((byte)(partial ? 1 : 0)); val.Write(list.Count + list2.Count + (packageEntries?.Count() ?? 0)); foreach (PackageEntry item in packageEntries ?? Array.Empty()) { AddEntryToPackage(val, item); } foreach (CustomSyncedValueBase item2 in list2) { AddEntryToPackage(val, new PackageEntry { section = "Internal", key = item2.Identifier, type = item2.Type, value = item2.BoxedValue }); } foreach (ConfigEntryBase item3 in list) { AddEntryToPackage(val, new PackageEntry { section = item3.Definition.Section, key = item3.Definition.Key, type = configType(item3), value = item3.BoxedValue }); } return val; } private static void AddEntryToPackage(ZPackage package, PackageEntry entry) { package.Write(entry.section); package.Write(entry.key); package.Write((entry.value == null) ? "" : GetZPackageTypeString(entry.type)); AddValueToZPackage(package, entry.value); } private static string GetZPackageTypeString(Type type) { return type.AssemblyQualifiedName; } private static void AddValueToZPackage(ZPackage package, object? value) { Type type = value?.GetType(); if (value is Enum) { value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(value.GetType()), CultureInfo.InvariantCulture); } else { if (value is ICollection collection) { package.Write(collection.Count); { foreach (object item in collection) { AddValueToZPackage(package, item); } return; } } if ((object)type != null && type.IsValueType && !type.IsPrimitive) { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); package.Write(fields.Length); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { package.Write(GetZPackageTypeString(fieldInfo.FieldType)); AddValueToZPackage(package, fieldInfo.GetValue(value)); } return; } } ZRpc.Serialize(new object[1] { value }, ref package); } private static object ReadValueWithTypeFromZPackage(ZPackage package, Type type) { if ((object)type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum) { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); int num = package.ReadInt(); if (num != fields.Length) { throw new InvalidDeserializationTypeException { received = $"(field count: {num})", expected = $"(field count: {fields.Length})" }; } object uninitializedObject = FormatterServices.GetUninitializedObject(type); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { string text = package.ReadString(); if (text != GetZPackageTypeString(fieldInfo.FieldType)) { throw new InvalidDeserializationTypeException { received = text, expected = GetZPackageTypeString(fieldInfo.FieldType), field = fieldInfo.Name }; } fieldInfo.SetValue(uninitializedObject, ReadValueWithTypeFromZPackage(package, fieldInfo.FieldType)); } return uninitializedObject; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >)) { int num2 = package.ReadInt(); IDictionary dictionary = (IDictionary)Activator.CreateInstance(type); Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments); FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic); for (int j = 0; j < num2; j++) { object obj = ReadValueWithTypeFromZPackage(package, type2); dictionary.Add(field.GetValue(obj), field2.GetValue(obj)); } return dictionary; } if (type != typeof(List) && type.IsGenericType) { Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]); if ((object)type3 != null && type3.IsAssignableFrom(type)) { int num3 = package.ReadInt(); object obj2 = Activator.CreateInstance(type); MethodInfo method = type3.GetMethod("Add"); for (int k = 0; k < num3; k++) { method.Invoke(obj2, new object[1] { ReadValueWithTypeFromZPackage(package, type.GenericTypeArguments[0]) }); } return obj2; } } ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo)); AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type); List source = new List(); ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source); return source.First(); } } [PublicAPI] [HarmonyPatch] internal class VersionCheck { private static readonly HashSet versionChecks; private static readonly Dictionary notProcessedNames; public string Name; private string? displayName; private string? currentVersion; private string? minimumRequiredVersion; public bool ModRequired = true; private string? ReceivedCurrentVersion; private string? ReceivedMinimumRequiredVersion; private readonly List ValidatedClients = new List(); private ConfigSync? ConfigSync; public string DisplayName { get { return displayName ?? Name; } set { displayName = value; } } public string CurrentVersion { get { return currentVersion ?? "0.0.0"; } set { currentVersion = value; } } public string MinimumRequiredVersion { get { return minimumRequiredVersion ?? (ModRequired ? CurrentVersion : "0.0.0"); } set { minimumRequiredVersion = value; } } private static void PatchServerSync() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown Patches patchInfo = PatchProcessor.GetPatchInfo((MethodBase)AccessTools.DeclaredMethod(typeof(ZNet), "Awake", (Type[])null, (Type[])null)); if (patchInfo != null && patchInfo.Postfixes.Count((Patch p) => p.PatchMethod.DeclaringType == typeof(ConfigSync.RegisterRPCPatch)) > 0) { return; } Harmony val = new Harmony("org.bepinex.helpers.ServerSync"); foreach (Type item in from t in typeof(ConfigSync).GetNestedTypes(BindingFlags.NonPublic).Concat(new Type[1] { typeof(VersionCheck) }) where t.IsClass select t) { val.PatchAll(item); } } static VersionCheck() { versionChecks = new HashSet(); notProcessedNames = new Dictionary(); typeof(ThreadingHelper).GetMethod("StartSyncInvoke").Invoke(ThreadingHelper.Instance, new object[1] { new Action(PatchServerSync) }); } public VersionCheck(string name) { Name = name; ModRequired = true; versionChecks.Add(this); } public VersionCheck(ConfigSync configSync) { ConfigSync = configSync; Name = ConfigSync.Name; versionChecks.Add(this); } public void Initialize() { ReceivedCurrentVersion = null; ReceivedMinimumRequiredVersion = null; if (ConfigSync != null) { Name = ConfigSync.Name; DisplayName = ConfigSync.DisplayName; CurrentVersion = ConfigSync.CurrentVersion; MinimumRequiredVersion = ConfigSync.MinimumRequiredVersion; ModRequired = ConfigSync.ModRequired; } } private bool IsVersionOk() { if (ReceivedMinimumRequiredVersion == null || ReceivedCurrentVersion == null) { return !ModRequired; } bool flag = new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion); bool flag2 = new Version(ReceivedCurrentVersion) >= new Version(MinimumRequiredVersion); return flag && flag2; } private string ErrorClient() { if (ReceivedMinimumRequiredVersion == null) { return DisplayName + " is not installed on the server."; } return (new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion)) ? (DisplayName + " may not be higher than version " + ReceivedCurrentVersion + ". You have version " + CurrentVersion + ".") : (DisplayName + " needs to be at least version " + ReceivedMinimumRequiredVersion + ". You have version " + CurrentVersion + "."); } private string ErrorServer(ZRpc rpc) { return "Disconnect: The client (" + rpc.GetSocket().GetHostName() + ") doesn't have the correct " + DisplayName + " version " + MinimumRequiredVersion; } private string Error(ZRpc? rpc = null) { return (rpc == null) ? ErrorClient() : ErrorServer(rpc); } private static VersionCheck[] GetFailedClient() { return versionChecks.Where((VersionCheck check) => !check.IsVersionOk()).ToArray(); } private static VersionCheck[] GetFailedServer(ZRpc rpc) { ZRpc rpc2 = rpc; return versionChecks.Where((VersionCheck check) => check.ModRequired && !check.ValidatedClients.Contains(rpc2)).ToArray(); } private static void Logout() { Game.instance.Logout(true, true); AccessTools.DeclaredField(typeof(ZNet), "m_connectionStatus").SetValue(null, (object)(ConnectionStatus)3); } private static void DisconnectClient(ZRpc rpc) { rpc.Invoke("Error", new object[1] { 3 }); } private static void CheckVersion(ZRpc rpc, ZPackage pkg) { CheckVersion(rpc, pkg, null); } private static void CheckVersion(ZRpc rpc, ZPackage pkg, Action? original) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); string text3 = pkg.ReadString(); bool flag = false; foreach (VersionCheck versionCheck in versionChecks) { if (!(text != versionCheck.Name)) { Debug.Log((object)("Received " + versionCheck.DisplayName + " version " + text3 + " and minimum version " + text2 + " from the " + (ZNet.instance.IsServer() ? "client" : "server") + ".")); versionCheck.ReceivedMinimumRequiredVersion = text2; versionCheck.ReceivedCurrentVersion = text3; if (ZNet.instance.IsServer() && versionCheck.IsVersionOk()) { versionCheck.ValidatedClients.Add(rpc); } flag = true; } } if (flag) { return; } pkg.SetPos(0); if (original != null) { original(rpc, pkg); if (pkg.GetPos() == 0) { notProcessedNames.Add(text, text3); } } } [HarmonyPrefix] [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private static bool RPC_PeerInfo(ZRpc rpc, ZNet __instance) { VersionCheck[] array = (__instance.IsServer() ? GetFailedServer(rpc) : GetFailedClient()); if (array.Length == 0) { return true; } VersionCheck[] array2 = array; foreach (VersionCheck versionCheck in array2) { Debug.LogWarning((object)versionCheck.Error(rpc)); } if (__instance.IsServer()) { DisconnectClient(rpc); } else { Logout(); } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static void RegisterAndCheckVersion(ZNetPeer peer, ZNet __instance) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown notProcessedNames.Clear(); IDictionary dictionary = (IDictionary)typeof(ZRpc).GetField("m_functions", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(peer.m_rpc); if (dictionary.Contains(StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck"))) { object obj = dictionary[StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")]; Action action = (Action)obj.GetType().GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj); peer.m_rpc.Register("ServerSync VersionCheck", (Action)delegate(ZRpc rpc, ZPackage pkg) { CheckVersion(rpc, pkg, action); }); } else { peer.m_rpc.Register("ServerSync VersionCheck", (Action)CheckVersion); } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.Initialize(); if (versionCheck.ModRequired || __instance.IsServer()) { Debug.Log((object)("Sending " + versionCheck.DisplayName + " version " + versionCheck.CurrentVersion + " and minimum version " + versionCheck.MinimumRequiredVersion + " to the " + (__instance.IsServer() ? "client" : "server") + ".")); ZPackage val = new ZPackage(); val.Write(versionCheck.Name); val.Write(versionCheck.MinimumRequiredVersion); val.Write(versionCheck.CurrentVersion); peer.m_rpc.Invoke("ServerSync VersionCheck", new object[1] { val }); } } } [HarmonyPrefix] [HarmonyPatch(typeof(ZNet), "Disconnect")] private static void RemoveDisconnected(ZNetPeer peer, ZNet __instance) { if (!__instance.IsServer()) { return; } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.ValidatedClients.Remove(peer.m_rpc); } } [HarmonyPostfix] [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] private static void ShowConnectionError(FejdStartup __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) if (!__instance.m_connectionFailedPanel.activeSelf || (int)ZNet.GetConnectionStatus() != 3) { return; } bool flag = false; VersionCheck[] failedClient = GetFailedClient(); if (failedClient.Length != 0) { string text = string.Join("\n", failedClient.Select((VersionCheck check) => check.Error())); TMP_Text connectionFailedError = __instance.m_connectionFailedError; connectionFailedError.text = connectionFailedError.text + "\n" + text; flag = true; } foreach (KeyValuePair item in notProcessedNames.OrderBy, string>((KeyValuePair kv) => kv.Key)) { if (!__instance.m_connectionFailedError.text.Contains(item.Key)) { TMP_Text connectionFailedError2 = __instance.m_connectionFailedError; connectionFailedError2.text = connectionFailedError2.text + "\nServer expects you to have " + item.Key + " (Version: " + item.Value + ") installed."; flag = true; } } if (flag) { RectTransform component = ((Component)__instance.m_connectionFailedPanel.transform.Find("Image")).GetComponent(); Vector2 sizeDelta = component.sizeDelta; sizeDelta.x = 675f; component.sizeDelta = sizeDelta; __instance.m_connectionFailedError.ForceMeshUpdate(false, false); float num = __instance.m_connectionFailedError.renderedHeight + 105f; RectTransform component2 = ((Component)((Component)component).transform.Find("ButtonOk")).GetComponent(); component2.anchoredPosition = new Vector2(component2.anchoredPosition.x, component2.anchoredPosition.y - (num - component.sizeDelta.y) / 2f); sizeDelta = component.sizeDelta; sizeDelta.y = num; component.sizeDelta = sizeDelta; } } } }