using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using ServerSync; using Splatform; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Homestead")] [assembly: AssemblyDescription("Player-facing construction tools, native blueprints, blueprint trading, build camera controls, placement helpers, and Dvergr circlet QoL for Valheim.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("sighsorry")] [assembly: AssemblyProduct("Homestead")] [assembly: AssemblyCopyright("Copyright 2026 sighsorry")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyFileVersion("1.1.2")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class ExtensionMarkerAttribute : Attribute { private readonly string k__BackingField; public string Name => k__BackingField; public ExtensionMarkerAttribute(string name) { k__BackingField = name; } } } namespace Homestead { internal static class AzuCraftyBoxesCompat { private const string ApiTypeName = "AzuCraftyBoxes.API"; private const string PluginTypeName = "AzuCraftyBoxes.AzuCraftyBoxesPlugin"; private const string MiscFunctionsTypeName = "AzuCraftyBoxes.Util.Functions.MiscFunctions"; private const string BoxesTypeName = "AzuCraftyBoxes.Util.Functions.Boxes"; private const float FallbackRange = 20f; private const float PatchRetryIntervalSeconds = 2f; private static readonly HashSet ProtectedContainerPrefabs = new HashSet(StringComparer.OrdinalIgnoreCase) { "piece_chest_wood_blueprint", "piece_chest_barrel_blueprint_store_price", "piece_chest_blueprint_store_purchase", "piece_chest_blackmetal_blueprint_store_payout" }; private static bool _initialized; private static ManualLogSource? _logger; private static Harmony? _harmony; private static Type? _apiType; private static Type? _pluginType; private static Type? _miscFunctionsType; private static Type? _boxesType; private static Type? _queryFrameType; private static MethodInfo? _getNearbyContainersDefinition; private static MethodInfo? _canItemBePulled; private static MethodInfo? _apiRemoveContainer; private static MethodInfo? _boxesRemoveContainer; private static MethodInfo? _shouldPrevent; private static MethodInfo? _checkAndDecrement; private static FieldInfo? _rangeField; private static bool _pullFilterPatchApplied; private static bool _loggedPullFilterPatchFailure; private static float _nextPatchRetryAt; internal static bool IsLoaded { get { EnsureInitialized(); if (_apiType != null) { return InvokeStaticBool(_apiType.GetMethod("IsLoaded", BindingFlags.Static | BindingFlags.Public), fallback: true); } return false; } } internal static void Initialize(ManualLogSource logger, Harmony harmony) { _logger = logger; _harmony = harmony; EnsureInitialized(force: true); TryPatchPullFilter(); } internal static void Update() { if (!_pullFilterPatchApplied && Time.realtimeSinceStartup >= _nextPatchRetryAt) { TryPatchPullFilter(); } } internal static int PullMissingMaterials(Component source, IReadOnlyList missingRequirements, Action acceptPulledMaterial) { if ((Object)(object)source == (Object)null || missingRequirements.Count == 0 || acceptPulledMaterial == null) { return 0; } EnsureInitialized(); if (!IsUsable()) { return 0; } if (InvokeStaticBool(_shouldPrevent, fallback: false)) { return 0; } IEnumerable nearbyContainers = GetNearbyContainers(source, GetPullRange()); if (nearbyContainers == null) { return 0; } int num = 0; foreach (ZoneBlueprintRequirement item in missingRequirements.Where((ZoneBlueprintRequirement requirement) => requirement.Amount > 0)) { int num2 = item.Amount; foreach (object item2 in nearbyContainers) { if (num2 <= 0) { break; } string text = InvokeString(item2, "GetPrefabName"); if (!string.IsNullOrWhiteSpace(text) && !string.Equals(text, "piece_chest_wood_blueprint", StringComparison.OrdinalIgnoreCase) && !ZoneBlueprintStoreChestPrefab.IsStorePrefabName(text) && CanItemBePulled(text, item.PrefabName)) { int amount = InvokeInt(item2, "ItemCount", item.ItemName); int num3 = Mathf.Max(0, CheckAndDecrement(amount)); int num4 = Mathf.Min(num2, num3); if (num4 > 0) { InvokeVoid(item2, "RemoveItem", item.ItemName, num4); InvokeVoid(item2, "Save"); acceptPulledMaterial(item, num4); num2 -= num4; num += num4; } } } } return num; } internal static void RemoveContainer(Container? container, string source) { if (!Object.op_Implicit((Object)(object)container)) { return; } EnsureInitialized(_apiType == null || _boxesType == null); int num = 0 | (InvokeStaticVoid(_apiRemoveContainer, container) ? 1 : 0) | (InvokeStaticVoid(_boxesRemoveContainer, container) ? 1 : 0) | (RemoveContainerFromAzuSets(container) ? 1 : 0); InvalidateNearbyContainerCache(); if (num != 0) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogDebug((object)("Removed Homestead container from AzuCraftyBoxes registry/cache (" + source + "): " + NormalizePrefabName(((Object)container).name ?? ""))); } } } private static void EnsureInitialized(bool force = false) { if (!_initialized || force) { _initialized = true; _apiType = FindType("AzuCraftyBoxes.API"); _pluginType = FindType("AzuCraftyBoxes.AzuCraftyBoxesPlugin"); _miscFunctionsType = FindType("AzuCraftyBoxes.Util.Functions.MiscFunctions"); _boxesType = FindType("AzuCraftyBoxes.Util.Functions.Boxes"); _queryFrameType = _boxesType?.GetNestedType("QueryFrame", BindingFlags.Public | BindingFlags.NonPublic); _getNearbyContainersDefinition = _apiType?.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MethodInfo method) => method.Name == "GetNearbyContainers" && method.IsGenericMethodDefinition); _canItemBePulled = _apiType?.GetMethod("CanItemBePulled", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(string), typeof(string) }, null); _apiRemoveContainer = _apiType?.GetMethod("RemoveContainer", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Container) }, null); _boxesRemoveContainer = _boxesType?.GetMethod("RemoveContainer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Container) }, null); _shouldPrevent = _miscFunctionsType?.GetMethod("ShouldPrevent", BindingFlags.Static | BindingFlags.NonPublic); _checkAndDecrement = _boxesType?.GetMethod("CheckAndDecrement", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); _rangeField = _pluginType?.GetField("mRange", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } } private static void TryPatchPullFilter() { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown if (_pullFilterPatchApplied || _harmony == null) { return; } EnsureInitialized(_boxesType == null); _nextPatchRetryAt = Time.realtimeSinceStartup + 2f; if (_boxesType == null) { return; } MethodInfo methodInfo = _boxesType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo method) { if (method.Name != "CanItemBePulled") { return false; } ParameterInfo[] parameters = method.GetParameters(); return parameters.Length >= 2 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string); }); MethodInfo method2 = typeof(AzuCraftyBoxesCompat).GetMethod("CanItemBePulledPrefix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo == null || method2 == null) { if (!_loggedPullFilterPatchFailure) { _loggedPullFilterPatchFailure = true; ManualLogSource? logger = _logger; if (logger != null) { logger.LogDebug((object)"AzuCraftyBoxes CanItemBePulled patch target is not available yet."); } } return; } try { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _pullFilterPatchApplied = true; ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogInfo((object)"AzuCraftyBoxes pull filter patched for Homestead blueprint containers."); } } catch (Exception ex) { if (!_loggedPullFilterPatchFailure) { _loggedPullFilterPatchFailure = true; ManualLogSource? logger3 = _logger; if (logger3 != null) { logger3.LogDebug((object)("Could not patch AzuCraftyBoxes pull filter: " + ex.Message)); } } } } private static bool CanItemBePulledPrefix(string container, ref bool __result) { if (!IsProtectedContainerPrefab(container)) { return true; } __result = false; return false; } private static bool IsProtectedContainerPrefab(string? prefabName) { string text = prefabName ?? ""; if (string.IsNullOrWhiteSpace(text)) { return false; } return ProtectedContainerPrefabs.Contains(NormalizePrefabName(text)); } private static string NormalizePrefabName(string prefabName) { int num = prefabName.IndexOfAny(new char[2] { '(', ' ' }); if (num >= 0) { return prefabName.Substring(0, num); } return prefabName; } private static bool InvokeStaticVoid(MethodInfo? method, Container container) { try { method?.Invoke(null, new object[1] { container }); return method != null; } catch { return false; } } private static bool RemoveContainerFromAzuSets(Container container) { return false | RemoveContainerFromSet("Containers", container) | RemoveContainerFromSet("ContainersToAdd", container) | RemoveContainerFromSet("ContainersToRemove", container); } private static bool RemoveContainerFromSet(string fieldName, Container container) { try { object obj = _boxesType?.GetField(fieldName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); object obj2 = (obj?.GetType().GetMethod("Remove", new Type[1] { typeof(Container) }))?.Invoke(obj, new object[1] { container }); bool flag = default(bool); int num; if (obj2 is bool) { flag = (bool)obj2; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } private static void InvalidateNearbyContainerCache() { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) try { _queryFrameType?.GetField("FrameId", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(null, -1); _queryFrameType?.GetField("Nearby", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(null, null); ClearListField(_boxesType, "_cachedAll"); ClearListField(_boxesType, "_scratchNearby"); _boxesType?.GetField("_lastQueryTime", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(null, float.NegativeInfinity); _boxesType?.GetField("_lastQueryRange", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(null, -1f); _boxesType?.GetField("_lastQueryPos", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(null, Vector3.positiveInfinity); } catch { } } private static void ClearListField(Type? type, string fieldName) { try { if (type?.GetField(fieldName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) is IList list) { list.Clear(); } } catch { } } private static bool IsUsable() { if (_apiType != null && _getNearbyContainersDefinition != null) { return _canItemBePulled != null; } return false; } private static IEnumerable? GetNearbyContainers(Component source, float range) { try { return _getNearbyContainersDefinition.MakeGenericMethod(((object)source).GetType()).Invoke(null, new object[2] { source, range }) as IEnumerable; } catch { return null; } } private static float GetPullRange() { try { object obj = _rangeField?.GetValue(null); object obj2 = obj?.GetType().GetProperty("Value")?.GetValue(obj, null); if (obj2 != null) { return Mathf.Max(1f, Convert.ToSingle(obj2, CultureInfo.InvariantCulture)); } } catch { } return 20f; } private static bool CanItemBePulled(string containerPrefab, string itemPrefab) { try { object obj = _canItemBePulled?.Invoke(null, new object[2] { containerPrefab, itemPrefab }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } private static int CheckAndDecrement(int amount) { try { return (_checkAndDecrement?.Invoke(null, new object[1] { amount }) is int num) ? num : amount; } catch { return amount; } } private static Type? FindType(string fullName) { string fullName2 = fullName; return (from assembly in AppDomain.CurrentDomain.GetAssemblies() select assembly.GetType(fullName2, throwOnError: false)).FirstOrDefault((Type type) => type != null); } private static string InvokeString(object target, string methodName) { try { return (target.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public)?.Invoke(target, Array.Empty()) as string) ?? ""; } catch { return ""; } } private static int InvokeInt(object target, string methodName, params object[] args) { try { return (target.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public)?.Invoke(target, args) is int num) ? num : 0; } catch { return 0; } } private static void InvokeVoid(object target, string methodName, params object[] args) { try { target.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public)?.Invoke(target, args); } catch { } } private static bool InvokeStaticBool(MethodInfo? method, bool fallback) { try { return (method?.Invoke(null, Array.Empty()) is bool flag) ? flag : fallback; } catch { return fallback; } } private static Exception Unwrap(Exception ex) { if (!(ex is TargetInvocationException) || ex.InnerException == null) { return ex; } return ex.InnerException; } } internal static class AzuExtendedPlayerInventoryCompat { private const string PluginGuid = "Azumatt.AzuExtendedPlayerInventory"; private const string CustomEquipVisualsTypeName = "AzuEPI.Game.PlayerPreview.CustomEquipVisuals"; private static readonly BindingFlags StaticFieldFlags = BindingFlags.Static | BindingFlags.NonPublic; private static readonly BindingFlags InstanceFieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static bool _initialized; private static bool _loaded; private static FieldInfo? _statesField; public static bool IsLoaded { get { EnsureInitialized(); return _loaded; } } public static bool TryGetCustomEquippedItem(Player player, Func predicate, out ItemData? item) { item = null; if (!IsLoaded || !Object.op_Implicit((Object)(object)player)) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return false; } foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem != null && allItem.m_equipped && allItem != ((Humanoid)player).m_helmetItem && allItem != ((Humanoid)player).m_chestItem && allItem != ((Humanoid)player).m_legItem && allItem != ((Humanoid)player).m_shoulderItem && allItem != ((Humanoid)player).m_utilityItem && allItem != ((Humanoid)player).m_trinketItem && predicate(allItem)) { item = allItem; return true; } } return false; } public static bool TryGetCustomEquipVisualRoots(VisEquipment visEquipment, ItemData item, List roots) { roots.Clear(); if (!IsLoaded || !Object.op_Implicit((Object)(object)visEquipment) || item == null || _statesField == null) { return false; } try { if (!(_statesField.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(visEquipment)) { return false; } object obj = dictionary[visEquipment]; if (obj == null) { return false; } if (!(obj.GetType().GetField("Equipped", InstanceFieldFlags)?.GetValue(obj) is IDictionary dictionary2)) { return false; } foreach (DictionaryEntry item2 in dictionary2) { object value = item2.Value; if (value == null) { continue; } Type type = value.GetType(); if (type.GetField("Item", InstanceFieldFlags)?.GetValue(value) != item || !(type.GetField("Instances", InstanceFieldFlags)?.GetValue(value) is IEnumerable enumerable)) { continue; } foreach (object item3 in enumerable) { GameObject val = (GameObject)((item3 is GameObject) ? item3 : null); if (val != null && Object.op_Implicit((Object)(object)val)) { roots.Add(val); } } } } catch { roots.Clear(); } return roots.Count > 0; } public static void ResetForWorldSession() { if (!_loaded) { _initialized = false; _statesField = null; } } private static void EnsureInitialized() { if (!_initialized) { _initialized = true; if (Chainloader.PluginInfos.TryGetValue("Azumatt.AzuExtendedPlayerInventory", out var value)) { _statesField = ((((object)value.Instance)?.GetType().Assembly)?.GetType("AzuEPI.Game.PlayerPreview.CustomEquipVisuals", throwOnError: false))?.GetField("_states", StaticFieldFlags); _loaded = true; } } } } internal static class BlueprintTerrainApplier { public static List CaptureContacts(Vector3 anchor, Quaternion inverseAnchorRotation, IEnumerable sources) { //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) List contacts = BlueprintTerrainContactSampler.CaptureWorldContacts(sources, BlueprintConfig.TerrainSupportContactTolerance); return BlueprintTerrainContactSampler.ToBlueprintContacts(anchor, inverseAnchorRotation, contacts); } public static bool ApplySupportContacts(IEnumerable supportContacts) { return HomesteadTerrainSupport.ApplyWorldSupportContacts(supportContacts); } public static IEnumerator ApplySupportContactsAsync(IEnumerable supportContacts, Action onComplete) { return HomesteadTerrainSupport.ApplyWorldSupportContactsAsync(supportContacts, onComplete); } } internal static class BlueprintTerrainContactSampler { public static List CaptureWorldContacts(IEnumerable sources, float tolerance) { //IL_0041: 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_004f: 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) Dictionary dictionary = new Dictionary(); foreach (TerrainContactSource source in sources) { if (Object.op_Implicit((Object)(object)source.Prefab) && !((Object)(object)source.Prefab.GetComponent() == (Object)null) && HomesteadTerrainSupport.TryGetWearNTearBounds(source.Prefab, source.Position, source.Rotation, source.Scale, out var bounds)) { AddLowestBoundsFootprintContacts(bounds, dictionary); } } List list = new List(); foreach (TerrainWorldContact item in from contact in dictionary.Values orderby contact.WorldZ, contact.WorldX select contact) { if (HomesteadTerrainSupport.TryGetTerrainHeight(item.WorldX, item.WorldZ, out var height) && !(Mathf.Abs(height - item.WorldY) > tolerance)) { list.Add(item); } } return list; } public static List ToBlueprintContacts(Vector3 anchor, Quaternion inverseAnchorRotation, IEnumerable contacts) { //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_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) return (from contact in contacts.Select(delegate(TerrainWorldContact contact) { //IL_0001: 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_000e: Unknown result type (might be due to invalid IL or missing references) //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_001d: 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_0035: 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) Vector3 val = inverseAnchorRotation * (contact.ToVector3() - anchor); return new ZoneBlueprintTerrainContact { LocalX = Round(val.x), LocalY = Round(val.y), LocalZ = Round(val.z) }; }) orderby contact.LocalZ, contact.LocalX select contact).ToList(); } private static void AddLowestBoundsFootprintContacts(Bounds bounds, Dictionary lowestByCell) { //IL_0002: 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_0020: 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_0044: Unknown result type (might be due to invalid IL or missing references) float y = ((Bounds)(ref bounds)).min.y; int num = Mathf.FloorToInt(((Bounds)(ref bounds)).min.x); int num2 = Mathf.CeilToInt(((Bounds)(ref bounds)).max.x); int num3 = Mathf.FloorToInt(((Bounds)(ref bounds)).min.z); int num4 = Mathf.CeilToInt(((Bounds)(ref bounds)).max.z); for (int i = num; i <= num2; i++) { for (int j = num3; j <= num4; j++) { long key = PackCell(i, j); TerrainWorldContact value = new TerrainWorldContact(i, j, y); if (!lowestByCell.TryGetValue(key, out var value2) || value.WorldY < value2.WorldY) { lowestByCell[key] = value; } } } } private static long PackCell(int x, int z) { return ((long)x << 32) ^ (uint)z; } private static float Round(float value) { return Mathf.Round(value * 1000f) / 1000f; } } internal readonly struct TerrainContactSource { public GameObject Prefab { get; } public Vector3 Position { get; } public Quaternion Rotation { get; } public Vector3 Scale { get; } public TerrainContactSource(GameObject prefab, Vector3 position, Quaternion rotation, Vector3 scale) { //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_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_0016: 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) Prefab = prefab; Position = position; Rotation = rotation; Scale = scale; } } internal readonly struct TerrainWorldContact { public float WorldX { get; } public float WorldZ { get; } public float WorldY { get; } public TerrainWorldContact(int cellX, int cellZ, float worldY) { WorldX = cellX; WorldZ = cellZ; WorldY = worldY; } public Vector3 ToVector3() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(WorldX, WorldY, WorldZ); } } [BepInPlugin("sighsorry.Homestead", "Homestead", "1.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class HomesteadPlugin : BaseUnityPlugin { public enum Toggle { On = 1, Off = 0 } internal const string ModName = "Homestead"; internal const string ModVersion = "1.1.2"; internal const string Author = "sighsorry"; internal const string ModGUID = "sighsorry.Homestead"; internal const string DataStorageFolder = "Homestead"; internal const string BlueprintStorageFolder = "Blueprints"; internal const string ServerBlueprintStorageFolder = "ServerBlueprints"; internal const string PlanGhostStorageFolder = "PlanGhosts"; internal const string BlueprintStoreStorageFolder = "Store"; private const string ConfigFileName = "sighsorry.Homestead.cfg"; private const long ReloadDelay = 10000000L; private static readonly string ConfigFileFullPath = Path.Combine(Paths.ConfigPath, "sighsorry.Homestead.cfg"); internal static readonly string DataStorageFullPath = Path.Combine(Paths.ConfigPath, "Homestead"); internal static readonly string BlueprintStorageFullPath = Path.Combine(DataStorageFullPath, "Blueprints"); internal static readonly string ServerBlueprintStorageFullPath = Path.Combine(DataStorageFullPath, "ServerBlueprints"); internal static readonly string PlanGhostStorageFullPath = Path.Combine(ServerBlueprintStorageFullPath, "PlanGhosts"); internal static readonly string BlueprintStoreStorageFullPath = Path.Combine(ServerBlueprintStorageFullPath, "Store"); internal static readonly ManualLogSource HomesteadLogger = Logger.CreateLogSource("Homestead"); internal static readonly ConfigSync ConfigSync = new ConfigSync("sighsorry.Homestead") { DisplayName = "Homestead", CurrentVersion = "1.1.2", MinimumRequiredVersion = "1.1.2" }; internal static string ConnectionError = ""; private readonly Harmony _harmony = new Harmony("sighsorry.Homestead"); private readonly object _reloadLock = new object(); private FileSystemWatcher? _configWatcher; private DateTime _lastConfigReloadTime; internal static HomesteadPlugin Instance { get; private set; } = null; private void BindConfiguration() { BindSharedConfiguration(); BindConstructionConfiguration(); } private void BindSharedConfiguration() { GeneralConfig.Bind(this); ClientConfig.Bind(this); } private void BindConstructionConfiguration() { DvergrCircletConfig.Bind(this); PlacementControlConfig.Bind(this); BuildCameraConfig.Bind(this); BlueprintConfig.Bind(this); } public void Awake() { Instance = this; bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; BindConfiguration(); HomesteadLocalization.Load(HomesteadLogger); EnsureDataDirectories(); HomesteadFeatureBootstrap.Initialize(HomesteadLogger, _harmony); SetupWatchers(); SaveWithRespectToConfigSet(); if (saveOnConfigSet) { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; } } private void OnDestroy() { SaveWithRespectToConfigSet(); HomesteadFeatureBootstrap.Shutdown(); _configWatcher?.Dispose(); } private void Update() { HomesteadFeatureBootstrap.Update(); } private void SetupWatchers() { EnsureDataDirectories(); _configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sighsorry.Homestead.cfg"); _configWatcher.Changed += ReadConfigValues; _configWatcher.Created += ReadConfigValues; _configWatcher.Renamed += ReadConfigValues; _configWatcher.IncludeSubdirectories = false; _configWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; _configWatcher.EnableRaisingEvents = true; } private static void EnsureDataDirectories() { Directory.CreateDirectory(DataStorageFullPath); Directory.CreateDirectory(BlueprintStorageFullPath); Directory.CreateDirectory(PlanGhostStorageFullPath); Directory.CreateDirectory(BlueprintStoreStorageFullPath); } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!CanReload(ref _lastConfigReloadTime)) { return; } lock (_reloadLock) { if (!File.Exists(ConfigFileFullPath)) { HomesteadLogger.LogWarning((object)"Config file does not exist. Skipping reload."); return; } try { HomesteadLogger.LogDebug((object)"Reloading configuration..."); ReloadConfigFromDisk(); HomesteadLogger.LogInfo((object)"Configuration reload complete."); } catch (Exception arg) { HomesteadLogger.LogError((object)$"Error reloading configuration: {arg}"); } } } private static bool CanReload(ref DateTime lastReloadTime) { DateTime now = DateTime.Now; if (now.Ticks - lastReloadTime.Ticks < 10000000) { return false; } lastReloadTime = now; return true; } private void SaveWithRespectToConfigSet(bool reload = false) { bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; if (reload) { ((BaseUnityPlugin)this).Config.Reload(); } ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; } private void ReloadConfigFromDisk() { bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; ((BaseUnityPlugin)this).Config.Reload(); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; } internal ConfigEntry config(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Client Only]"), description.AcceptableValues, description.Tags); ConfigEntry val2 = ((BaseUnityPlugin)this).Config.Bind(group, name, value, val); ConfigSync.AddConfigEntry(val2).SynchronizedConfig = synchronizedSetting; return val2; } internal ConfigEntry config(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), synchronizedSetting); } } internal sealed class HomesteadCommandResult { public bool Success { get; set; } public string Message { get; set; } = ""; public static HomesteadCommandResult Ok(string message) { return new HomesteadCommandResult { Success = true, Message = message }; } public static HomesteadCommandResult Fail(string message) { return new HomesteadCommandResult { Success = false, Message = message }; } } internal static class GeneralConfig { private static ConfigEntry _serverConfigLocked; public static void Bind(HomesteadPlugin plugin) { _serverConfigLocked = plugin.config("01 - General", "Lock Configuration", HomesteadPlugin.Toggle.On, "If on, the server controls synced settings."); HomesteadPlugin.ConfigSync.AddLockingConfigEntry(_serverConfigLocked); } } internal static class ClientConfig { private static ConfigEntry _statusHudX; private static ConfigEntry _statusHudY; private static ConfigEntry _statusHudFontSize; public static Vector2 StatusHudPosition => new Vector2(Mathf.Clamp(_statusHudX.Value, 0f, 3000f), 0f - Mathf.Clamp(_statusHudY.Value, 0f, 3000f)); public static int StatusHudFontSize => Mathf.Clamp(_statusHudFontSize.Value, 10, 64); public static void Bind(HomesteadPlugin plugin) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown _statusHudX = plugin.config("02 - Client", "Status HUD X Offset", 28f, new ConfigDescription("Client-only X offset in pixels from the top-left corner for the unified status HUD.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 3000f), Array.Empty()), synchronizedSetting: false); _statusHudY = plugin.config("02 - Client", "Status HUD Y Offset", 116f, new ConfigDescription("Client-only Y offset in pixels from the top-left corner for the unified status HUD.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 3000f), Array.Empty()), synchronizedSetting: false); _statusHudFontSize = plugin.config("02 - Client", "Status HUD Font Size", 18, new ConfigDescription("Client-only font size for the unified status HUD. HUD width and height are calculated from this value.", (AcceptableValueBase)(object)new AcceptableValueRange(10, 64), Array.Empty()), synchronizedSetting: false); } } internal readonly struct BlueprintNetworkSettings { public int MaxUploadBytes { get; } public int MaxIconBytes { get; } public BlueprintNetworkSettings(int maxUploadBytes, int maxIconBytes) { MaxUploadBytes = maxUploadBytes; MaxIconBytes = maxIconBytes; } } internal readonly struct BlueprintStoreSettings { public int ListingDays { get; } public int AutoDelistMaxPurchases { get; } public int MaxListingsPerSteamId { get; } public BlueprintStoreIdentityMode IdentityMode { get; } public BlueprintStoreSettings(int listingDays, int autoDelistMaxPurchases, int maxListingsPerSteamId, BlueprintStoreIdentityMode identityMode) { ListingDays = listingDays; AutoDelistMaxPurchases = autoDelistMaxPurchases; MaxListingsPerSteamId = maxListingsPerSteamId; IdentityMode = identityMode; } } internal static class BlueprintConfig { public const int BlueprintChestRows = 40; private const int FixedMaxIconKb = 500; private const float FixedStorePanelScale = 1.8f; private static ConfigEntry _terrainSupport = null; private static ConfigEntry _chestConfirmHotkey = null; private static ConfigEntry _azuCraftyBoxesPullMode = null; private static ConfigEntry _terrainSupportContactTolerance = null; private static ConfigEntry _terrainSupportFeatherWidth = null; private static ConfigEntry _maxUploadKb = null; private static ConfigEntry _storeListingDays = null; private static ConfigEntry _storeAutoDelistMaxPurchases = null; private static ConfigEntry _storeMaxListingsPerSteamId = null; private static ConfigEntry _storeIdentityMode = null; private static ConfigEntry _chestTimeoutMinutes = null; private static ConfigEntry _chestMapIconSize = null; private static ConfigEntry _maxActiveChestsPerPlayer = null; private static ConfigEntry _storeLargePanelX = null; private static ConfigEntry _storeLargePanelY = null; private static ConfigEntry _storeFormPanelX = null; private static ConfigEntry _storeFormPanelY = null; private static ConfigEntry _storeAnonymousNotifications = null; private static ConfigEntry _storeNotificationMode = null; private static ConfigEntry _storeNotificationButtonX = null; private static ConfigEntry _storeNotificationButtonY = null; private static ConfigEntry _storeListModifierKey = null; private static ConfigEntry _storeBackHotkey = null; private static ConfigEntry _areaSaveMaxSide = null; private static ConfigEntry _areaSaveDefaultWidth = null; private static ConfigEntry _areaSaveDefaultDepth = null; private static ConfigEntry _areaSaveCreatorMode = null; private static ConfigEntry _areaDismantleMaxSide = null; private static ConfigEntry _areaDismantleDefaultWidth = null; private static ConfigEntry _areaDismantleDefaultDepth = null; private static ConfigEntry _areaDismantlePrefabBlacklist = null; private static ConfigEntry _areaToolDepthModifierKey = null; private static ConfigEntry _areaToolWidthModifierKey = null; private static ConfigEntry _previewGhostColor = null; private static readonly HashSet BuiltInAreaDismantleProtectedPrefabs = new HashSet(StringComparer.OrdinalIgnoreCase) { "piece_chest_wood_blueprint", "piece_chest_barrel_blueprint_store_price", "piece_chest_blueprint_store_purchase", "piece_chest_blackmetal_blueprint_store_payout" }; public static bool TerrainSupportEnabled => _terrainSupport.Value == BlueprintTerrainSupportMode.On; public static KeyboardShortcut ChestConfirmHotkey => _chestConfirmHotkey.Value; public static bool AzuCraftyBoxesPullOnConfirm => _azuCraftyBoxesPullMode.Value != BlueprintAzuCraftyBoxesPullMode.Off; public static bool AzuCraftyBoxesPullOnOpen => _azuCraftyBoxesPullMode.Value == BlueprintAzuCraftyBoxesPullMode.OpenAndConfirm; public static float TerrainSupportContactTolerance => Mathf.Clamp(_terrainSupportContactTolerance.Value, 0.01f, 2f); public static float TerrainSupportFeatherWidth => Mathf.Clamp(_terrainSupportFeatherWidth.Value, 0f, 64f); public static int MaxUploadKb => Mathf.Clamp(_maxUploadKb.Value, 64, 16384); public static int MaxUploadBytes => MaxUploadKb * 1024; public static int MaxIconBytes => 512000; public static BlueprintNetworkSettings NetworkSettings => new BlueprintNetworkSettings(MaxUploadBytes, MaxIconBytes); public static int StoreListingDays => Mathf.Clamp(_storeListingDays.Value, 0, 365); public static int StoreAutoDelistMaxPurchases => Mathf.Clamp(_storeAutoDelistMaxPurchases.Value, 0, 100000); public static int StoreMaxListingsPerSteamId => Mathf.Clamp(_storeMaxListingsPerSteamId.Value, 1, 200); public static BlueprintStoreIdentityMode StoreIdentityMode => _storeIdentityMode.Value; public static BlueprintStoreSettings StoreSettings => new BlueprintStoreSettings(StoreListingDays, StoreAutoDelistMaxPurchases, StoreMaxListingsPerSteamId, StoreIdentityMode); public static int ChestTimeoutMinutes => Mathf.Clamp(_chestTimeoutMinutes.Value, 0, 60); public static int ChestMapIconSize => Mathf.Clamp(_chestMapIconSize.Value, 0, 10); public static int MaxActiveChestsPerPlayer => Mathf.Clamp(_maxActiveChestsPerPlayer.Value, 0, 50); public static float StoreLargePanelScale => 1.8f; public static Vector2 StoreLargePanelOffset => new Vector2(Mathf.Clamp(_storeLargePanelX.Value, -2000f, 2000f), Mathf.Clamp(_storeLargePanelY.Value, -2000f, 2000f)); public static float StoreFormPanelScale => 1.8f; public static Vector2 StoreFormPanelOffset => new Vector2(Mathf.Clamp(_storeFormPanelX.Value, -2000f, 2000f), Mathf.Clamp(_storeFormPanelY.Value, -2000f, 2000f)); public static float StoreUiScale => StoreLargePanelScale; public static int StoreNotificationPollSeconds { get { if (!StoreNotificationsEnabled) { return 0; } return 900; } } public static BlueprintStoreNotificationMode StoreNotificationMode => _storeNotificationMode.Value; public static bool StoreNotificationsEnabled => StoreNotificationMode != BlueprintStoreNotificationMode.Off; public static bool StoreNotificationAutoOpen => StoreNotificationMode == BlueprintStoreNotificationMode.AutoOpenPanel; public static bool StoreAnonymousNotifications => _storeAnonymousNotifications.Value.IsOn(); public static bool StoreNotificationButtonEnabled => StoreNotificationsEnabled; public static Vector2 StoreNotificationButtonOffset => new Vector2(Mathf.Clamp(_storeNotificationButtonX.Value, -3000f, 3000f), Mathf.Clamp(_storeNotificationButtonY.Value, -3000f, 3000f)); public static KeyboardShortcut StoreListModifierKey => _storeListModifierKey.Value; public static string StoreListModifierLabel => ConfigValueHelpers.FormatShortcut(StoreListModifierKey); public static KeyboardShortcut StoreBackHotkey => _storeBackHotkey.Value; public static string StoreBackHotkeyLabel => ConfigValueHelpers.FormatShortcut(StoreBackHotkey); public static Color StoreListingPreviewColor => PreviewGhostColor; public static Color StorePurchasePreviewColor => PreviewGhostColor; public static float AreaSaveMaxSide => Mathf.Clamp(_areaSaveMaxSide.Value, 2f, 256f); public static float AreaSaveDefaultWidth => Mathf.Clamp(_areaSaveDefaultWidth.Value, 2f, AreaSaveMaxSide); public static float AreaSaveDefaultDepth => Mathf.Clamp(_areaSaveDefaultDepth.Value, 2f, AreaSaveMaxSide); public static BlueprintAreaSaveCreatorMode AreaSaveCreatorMode => _areaSaveCreatorMode.Value; public static string AreaSaveEligibleTargetLabel => AreaSaveCreatorMode switch { BlueprintAreaSaveCreatorMode.AllCreators => "WearNTear", BlueprintAreaSaveCreatorMode.OwnedAndCreatorless => "owned or creatorless WearNTear", _ => "owned WearNTear", }; public static Color AreaSaveBoundaryColor => new Color(1f, 0.9f, 0.2f, 0.9f); public static float AreaDismantleMaxSide => Mathf.Clamp(_areaDismantleMaxSide.Value, 1f, 128f); public static float AreaDismantleDefaultWidth => Mathf.Clamp(_areaDismantleDefaultWidth.Value, 1f, AreaDismantleMaxSide); public static float AreaDismantleDefaultDepth => Mathf.Clamp(_areaDismantleDefaultDepth.Value, 1f, AreaDismantleMaxSide); public static Color AreaDismantleBoundaryColor => new Color(1f, 0.3f, 0.12f, 0.9f); public static HashSet AreaDismantlePrefabBlacklist => ConfigValueHelpers.SplitPrefabList(_areaDismantlePrefabBlacklist.Value); public static KeyboardShortcut AreaToolDepthModifierKey => _areaToolDepthModifierKey.Value; public static string AreaToolDepthModifierLabel => ConfigValueHelpers.FormatShortcut(AreaToolDepthModifierKey); public static string AreaToolDepthInputLabel { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) KeyboardShortcut areaToolDepthModifierKey = AreaToolDepthModifierKey; if ((int)((KeyboardShortcut)(ref areaToolDepthModifierKey)).MainKey != 0) { return AreaToolDepthModifierLabel + "+Wheel"; } return ""; } } public static KeyboardShortcut AreaToolWidthModifierKey => _areaToolWidthModifierKey.Value; public static string AreaToolWidthModifierLabel => ConfigValueHelpers.FormatShortcut(AreaToolWidthModifierKey); public static string AreaToolWidthInputLabel { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) KeyboardShortcut areaToolWidthModifierKey = AreaToolWidthModifierKey; if ((int)((KeyboardShortcut)(ref areaToolWidthModifierKey)).MainKey != 0) { return AreaToolWidthModifierLabel + "+Wheel"; } return ""; } } public static Color PreviewGhostColor => ClampPreviewColor(_previewGhostColor.Value); public static void SetStoreLargePanelOffset(Vector2 offset) { //IL_0005: 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) _storeLargePanelX.Value = Mathf.Clamp(offset.x, -2000f, 2000f); _storeLargePanelY.Value = Mathf.Clamp(offset.y, -2000f, 2000f); } public static void SetStoreFormPanelOffset(Vector2 offset) { //IL_0005: 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) _storeFormPanelX.Value = Mathf.Clamp(offset.x, -2000f, 2000f); _storeFormPanelY.Value = Mathf.Clamp(offset.y, -2000f, 2000f); } public static void SetStoreNotificationButtonOffset(Vector2 offset) { //IL_0005: 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) _storeNotificationButtonX.Value = Mathf.Clamp(offset.x, -3000f, 3000f); _storeNotificationButtonY.Value = Mathf.Clamp(offset.y, -3000f, 3000f); } public static bool IsStoreListModifierHeld() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ConfigValueHelpers.IsShortcutHeld(StoreListModifierKey, allowUnbound: true); } public static bool IsStoreBackHotkeyDown() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ConfigValueHelpers.IsShortcutDown(StoreBackHotkey); } public static bool AreaSaveAllowsCreator(long playerId, long creator) { if (creator == playerId) { return true; } return AreaSaveCreatorMode switch { BlueprintAreaSaveCreatorMode.AllCreators => true, BlueprintAreaSaveCreatorMode.OwnedAndCreatorless => creator == 0, _ => false, }; } public static bool ShouldApplyTerrainSupport(Player player) { return _terrainSupport.Value switch { BlueprintTerrainSupportMode.On => true, BlueprintTerrainSupportMode.AdminDebug => IsAdminDebugPlayer(player), _ => false, }; } public static void Bind(HomesteadPlugin plugin) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0094: 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_00c8: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Expected O, but got Unknown //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Expected O, but got Unknown //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Expected O, but got Unknown //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Expected O, but got Unknown //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Expected O, but got Unknown //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Expected O, but got Unknown //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Expected O, but got Unknown //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Expected O, but got Unknown //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Expected O, but got Unknown //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Expected O, but got Unknown //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Expected O, but got Unknown //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_0528: Expected O, but got Unknown //IL_055d: Unknown result type (might be due to invalid IL or missing references) //IL_0568: Expected O, but got Unknown //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_05a8: Expected O, but got Unknown //IL_05eb: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Expected O, but got Unknown //IL_0639: Unknown result type (might be due to invalid IL or missing references) //IL_0644: Expected O, but got Unknown //IL_065e: Unknown result type (might be due to invalid IL or missing references) //IL_0687: Unknown result type (might be due to invalid IL or missing references) //IL_0692: Expected O, but got Unknown //IL_06ac: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06e0: Expected O, but got Unknown //IL_070e: Unknown result type (might be due to invalid IL or missing references) //IL_0719: Expected O, but got Unknown //IL_0747: Unknown result type (might be due to invalid IL or missing references) //IL_0752: Expected O, but got Unknown //IL_079c: Unknown result type (might be due to invalid IL or missing references) //IL_07a7: Expected O, but got Unknown //IL_07d5: Unknown result type (might be due to invalid IL or missing references) //IL_07e0: Expected O, but got Unknown //IL_080e: Unknown result type (might be due to invalid IL or missing references) //IL_0819: Expected O, but got Unknown //IL_0858: Unknown result type (might be due to invalid IL or missing references) //IL_0882: Unknown result type (might be due to invalid IL or missing references) //IL_08b6: Unknown result type (might be due to invalid IL or missing references) //IL_08df: Unknown result type (might be due to invalid IL or missing references) //IL_08ea: Expected O, but got Unknown _areaSaveMaxSide = plugin.config("06 - Area Tools", "Area Save Max Side Length", 64f, new ConfigDescription("Server-synced maximum side length in meters for the hammer Area Save blueprint rectangle.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 256f), Array.Empty())); _terrainSupport = plugin.config("07 - Blueprint", "Terrain Support", BlueprintTerrainSupportMode.Off, new ConfigDescription("Controls native blueprint terrain support. Off only places WearNTear. On restores saved terrain support contacts for everyone. AdminDebug restores terrain support only when the placing player is admin and has debug/no-cost build enabled.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 930 } })); _chestConfirmHotkey = plugin.config("07 - Blueprint", "Blueprint Chest Confirm Hotkey", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new ConfigDescription("Client-only hotkey for confirming a Homestead blueprint chest. The default is Alt+E.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1000 } }), synchronizedSetting: false); _azuCraftyBoxesPullMode = plugin.config("07 - Blueprint", "AzuCraftyBoxes Pull Mode", BlueprintAzuCraftyBoxesPullMode.ConfirmOnly, new ConfigDescription("If AzuCraftyBoxes is installed, pulls missing blueprint materials from nearby allowed containers. ConfirmOnly pulls when confirming the blueprint. OpenAndConfirm also pulls before opening the blueprint chest.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 940 } })); _terrainSupportContactTolerance = plugin.config("07 - Blueprint", "Blueprint Terrain Support Contact Tolerance", 0.5f, new ConfigDescription("How close terrain must be to the lowest WearNTear bottom at a 1m x/z cell to be saved as a blueprint terrain support contact.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 2f), new object[1] { new ConfigurationManagerAttributes { Order = 920 } })); _terrainSupportFeatherWidth = plugin.config("07 - Blueprint", "Blueprint Terrain Support Feather Width", 6f, new ConfigDescription("Meters around blueprint terrain support contact footprints that blend back to native terrain. Set to 0 to only change exact contact cells.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 64f), new object[1] { new ConfigurationManagerAttributes { Order = 910 } })); _maxUploadKb = plugin.config("07 - Blueprint", "Max Blueprint Upload KB", 2048, new ConfigDescription("Server-synced maximum uncompressed blueprint text size for a client blueprint upload. This is checked before blueprint parsing.", (AcceptableValueBase)(object)new AcceptableValueRange(64, 16384), new object[1] { new ConfigurationManagerAttributes { Order = 950 } })); _storeListingDays = plugin.config("08 - Blueprint Store", "Blueprint Store Listing Days", 0, new ConfigDescription("How many days a blueprint store listing stays visible from the time it is listed before the server can automatically hide it. Set to 0 to disable automatic delisting.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 365), new object[1] { new ConfigurationManagerAttributes { Order = 1000 } })); _storeAutoDelistMaxPurchases = plugin.config("08 - Blueprint Store", "Blueprint Store Auto Delist Max Purchases", 0, new ConfigDescription("Only listings with this many purchases or fewer are automatically hidden after Blueprint Store Listing Days. Default 0 means only listings with no purchases are auto-delisted.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100000), new object[1] { new ConfigurationManagerAttributes { Order = 990 } })); _storeMaxListingsPerSteamId = plugin.config("08 - Blueprint Store", "Blueprint Store Max Listings Per SteamID", 10, new ConfigDescription("Server-synced maximum active blueprint store listings allowed for one SteamID/platform identity.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 200), new object[1] { new ConfigurationManagerAttributes { Order = 980 } })); _storeIdentityMode = plugin.config("08 - Blueprint Store", "Blueprint Store Identity Mode", BlueprintStoreIdentityMode.PlayerId, new ConfigDescription("Controls how Blueprint Store ownership and offer buyer permissions are matched. PlayerId treats each Valheim character separately. SteamId treats every character on the same Steam/platform account as the same store identity.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 960 } })); _chestTimeoutMinutes = plugin.config("07 - Blueprint", "Blueprint Chest Timeout Minutes", 30, new ConfigDescription("Minutes since last interaction before empty Homestead blueprint/build/store chests are removed. Set to 0 to disable automatic chest cleanup. A chest is kept while it has visible items, absorbed materials, price items, purchase deposits, or payout contents.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 60), new object[1] { new ConfigurationManagerAttributes { Order = 970 } })); _chestMapIconSize = plugin.config("07 - Blueprint", "Blueprint Chest Map Icon Size", 1, new ConfigDescription("Client-only icon size for your Homestead blueprint/build/store chests on the large map. Set to 0 to hide these map icons.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 10), new object[1] { new ConfigurationManagerAttributes { Order = 990 } }), synchronizedSetting: false); _maxActiveChestsPerPlayer = plugin.config("07 - Blueprint", "Max Active Blueprint Chests Per SteamID", 5, new ConfigDescription("Maximum active Homestead blueprint/build/store chests per Steam/platform identity. Set to 0 to disable this limit. If a platform identity cannot be resolved, Homestead falls back to the Valheim playerID.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 50), new object[1] { new ConfigurationManagerAttributes { Order = 960 } })); _storeLargePanelX = plugin.config("08 - Blueprint Store", "Blueprint Store Large Panel X Offset", 0f, new ConfigDescription("Hidden client-only X offset from screen center for the Blueprint Store listing and offers panels. Use the in-game panel drag instead of editing this manually.", (AcceptableValueBase)(object)new AcceptableValueRange(-2000f, 2000f), new object[1] { new ConfigurationManagerAttributes { Browsable = false } }), synchronizedSetting: false); _storeLargePanelY = plugin.config("08 - Blueprint Store", "Blueprint Store Large Panel Y Offset", 0f, new ConfigDescription("Hidden client-only Y offset from screen center for the Blueprint Store listing and offers panels. Use the in-game panel drag instead of editing this manually.", (AcceptableValueBase)(object)new AcceptableValueRange(-2000f, 2000f), new object[1] { new ConfigurationManagerAttributes { Browsable = false } }), synchronizedSetting: false); _storeFormPanelX = plugin.config("08 - Blueprint Store", "Blueprint Store Form Panel X Offset", 0f, new ConfigDescription("Hidden client-only X offset from screen center for Blueprint Store form panels. Use the in-game panel drag instead of editing this manually.", (AcceptableValueBase)(object)new AcceptableValueRange(-2000f, 2000f), new object[1] { new ConfigurationManagerAttributes { Browsable = false } }), synchronizedSetting: false); _storeFormPanelY = plugin.config("08 - Blueprint Store", "Blueprint Store Form Panel Y Offset", 0f, new ConfigDescription("Hidden client-only Y offset from screen center for Blueprint Store form panels. Use the in-game panel drag instead of editing this manually.", (AcceptableValueBase)(object)new AcceptableValueRange(-2000f, 2000f), new object[1] { new ConfigurationManagerAttributes { Browsable = false } }), synchronizedSetting: false); _storeNotificationMode = plugin.config("08 - Blueprint Store", "Blueprint Store Notification Mode", BlueprintStoreNotificationMode.BadgeOnly, new ConfigDescription("Client-only display mode for Blueprint Store notifications. Off hides the notification button and disables fallback polling. BadgeOnly keeps the button and unread count visible without opening the panel automatically. AutoOpenPanel opens the notification panel when a new unread notification arrives.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 950 } }), synchronizedSetting: false); _storeAnonymousNotifications = plugin.config("08 - Blueprint Store", "Blueprint Store Anonymous Notifications", HomesteadPlugin.Toggle.Off, new ConfigDescription("Server-synced toggle for hiding player names in Blueprint Store notification messages. When on, notifications say Anonymous instead of the buyer, seller, or offer creator name.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 970 } })); _storeNotificationButtonX = plugin.config("08 - Blueprint Store", "Blueprint Store Notification Button X Offset", -333f, new ConfigDescription("Hidden client-only default/current X offset for the floating Blueprint Store notification button from the top-right screen anchor. Dragging the in-game button also updates this value.", (AcceptableValueBase)(object)new AcceptableValueRange(-3000f, 3000f), new object[1] { new ConfigurationManagerAttributes { Browsable = false } }), synchronizedSetting: false); _storeNotificationButtonY = plugin.config("08 - Blueprint Store", "Blueprint Store Notification Button Y Offset", -55f, new ConfigDescription("Hidden client-only default/current Y offset for the floating Blueprint Store notification button from the top-right screen anchor. Dragging the in-game button also updates this value.", (AcceptableValueBase)(object)new AcceptableValueRange(-3000f, 3000f), new object[1] { new ConfigurationManagerAttributes { Browsable = false } }), synchronizedSetting: false); _storeListModifierKey = plugin.config("08 - Blueprint Store", "Blueprint Store List Modifier Key", new KeyboardShortcut((KeyCode)308, Array.Empty()), new ConfigDescription("Client-only modifier key held while left-clicking a blueprint in the Homestead build tab to place its Blueprint Store price chest. Set to None to use left-click without a modifier.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 940 } }), synchronizedSetting: false); _storeBackHotkey = plugin.config("08 - Blueprint Store", "Blueprint Store Back Hotkey", new KeyboardShortcut((KeyCode)326, Array.Empty()), new ConfigDescription("Client-only hotkey for returning from Blueprint Store sub-panels such as the offers view. Display uses the same Unity key names as Config Manager.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 930 } }), synchronizedSetting: false); _areaSaveDefaultWidth = plugin.config("06 - Area Tools", "Area Save Default Width", 8f, new ConfigDescription("Client-only default Area Save rectangle width. This is clamped by the server max side length.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 256f), Array.Empty()), synchronizedSetting: false); _areaSaveDefaultDepth = plugin.config("06 - Area Tools", "Area Save Default Depth", 8f, new ConfigDescription("Client-only default Area Save rectangle depth. Set a different value from width to start as a rectangle.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 256f), Array.Empty()), synchronizedSetting: false); _areaSaveCreatorMode = plugin.config("06 - Area Tools", "Area Save Creator Mode", BlueprintAreaSaveCreatorMode.OwnedAndCreatorless, "Controls which WearNTear objects the Area Save tool can select. AllCreators saves your own, creator=0, and other creators' WearNTear. OwnedAndCreatorless saves your own plus creator=0 WearNTear. OwnedOnly saves only WearNTear with your playerID."); _areaDismantleMaxSide = plugin.config("06 - Area Tools", "Area Dismantle Max Side Length", 8f, new ConfigDescription("Server-synced maximum side length in meters for the hammer Area Dismantle rectangle.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 128f), Array.Empty())); _areaDismantleDefaultWidth = plugin.config("06 - Area Tools", "Area Dismantle Default Width", 4f, new ConfigDescription("Client-only default Area Dismantle rectangle width. This is clamped by the server max side length.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 128f), Array.Empty()), synchronizedSetting: false); _areaDismantleDefaultDepth = plugin.config("06 - Area Tools", "Area Dismantle Default Depth", 4f, new ConfigDescription("Client-only default Area Dismantle rectangle depth. Set a different value from width to start as a rectangle.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 128f), Array.Empty()), synchronizedSetting: false); _areaDismantlePrefabBlacklist = plugin.config("06 - Area Tools", "Area Dismantle Prefab Blacklist", "piece_stuward", "Comma-separated additional prefab names that Area Dismantle will never dismantle. Homestead blueprint/store chests are always protected internally."); PruneBuiltInAreaDismantleBlacklistEntries(); _areaToolDepthModifierKey = plugin.config("06 - Area Tools", "Area Tool Depth Modifier Key", new KeyboardShortcut((KeyCode)326, Array.Empty()), "Client-only modifier key held while using the mouse wheel to resize only the depth of Area Save and Area Dismantle rectangles. Set to None to disable depth-only wheel resizing.", synchronizedSetting: false); _areaToolWidthModifierKey = plugin.config("06 - Area Tools", "Area Tool Width Modifier Key", new KeyboardShortcut((KeyCode)327, Array.Empty()), "Client-only modifier key held while using the mouse wheel to resize only the width of Area Save and Area Dismantle rectangles. Set to None to disable width-only wheel resizing.", synchronizedSetting: false); _previewGhostColor = plugin.config("07 - Blueprint", "Preview Ghost Color", new Color(1f, 1f, 1f, 0.25f), new ConfigDescription("Client-only color for unfinished blueprint preview pieces.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 980 } }), synchronizedSetting: false); } private static bool IsAdminDebugPlayer(Player player) { if ((Object)(object)player != (Object)null && player.NoCostCheat()) { return IsAdminPlayer(player); } return false; } private static bool IsAdminPlayer(Player player) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)player == (Object)null) { return false; } if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { return ZNet.instance.LocalPlayerIsAdminOrHost(); } if (ZDOMan.instance == null) { return false; } long playerID = player.GetPlayerID(); if (playerID == 0L) { return false; } foreach (ZNetPeer peer in ZNet.instance.m_peers) { if (peer == null || !peer.IsReady() || ((ZDOID)(ref peer.m_characterID)).IsNone()) { continue; } ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); if (zDO != null && zDO.GetLong(ZDOVars.s_playerID, 0L) == playerID) { ZRpc rpc = peer.m_rpc; object obj; if (rpc == null) { obj = null; } else { ISocket socket = rpc.m_socket; obj = ((socket != null) ? socket.GetHostName() : null); } if (obj == null) { obj = ""; } string text = (string)obj; return text.Length > 0 && ZNet.instance.IsAdmin(text); } } return false; } private static void PruneBuiltInAreaDismantleBlacklistEntries() { List list = (from entry in (_areaDismantlePrefabBlacklist.Value ?? "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries) select entry.Trim() into entry where !string.IsNullOrWhiteSpace(entry) select entry).ToList(); List list2 = list.Where((string entry) => !BuiltInAreaDismantleProtectedPrefabs.Contains(entry)).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); if (list2.Count != list.Count || !list2.SequenceEqual(list, StringComparer.OrdinalIgnoreCase)) { _areaDismantlePrefabBlacklist.Value = string.Join(",", list2); } } private static Color ClampPreviewColor(Color value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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) //IL_0028: 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_004a: Unknown result type (might be due to invalid IL or missing references) Color val = value; val.r = Mathf.Clamp01(val.r); val.g = Mathf.Clamp01(val.g); val.b = Mathf.Clamp01(val.b); val.a = Mathf.Clamp01(val.a); return val; } } internal static class BuildCameraConfig { private static ConfigEntry _enabled; private static ConfigEntry _resourcePickupRange; private static ConfigEntry _resourcePickupRangePerComfortLevel; private static ConfigEntry _maxPlaceDistance; private static ConfigEntry _maxPlaceDistancePerComfortLevel; private static ConfigEntry _baseDistanceFromAvatar; private static ConfigEntry _distancePerComfortLevel; private static ConfigEntry _moveSpeedMultiplier; private static ConfigEntry _toggleHotkey; private static ConfigEntry _lookAtLockHotkey; private static ConfigEntry _minimumComfortLevel; private static ConfigEntry _helmetLightOffsetForward; private static ConfigEntry _helmetLightOffsetUp; public static bool Enabled => _enabled.Value.IsOn(); public static float ResourcePickupRange => Mathf.Clamp(_resourcePickupRange.Value, 0f, 100f); public static float ResourcePickupRangePerComfortLevel => Mathf.Clamp(_resourcePickupRangePerComfortLevel.Value, 0f, 10f); public static float MaxPlaceDistance => Mathf.Clamp(_maxPlaceDistance.Value, 5f, 100f); public static float MaxPlaceDistancePerComfortLevel => Mathf.Clamp(_maxPlaceDistancePerComfortLevel.Value, 0f, 10f); public static float BaseDistanceFromAvatar => Mathf.Clamp(_baseDistanceFromAvatar.Value, 1f, 500f); public static float DistancePerComfortLevel => Mathf.Clamp(_distancePerComfortLevel.Value, 0f, 50f); public static float MoveSpeedMultiplier => Mathf.Clamp(_moveSpeedMultiplier.Value, 0.1f, 20f); public static KeyboardShortcut ToggleHotkey => _toggleHotkey.Value; public static KeyboardShortcut LookAtLockHotkey => _lookAtLockHotkey.Value; public static int MinimumComfortLevel => Mathf.Clamp(_minimumComfortLevel.Value, 0, 30); public static float HelmetLightOffsetForward => Mathf.Clamp(_helmetLightOffsetForward.Value, -5f, 5f); public static float HelmetLightOffsetUp => Mathf.Clamp(_helmetLightOffsetUp.Value, -5f, 5f); public static void Bind(HomesteadPlugin plugin) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Expected O, but got Unknown //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Expected O, but got Unknown //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Expected O, but got Unknown //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Expected O, but got Unknown //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Expected O, but got Unknown //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Expected O, but got Unknown //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Expected O, but got Unknown _enabled = plugin.config("05 - Build Camera", "Enabled", HomesteadPlugin.Toggle.On, new ConfigDescription("If on, Homestead includes BuildCameraCHE-style free build camera mode. Disable this if the standalone BuildCameraCHE mod is installed.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1000 } })); _minimumComfortLevel = plugin.config("05 - Build Camera", "Restriction Mode Minimum Comfort Level", 1, new ConfigDescription("Minimum comfort level required to enter and stay in build camera mode. Set to 0 to disable the comfort restriction.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 30), new object[1] { new ConfigurationManagerAttributes { Order = 990 } })); _baseDistanceFromAvatar = plugin.config("05 - Build Camera", "Base Camera Distance From Avatar", 32f, new ConfigDescription("Base distance in meters that the build camera can move away from your player avatar before comfort scaling is added.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 500f), new object[1] { new ConfigurationManagerAttributes { Order = 980 } })); _distancePerComfortLevel = plugin.config("05 - Build Camera", "Camera Distance Per Comfort Level", 3f, new ConfigDescription("Extra build camera distance in meters added for each current comfort level. Set to 0 to use a fixed camera distance.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 50f), new object[1] { new ConfigurationManagerAttributes { Order = 970 } })); _maxPlaceDistance = plugin.config("05 - Build Camera", "Max Place Distance", 5f, new ConfigDescription("Base Player.m_maxPlaceDistance in meters while build camera mode is active. Valheim default is 5.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 100f), new object[1] { new ConfigurationManagerAttributes { Order = 960 } })); _maxPlaceDistancePerComfortLevel = plugin.config("05 - Build Camera", "Max Place Distance Per Comfort Level", 2f, new ConfigDescription("Extra Player.m_maxPlaceDistance in meters added for each current comfort level while build camera mode is active.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 10f), new object[1] { new ConfigurationManagerAttributes { Order = 950 } })); _resourcePickupRange = plugin.config("05 - Build Camera", "Resource Pickup Range", 2f, new ConfigDescription("Base distance in meters from which build camera mode can pick up resources on the ground. Valheim default is 2.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), new object[1] { new ConfigurationManagerAttributes { Order = 940 } })); _resourcePickupRangePerComfortLevel = plugin.config("05 - Build Camera", "Resource Pickup Range Per Comfort Level", 0.5f, new ConfigDescription("Extra build camera resource pickup range in meters added for each current comfort level.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 10f), new object[1] { new ConfigurationManagerAttributes { Order = 930 } })); _moveSpeedMultiplier = plugin.config("05 - Build Camera", "Camera Move Speed Multiplier", 3f, new ConfigDescription("Multiplies build camera panning speed.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 20f), new object[1] { new ConfigurationManagerAttributes { Order = 920 } })); _toggleHotkey = plugin.config("05 - Build Camera", "Toggle Build Camera Hotkey", new KeyboardShortcut((KeyCode)98, Array.Empty()), new ConfigDescription("Client-only hotkey that toggles build camera mode while a build tool is equipped.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 910 } }), synchronizedSetting: false); _lookAtLockHotkey = plugin.config("05 - Build Camera", "Look At Lock Hotkey", new KeyboardShortcut((KeyCode)113, Array.Empty()), new ConfigDescription("Client-only hotkey that toggles build camera look-at lock while build camera mode is active.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 900 } }), synchronizedSetting: false); _helmetLightOffsetForward = plugin.config("02 - Client", "Dvergr Circlet Light Forward Offset", 0.65f, new ConfigDescription("Client-only Dvergr circlet light offset along the build camera forward axis.", (AcceptableValueBase)(object)new AcceptableValueRange(-5f, 5f), Array.Empty()), synchronizedSetting: false); _helmetLightOffsetUp = plugin.config("02 - Client", "Dvergr Circlet Light Up Offset", -0.08f, new ConfigDescription("Client-only Dvergr circlet light offset along the build camera up axis.", (AcceptableValueBase)(object)new AcceptableValueRange(-5f, 5f), Array.Empty()), synchronizedSetting: false); } } internal static class PlacementControlConfig { private static ConfigEntry _gridSnapToggleHotkey; private static ConfigEntry _gridSnapSize; private static ConfigEntry _placementAdjustEnabled; private static ConfigEntry _placementAdjustHeightStep; private static ConfigEntry _placementAdjustHorizontalStep; private static ConfigEntry _placementRotationStep; private static ConfigEntry _placementXAxisRotation; private static ConfigEntry _placementZAxisRotation; private static ConfigEntry _placementAdjustModifierKey; public static KeyboardShortcut GridSnapToggleHotkey => _gridSnapToggleHotkey.Value; public static float GridSnapSize => Mathf.Round(Mathf.Clamp(_gridSnapSize.Value, 0.05f, 1f) * 20f) / 20f; public static bool PlacementAdjustEnabled => _placementAdjustEnabled.Value.IsOn(); public static float HeightStep => Mathf.Clamp(_placementAdjustHeightStep.Value, 0.01f, 10f); public static float HorizontalStep => Mathf.Clamp(_placementAdjustHorizontalStep.Value, 0.01f, 10f); public static float RotationStep => RoundHalfDegree(Mathf.Clamp(_placementRotationStep.Value, 0.5f, 90f)); public static float XAxisRotation => RoundHalfDegree(Mathf.Clamp(_placementXAxisRotation.Value, -180f, 180f)); public static float ZAxisRotation => RoundHalfDegree(Mathf.Clamp(_placementZAxisRotation.Value, -180f, 180f)); public static bool HasPlacementAxisRotation { get { if (!(Mathf.Abs(XAxisRotation) > 0.001f)) { return Mathf.Abs(ZAxisRotation) > 0.001f; } return true; } } public static KeyboardShortcut PlacementAdjustModifierKey => _placementAdjustModifierKey.Value; public static string PlacementAdjustModifierLabel => ConfigValueHelpers.FormatShortcut(PlacementAdjustModifierKey); public static string AreaUniformScaleInputLabel { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) KeyboardShortcut placementAdjustModifierKey = PlacementAdjustModifierKey; if ((int)((KeyboardShortcut)(ref placementAdjustModifierKey)).MainKey != 0) { return PlacementAdjustModifierLabel + "+Wheel"; } return ""; } } public static bool IsAreaDepthModifierHeld() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ConfigValueHelpers.IsShortcutHeld(BlueprintConfig.AreaToolDepthModifierKey, allowUnbound: false); } public static bool IsAreaWidthModifierHeld() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ConfigValueHelpers.IsShortcutHeld(BlueprintConfig.AreaToolWidthModifierKey, allowUnbound: false); } public static bool IsAreaUniformScaleModifierHeld() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_000f: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut placementAdjustModifierKey = PlacementAdjustModifierKey; if ((int)((KeyboardShortcut)(ref placementAdjustModifierKey)).MainKey != 0) { return ConfigValueHelpers.IsShortcutHeld(PlacementAdjustModifierKey, allowUnbound: false); } return false; } public static bool IsPlacementAdjustModifierHeld() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ConfigValueHelpers.IsShortcutHeld(PlacementAdjustModifierKey, allowUnbound: true); } public static void Bind(HomesteadPlugin plugin) { //IL_0012: 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_005b: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) _gridSnapToggleHotkey = plugin.config("04 - Placement Controls", "Grid Snap Toggle Hotkey", new KeyboardShortcut((KeyCode)103, Array.Empty()), "Client-only hotkey that toggles grid snapping on or off while placing build pieces. The default is G.", synchronizedSetting: false); _gridSnapSize = plugin.config("04 - Placement Controls", "Grid Size", 0.5f, new ConfigDescription("Client-only grid spacing in meters. Values are clamped and rounded to 0.05m steps between 0.05 and 1.0.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 1f), Array.Empty()), synchronizedSetting: false); _placementAdjustEnabled = plugin.config("04 - Placement Controls", "Position Adjust", HomesteadPlugin.Toggle.On, "If on, hammer pieces, Homestead blueprints, and area tools can be nudged with PgUp/PgDn and arrow keys."); _placementAdjustHeightStep = plugin.config("04 - Placement Controls", "Position Height Step", 0.5f, new ConfigDescription("Client-only vertical offset step in meters for PgUp/PgDn while adjusting placement.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 10f), Array.Empty()), synchronizedSetting: false); _placementAdjustHorizontalStep = plugin.config("04 - Placement Controls", "Position Horizontal Step", 0.5f, new ConfigDescription("Client-only horizontal offset step in meters for arrow keys while adjusting placement.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 10f), Array.Empty()), synchronizedSetting: false); _placementRotationStep = plugin.config("04 - Placement Controls", "Rotation Step", 22.5f, new ConfigDescription("Client-only rotation step in degrees shared by Area Save, Area Dismantle, blueprint yaw rotation, and placement rotation controls. Values are rounded to 0.5 degree steps.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 90f), Array.Empty()), synchronizedSetting: false); _placementXAxisRotation = plugin.config("04 - Placement Controls", "X Axis Rotation", 0f, new ConfigDescription("Client-only default X-axis rotation in degrees applied to ordinary hammer build piece previews and final placement. Terrain tools and Homestead area tools are ignored. Values are rounded to 0.5 degree steps.", (AcceptableValueBase)(object)new AcceptableValueRange(-180f, 180f), Array.Empty()), synchronizedSetting: false); _placementZAxisRotation = plugin.config("04 - Placement Controls", "Z Axis Rotation", 0f, new ConfigDescription("Client-only default Z-axis rotation in degrees applied to ordinary hammer build piece previews and final placement. Terrain tools and Homestead area tools are ignored. Values are rounded to 0.5 degree steps.", (AcceptableValueBase)(object)new AcceptableValueRange(-180f, 180f), Array.Empty()), synchronizedSetting: false); _placementAdjustModifierKey = plugin.config("04 - Placement Controls", "Position Adjust Modifier Key", new KeyboardShortcut((KeyCode)308, Array.Empty()), "Client-only modifier key held while using PgUp/PgDn and arrow keys for placement offsets. Set to None to allow the old unmodified keys.", synchronizedSetting: false); } private static float RoundHalfDegree(float value) { return Mathf.Round(value * 2f) / 2f; } } internal static class DvergrCircletConfig { public const float MaxDurability = 100f; public const float PerItemMinMultiplier = 1f; private static ConfigEntry _extensionEnabled; private static ConfigEntry _fuelMinutes; private static ConfigEntry _repairStation; private static ConfigEntry _perItemMaxIntensityMultiplier; private static ConfigEntry _perItemMaxRangeMultiplier; private static ConfigEntry _perItemAdjustmentStep; private static ConfigEntry _toggleLightHotkey; private static ConfigEntry _adjustmentModifierKey; public static bool ExtensionEnabled => _extensionEnabled.Value.IsOn(); public static float FuelSeconds => Mathf.Max(1f, _fuelMinutes.Value) * 60f; public static string RepairStation { get { if (!string.IsNullOrWhiteSpace(_repairStation.Value)) { return _repairStation.Value.Trim(); } return "forge"; } } public static float PerItemMaxIntensityMultiplier => Mathf.Max(1f, Mathf.Clamp(_perItemMaxIntensityMultiplier.Value, 1f, 3f)); public static float PerItemMaxRangeMultiplier => Mathf.Max(1f, Mathf.Clamp(_perItemMaxRangeMultiplier.Value, 1f, 3f)); public static float PerItemAdjustmentStep => Mathf.Clamp(_perItemAdjustmentStep.Value, 0.05f, 1f); public static KeyboardShortcut ToggleLightHotkey => _toggleLightHotkey.Value; public static KeyboardShortcut AdjustmentModifierKey => _adjustmentModifierKey.Value; public static string AdjustmentModifierLabel => ConfigValueHelpers.FormatShortcut(AdjustmentModifierKey); public static void Bind(HomesteadPlugin plugin) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown //IL_01e1: 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_0215: Expected O, but got Unknown //IL_022c: 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_0260: Expected O, but got Unknown _extensionEnabled = plugin.config("03 - Dvergr Circlet", "Enabled", HomesteadPlugin.Toggle.On, new ConfigDescription("If on, Homestead gives the Dvergr circlet per-item configurable light range, light intensity, durability drain while lit, and custom repair station support. If Circlet Extended is installed, Homestead leaves circlet handling to that mod.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1000 } })); _repairStation = plugin.config("03 - Dvergr Circlet", "Repair Station", "forge", new ConfigDescription("Crafting station required to repair the Dvergr circlet. Use the prefab name like forge, workbench, blackforge, or the localized station token like $piece_forge.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 990 } })); _fuelMinutes = plugin.config("03 - Dvergr Circlet", "Base Fuel Minutes", 60f, new ConfigDescription("How many minutes a full Dvergr circlet lasts at 1.0 light intensity and 1.0 light range. Higher intensity and range drain proportionally faster.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10000f), new object[1] { new ConfigurationManagerAttributes { Order = 980 } })); _perItemMaxIntensityMultiplier = plugin.config("03 - Dvergr Circlet", "Maximum Intensity Multiplier", 2f, new ConfigDescription("Highest brightness multiplier a player can set on an individual Dvergr circlet with hotkeys.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 3f), new object[1] { new ConfigurationManagerAttributes { Order = 970 } })); _perItemMaxRangeMultiplier = plugin.config("03 - Dvergr Circlet", "Maximum Range Multiplier", 2f, new ConfigDescription("Highest range multiplier a player can set on an individual Dvergr circlet with hotkeys.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 3f), new object[1] { new ConfigurationManagerAttributes { Order = 960 } })); _perItemAdjustmentStep = plugin.config("03 - Dvergr Circlet", "Adjustment Step", 0.25f, new ConfigDescription("Client-only brightness/range multiplier step used by Dvergr circlet hotkeys. 0.25 means 25% per key press.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 950 } }), synchronizedSetting: false); _adjustmentModifierKey = plugin.config("03 - Dvergr Circlet", "Adjustment Modifier Key", new KeyboardShortcut((KeyCode)304, Array.Empty()), new ConfigDescription("Client-only modifier held while using fixed arrow keys to adjust the equipped Dvergr circlet. Up/Down changes brightness, Right/Left changes range. Set to None to use arrow keys without a modifier.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 940 } }), synchronizedSetting: false); _toggleLightHotkey = plugin.config("03 - Dvergr Circlet", "Toggle Light Hotkey", new KeyboardShortcut((KeyCode)108, Array.Empty()), new ConfigDescription("Client-only hotkey that toggles the equipped Dvergr circlet light on or off.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 930 } }), synchronizedSetting: false); } } internal static class ConfigValueHelpers { public static HashSet SplitPrefabList(string value) { return (from item in (value ?? "").Split(new char[4] { ',', ';', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries) select item.Trim() into item where item.Length > 0 select item).ToHashSet(StringComparer.OrdinalIgnoreCase); } public static bool IsShortcutHeld(KeyboardShortcut shortcut, bool allowUnbound) { //IL_0002: 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) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return allowUnbound; } if (IsModifierKeyHeld(((KeyboardShortcut)(ref shortcut)).MainKey)) { return ((KeyboardShortcut)(ref shortcut)).Modifiers.All(IsModifierKeyHeld); } return false; } public static bool IsShortcutDown(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && ((KeyboardShortcut)(ref shortcut)).Modifiers.All(IsModifierKeyHeld)) { return IsKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey); } return false; } public static string FormatShortcut(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return "None"; } List list = (from text in ((KeyboardShortcut)(ref shortcut)).Modifiers.Where((KeyCode key) => (int)key > 0).Select(FormatKeyCode) where !string.IsNullOrWhiteSpace(text) select text).ToList(); list.Add(FormatKeyCode(((KeyboardShortcut)(ref shortcut)).MainKey)); if (list.Count != 0) { return string.Join("+", list); } return "None"; } private static string FormatKeyCode(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if ((int)key == 0) { return ""; } return ((object)(KeyCode)(ref key)).ToString().Replace("LeftControl", "Ctrl").Replace("RightControl", "Ctrl") .Replace("LeftShift", "Shift") .Replace("RightShift", "Shift") .Replace("LeftAlt", "Alt") .Replace("RightAlt", "Alt"); } private static bool IsModifierKeyHeld(KeyCode key) { //IL_0000: 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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected I4, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected I4, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0) { switch (key - 303) { default: return (key - 323) switch { 0 => Input.GetMouseButton(0), 1 => Input.GetMouseButton(1), 2 => Input.GetMouseButton(2), 3 => Input.GetMouseButton(3), 4 => Input.GetMouseButton(4), 5 => Input.GetMouseButton(5), 6 => Input.GetMouseButton(6), _ => Input.GetKey(key), }; case 2: case 3: return Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305); case 0: case 1: return Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); case 4: case 5: return Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); } } return false; } private static bool IsKeyDown(KeyCode key) { //IL_0000: 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_0028: Expected I4, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) return (key - 323) switch { 0 => Input.GetMouseButtonDown(0), 1 => Input.GetMouseButtonDown(1), 2 => Input.GetMouseButtonDown(2), 3 => Input.GetMouseButtonDown(3), 4 => Input.GetMouseButtonDown(4), 5 => Input.GetMouseButtonDown(5), 6 => Input.GetMouseButtonDown(6), _ => Input.GetKeyDown(key), }; } } internal sealed class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string? Category; [UsedImplicitly] public Action? CustomDrawer; } internal static class HomesteadFeatureBootstrap { private static Player? _lastLocalPlayer; public static void Initialize(ManualLogSource logger, Harmony harmony) { HomesteadInputBlockers.Initialize(logger); ZoneSessionResetRegistry.Initialize(logger); ZoneBlueprintCommands.Initialize(logger); ZoneBlueprintSaveTool.Initialize(logger); ZoneAreaDismantleTool.Initialize(logger); ZoneBlueprintPlacementTool.Initialize(logger); ZoneBlueprintChestVfx.Initialize(logger); ZoneBlueprintPlanChestPrefab.Initialize(logger); ZoneBlueprintChestZdoRegistry.Initialize(logger); ZoneBlueprintChestMapPins.Initialize(logger); ZoneBlueprintChestCommands.Initialize(logger); ZoneBlueprintStore.Initialize(logger); ZoneBuildCamera.Initialize(logger); ZoneGridSnap.Initialize(logger); ZonePlacementAdjust.Initialize(logger); ZoneDvergrCirclet.Initialize(logger); RegisterSessionResetters(); harmony.PatchAll(Assembly.GetExecutingAssembly()); VeiledRecipesCompat.Initialize(logger); AzuCraftyBoxesCompat.Initialize(logger, harmony); ZoneWorldEditTerrainCompat.Initialize(logger, harmony); } private static void RegisterSessionResetters() { ZoneSessionResetRegistry.Register("Blueprint RPC queue", ZoneBlueprintNetworkPayload.ResetForWorldSession); ZoneSessionResetRegistry.Register("Blueprint plan ghost cleanup", ZoneBlueprintCommands.ResetForWorldSession); ZoneSessionResetRegistry.Register("Blueprint menu", ZoneBlueprintSaveToolMenu.ResetForWorldSession); ZoneSessionResetRegistry.Register("Blueprint plan RPC", ZoneBlueprintPlanRpc.ResetForWorldSession); ZoneSessionResetRegistry.Register("Blueprint store", ZoneBlueprintStore.ResetForWorldSession); ZoneSessionResetRegistry.Register("ContentsWithin preview", ZoneContentsWithinBlueprintChestPreview.ResetForWorldSession); ZoneSessionResetRegistry.Register("Dvergr circlet", ZoneDvergrCirclet.ResetForWorldSession); } public static void Update() { ZoneBlueprintNetworkPayload.Update(); ZoneBlueprintChestZdoRegistry.Update(); ZoneBlueprintCommands.Update(); ZoneBlueprintChestCommands.RegisterRpcs(); ZoneBlueprintChestVfx.Update(); ZoneAreaDismantleTool.RegisterRpcs(); ZoneBlueprintSaveToolMenu.Update(); ZoneBlueprintPlanRpc.Update(); ZoneBlueprintStore.Update(); ZoneBuildCamera.Update(); ZoneGridSnap.Update(); ZoneDvergrCirclet.Update(); VeiledRecipesCompat.Update(); AzuCraftyBoxesCompat.Update(); ZoneWorldEditTerrainCompat.Update(); } public static void Shutdown() { ZoneBuildCamera.Shutdown(); ZoneSessionResetRegistry.ResetForWorldSession("shutdown"); ZoneBlueprintChestMapPins.Shutdown(); ZoneBlueprintChestZdoRegistry.Shutdown(); ZoneBlueprintStoreDraftRepository.Flush(force: true); } public static void OnLocalPlayerSet() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)localPlayer == (Object)(object)_lastLocalPlayer)) { _lastLocalPlayer = localPlayer; ZoneSessionResetRegistry.ResetForWorldSession("local player changed"); } } } internal static class HomesteadInputBlockers { private static ManualLogSource? _logger; private static bool _useTextInputFallback; private static bool _loggedTextInputFallback; internal static void Initialize(ManualLogSource logger) { _logger = logger; } internal static bool IsTextInputVisible() { if (!_useTextInputFallback) { try { return TextInput.IsVisible() || IsFocusedInputField(); } catch (Exception ex) { _useTextInputFallback = true; LogTextInputFallback(ex); } } if (!IsValheimTextInputVisible()) { return IsFocusedInputField(); } return true; } private static bool IsValheimTextInputVisible() { TextInput instance = TextInput.instance; if (Object.op_Implicit((Object)(object)instance)) { return instance.m_visibleFrame; } return false; } private static bool IsFocusedInputField() { EventSystem current = EventSystem.current; if ((Object)(object)current == (Object)null) { return false; } GameObject currentSelectedGameObject = current.currentSelectedGameObject; if (!Object.op_Implicit((Object)(object)currentSelectedGameObject)) { return false; } InputField val = currentSelectedGameObject.GetComponent() ?? currentSelectedGameObject.GetComponentInParent(); if ((Object)(object)val != (Object)null && val.isFocused) { return true; } TMP_InputField val2 = currentSelectedGameObject.GetComponent() ?? currentSelectedGameObject.GetComponentInParent(); if ((Object)(object)val2 != (Object)null) { return val2.isFocused; } return false; } private static void LogTextInputFallback(Exception ex) { if (!_loggedTextInputFallback) { _loggedTextInputFallback = true; ManualLogSource? logger = _logger; if (logger != null) { logger.LogWarning((object)("TextInput.IsVisible failed (" + ex.GetType().Name + ": " + ex.Message + "); using Homestead's safe input visibility fallback.")); } } } } internal static class HomesteadLocalization { private static bool _loaded; private static ManualLogSource? _logger; public static void Load(ManualLogSource logger) { _logger = logger; if (!_loaded) { _loaded = true; CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); AddEmbeddedYaml(localization, "English"); AddEmbeddedYaml(localization, "Korean"); AddExternalYamlFiles(localization); } } public static string Token(string key) { if (!key.StartsWith("$", StringComparison.Ordinal)) { return "$" + key; } return key; } public static string Text(string key) { string text = Token(key); if (Localization.instance == null) { return text; } return Localization.instance.Localize(text); } public static string Format(string key, params object[] args) { string text = Text(key); try { return string.Format(CultureInfo.InvariantCulture, text, args); } catch (FormatException) { return text; } } public static string MaybeLocalize(string value) { if (Localization.instance == null) { return value; } return Localization.instance.Localize(value); } private static void AddEmbeddedYaml(CustomLocalization localization, string language) { string resourceSuffix = ".translations." + language + ".yml"; Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string name) => name.EndsWith(resourceSuffix, StringComparison.Ordinal)); if (text == null) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogWarning((object)("Homestead localization resource not found: translations/" + language + ".yml")); } return; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogWarning((object)("Homestead localization resource could not be opened: " + text)); } return; } using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); localization.AddYamlFile(language, streamReader.ReadToEnd()); } private static void AddExternalYamlFiles(CustomLocalization localization) { string pluginPath = Paths.PluginPath; if (string.IsNullOrWhiteSpace(pluginPath) || !Directory.Exists(pluginPath)) { return; } HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (string item in Directory.EnumerateFiles(pluginPath, "Homestead.*.yml", SearchOption.AllDirectories).Concat(Directory.EnumerateFiles(pluginPath, "Homestead.*.yaml", SearchOption.AllDirectories)).OrderBy((string path) => path, StringComparer.OrdinalIgnoreCase)) { if (!TryGetExternalLanguage(item, out string language)) { continue; } if (!hashSet.Add(language)) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogWarning((object)("Duplicate external Homestead localization for language '" + language + "' skipped: " + item)); } continue; } try { localization.AddYamlFile(language, File.ReadAllText(item, Encoding.UTF8)); ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogInfo((object)("Loaded external Homestead localization '" + language + "' from " + item)); } } catch (Exception ex) { ManualLogSource? logger3 = _logger; if (logger3 != null) { logger3.LogWarning((object)("Failed to load external Homestead localization '" + item + "': " + ex.Message)); } } } } private static bool TryGetExternalLanguage(string file, out string language) { language = ""; string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file); string text = "Homestead."; if (!fileNameWithoutExtension.StartsWith(text, StringComparison.OrdinalIgnoreCase)) { return false; } language = fileNameWithoutExtension.Substring(text.Length).Trim(); return !string.IsNullOrWhiteSpace(language); } } internal static class HomesteadPlayerIdentity { public static string ResolvePlatformId(Player? player, long sender, long playerId) { if ((Object)(object)player != (Object)null) { return ResolveLocalPlatformId(playerId); } ZNet instance = ZNet.instance; ZNetPeer val = ((instance != null) ? instance.GetPeer(sender) : null); if (val != null) { return ResolvePeerPlatformId(val, playerId); } if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.GetPlayerID() == playerId) { return ResolveLocalPlatformId(playerId); } return FallbackPlatformId(playerId); } public static string ResolvePeerPlatformId(ZNetPeer peer, long playerId) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (peer == null) { return FallbackPlatformId(playerId); } ISocket socket = peer.m_socket; string text = ((socket != null) ? socket.GetHostName() : null) ?? ""; if (!string.IsNullOrWhiteSpace(text)) { return NormalizePlatformId(((int)ZNet.m_onlineBackend == 0) ? ("steam:" + text) : text); } return $"session:{peer.m_uid}"; } public static string ResolveLocalPlatformId(long playerId) { string value = ""; try { UserInfo localUser = UserInfo.GetLocalUser(); value = ((localUser != null) ? ((object)(PlatformUserID)(ref localUser.UserId)).ToString() : null) ?? ""; } catch { } value = NormalizePlatformId(value); if (!string.IsNullOrWhiteSpace(value)) { return value; } return FallbackPlatformId(playerId); } public static string FallbackPlatformId(long playerId) { if (playerId == 0L) { return ""; } return $"local:{playerId}"; } public static string NormalizePlatformId(string value) { string text = (value ?? "").Trim(); if (string.IsNullOrWhiteSpace(text)) { return ""; } if (text.StartsWith("Steam_", StringComparison.OrdinalIgnoreCase)) { return "steam:" + text.Substring("Steam_".Length); } if (text.StartsWith("steam:", StringComparison.OrdinalIgnoreCase)) { return "steam:" + text.Substring("steam:".Length).Trim(); } return text; } public static bool TryGetPeerActivity(ZNetPeer peer, out string platformId, out long playerId, out string name) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) platformId = ""; playerId = 0L; name = ""; if (peer == null || !peer.IsReady()) { return false; } platformId = ResolvePeerPlatformId(peer, 0L); playerId = TryReadPlayerId(peer.m_characterID); name = peer.m_playerName; return true; } private static long TryReadPlayerId(ZDOID characterId) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (((ZDOID)(ref characterId)).IsNone() || ZDOMan.instance == null) { return 0L; } ZDO zDO = ZDOMan.instance.GetZDO(characterId); if (zDO == null) { return 0L; } return zDO.GetLong(ZDOVars.s_playerID, 0L); } } internal static class SavedZdoHelper { public static void Destroy(ZDO zdo) { //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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (zdo == null || ZDOMan.instance == null) { return; } ZDOID uid = zdo.m_uid; if (!CanDestroyZdo(uid)) { return; } zdo.SetOwner(ZDOMan.GetSessionID()); ZDOID connectionZDOID = zdo.GetConnectionZDOID((ConnectionType)3); if (connectionZDOID != ZDOID.None && ZDOMan.instance.m_objectsByID.TryGetValue(connectionZDOID, out var value) && value != zdo) { Destroy(value); } ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance != (Object)null) { ZNetView val = instance.FindInstance(zdo); if ((Object)(object)val != (Object)null) { instance.Destroy(((Component)val).gameObject); } } ZDO zDO = ZDOMan.instance.GetZDO(uid); if (zDO != null && zDO.IsValid()) { zDO.SetOwner(ZDOMan.GetSessionID()); ZDOMan.instance.DestroyZDO(zDO); ZDOMan.instance.HandleDestroyedZDO(uid); } } public static void FlushDestroyed() { ZDOMan instance = ZDOMan.instance; if (instance != null) { instance.SendDestroyed(); } } private static bool CanDestroyZdo(ZDOID id) { //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_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).GetZDOID() == id) { return false; } if (!((Object)(object)ZNet.instance == (Object)null)) { return !ZNet.instance.m_peers.Any((ZNetPeer peer) => peer != null && peer.m_characterID == id); } return true; } } internal static class HomesteadTerrainSupport { private readonly struct TerrainSupportCell { public int X { get; } public int Z { get; } public float Height { get; } public TerrainSupportCell(int x, int z, float height) { X = x; Z = z; Height = height; } } private sealed class TerrainSupportCellIndex { private readonly Dictionary> _cellsByBucket = new Dictionary>(); private readonly float _bucketSize; private readonly int _searchRadius; public TerrainSupportCellIndex(IEnumerable cells, float featherWidth) { _bucketSize = Mathf.Max(1f, featherWidth); _searchRadius = Mathf.Max(0, Mathf.CeilToInt(featherWidth / _bucketSize)); foreach (TerrainSupportCell cell in cells) { long key = PackCell(ToBucket(cell.X), ToBucket(cell.Z)); if (!_cellsByBucket.TryGetValue(key, out List value)) { value = new List(); _cellsByBucket[key] = value; } value.Add(cell); } } public bool TryGetNearest(Vector3 node, float maxDistanceSqr, out TerrainSupportCell nearest, out float bestDistanceSqr) { //IL_001f: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) nearest = default(TerrainSupportCell); bestDistanceSqr = float.PositiveInfinity; if (_cellsByBucket.Count == 0) { return false; } int num = ToBucket(node.x); int num2 = ToBucket(node.z); for (int i = num2 - _searchRadius; i <= num2 + _searchRadius; i++) { for (int j = num - _searchRadius; j <= num + _searchRadius; j++) { if (!_cellsByBucket.TryGetValue(PackCell(j, i), out List value)) { continue; } foreach (TerrainSupportCell item in value) { float num3 = node.x - (float)item.X; float num4 = node.z - (float)item.Z; float num5 = num3 * num3 + num4 * num4; if (!(num5 >= bestDistanceSqr) && !(num5 > maxDistanceSqr)) { bestDistanceSqr = num5; nearest = item; } } } } return !float.IsPositiveInfinity(bestDistanceSqr); } private int ToBucket(float value) { return Mathf.FloorToInt(value / _bucketSize); } } [CompilerGenerated] private sealed class <>c__DisplayClass7_0 { public bool zoneChanged; internal void b__3(bool result) { zoneChanged = result; } } [CompilerGenerated] private sealed class d__12 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Heightmap heightmap; public List supportCells; public Dictionary supportHeights; public Action onComplete; private int 5__2; private float[] 5__3; private Color[] 5__4; private float 5__5; private TerrainSupportCellIndex 5__6; private bool 5__7; private int 5__8; private int 5__9; private int 5__10; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__3 = null; 5__4 = null; 5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00f0: 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_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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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) int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; goto IL_01d7; } <>1__state = -1; 5__2 = heightmap.m_width + 1; 5__3 = new float[5__2 * 5__2]; 5__4 = (Color[])(object)new Color[5__2 * 5__2]; 5__5 = BlueprintConfig.TerrainSupportFeatherWidth; 5__6 = new TerrainSupportCellIndex(supportCells, 5__5); 5__7 = false; 5__8 = 0; 5__9 = 0; goto IL_020c; IL_020c: if (5__9 < 5__2) { 5__10 = 0; goto IL_01e9; } if (!5__7) { onComplete(obj: false); return false; } PersistSupportFillBaseLayer(heightmap.GetAndCreateTerrainCompiler(), 5__2, 5__3, 5__4); heightmap.Poke(false); ClutterSystem instance = ClutterSystem.instance; if (instance != null) { instance.ResetGrass(((Component)heightmap).transform.position, 48f); } onComplete(obj: true); return false; IL_01d7: 5__10++; goto IL_01e9; IL_01e9: if (5__10 < 5__2) { int num2 = 5__9 * 5__2 + 5__10; Vector3 val = VertexToWorld(heightmap, 5__10, 5__9); float worldHeight = GetWorldHeight(heightmap, 5__10, 5__9); float height; float num3 = (TryGetTerrainBaseHeight(val.x, val.z, out height) ? height : worldHeight); float num4 = num3; 5__4[num2] = GetPaint(heightmap, 5__10, 5__9); float height2; if (supportHeights.TryGetValue(PackCell(Mathf.RoundToInt(val.x), Mathf.RoundToInt(val.z)), out var value)) { num4 = value; } else if (TryGetFeatheredSupportHeight(val, num3, 5__6, 5__5, out height2)) { num4 = height2; } 5__3[num2] = num4; if (Mathf.Abs(worldHeight - num4) > 0.01f) { 5__7 = true; } 5__8++; if (5__8 >= 1024) { 5__8 = 0; <>2__current = null; <>1__state = 1; return true; } goto IL_01d7; } 5__9++; goto IL_020c; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__7 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public IEnumerable supportContacts; public Action onComplete; private <>c__DisplayClass7_0 <>8__1; private List 5__2; private Dictionary 5__3; private bool 5__4; private List.Enumerator <>7__wrap4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally1(); } } <>8__1 = null; 5__2 = null; 5__3 = null; <>7__wrap4 = default(List.Enumerator); <>1__state = -2; } private bool MoveNext() { //IL_0102: Unknown result type (might be due to invalid IL or missing references) bool result2; try { switch (<>1__state) { default: result2 = false; goto end_IL_0000; case 0: <>1__state = -1; 5__2 = BuildSupportCells(supportContacts); if (5__2.Count != 0) { 5__3 = 5__2.ToDictionary((TerrainSupportCell cell) => PackCell(cell.X, cell.Z), (TerrainSupportCell cell) => cell.Height); List list = 5__2.Select((TerrainSupportCell cell) => ZoneSystem.GetZone(new Vector3((float)cell.X, 0f, (float)cell.Z))).Distinct().ToList(); 5__4 = false; <>7__wrap4 = list.GetEnumerator(); <>1__state = -3; break; } onComplete(obj: false); result2 = false; goto end_IL_0000; case 1: <>1__state = -3; 5__4 |= <>8__1.zoneChanged; <>2__current = null; <>1__state = 2; result2 = true; goto end_IL_0000; case 2: <>1__state = -3; <>8__1 = null; break; } if (<>7__wrap4.MoveNext()) { Vector2i current = <>7__wrap4.Current; <>8__1 = new <>c__DisplayClass7_0(); if (!TryGetHeightmap(current, out Heightmap heightmap)) { onComplete(obj: false); result2 = false; <>m__Finally1(); } else { <>8__1.zoneChanged = false; <>2__current = ApplySupportCellsToHeightmapAsync(heightmap, 5__3, 5__2, delegate(bool result) { <>8__1.zoneChanged = result; }); <>1__state = 1; result2 = true; } } else { <>m__Finally1(); <>7__wrap4 = default(List.Enumerator); onComplete(5__4); result2 = false; } end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result2; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap4).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__37 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private Vector3 <>2__current; private int <>l__initialThreadId; private Bounds bounds; public Bounds <>3__bounds; private Vector3 5__2; private Vector3 5__3; Vector3 IEnumerator.Current { [DebuggerHidden] get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return <>2__current; } } [DebuggerHidden] public d__37(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //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_0052: 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_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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //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_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = ((Bounds)(ref bounds)).min; 5__3 = ((Bounds)(ref bounds)).max; <>2__current = new Vector3(5__2.x, 5__2.y, 5__2.z); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = new Vector3(5__2.x, 5__2.y, 5__3.z); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = new Vector3(5__2.x, 5__3.y, 5__2.z); <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = new Vector3(5__2.x, 5__3.y, 5__3.z); <>1__state = 4; return true; case 4: <>1__state = -1; <>2__current = new Vector3(5__3.x, 5__2.y, 5__2.z); <>1__state = 5; return true; case 5: <>1__state = -1; <>2__current = new Vector3(5__3.x, 5__2.y, 5__3.z); <>1__state = 6; return true; case 6: <>1__state = -1; <>2__current = new Vector3(5__3.x, 5__3.y, 5__2.z); <>1__state = 7; return true; case 7: <>1__state = -1; <>2__current = new Vector3(5__3.x, 5__3.y, 5__3.z); <>1__state = 8; return true; case 8: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) d__37 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__37(0); } d__.bounds = <>3__bounds; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private const float SearchRadius = 48f; private const float SupportFillClearance = 0.05f; private const int TerrainApplyNodeBatchSize = 1024; private static readonly int SupportFillBaseLayerHash = StringExtensionMethods.GetStableHashCode("sighsorry.Homestead.terrain_base_v1"); public static bool TryGetWearNTearBounds(GameObject prefab, Vector3 position, Quaternion rotation, Vector3 scale, out Bounds bounds) { //IL_0001: 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_0003: Unknown result type (might be due to invalid IL or missing references) return TryGetWearNTearWorldBounds(prefab, position, rotation, scale, out bounds); } public static bool TryGetTerrainHeight(float x, float z, out float height) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Heightmap.GetHeight(new Vector3(x, 0f, z), ref height); } public static bool ApplyWorldSupportContacts(IEnumerable supportContacts) { //IL_0091: 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_0098: 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) List list = BuildSupportCells(supportContacts); if (list.Count == 0) { return false; } Dictionary supportHeights = list.ToDictionary((TerrainSupportCell cell) => PackCell(cell.X, cell.Z), (TerrainSupportCell cell) => cell.Height); List list2 = list.Select((TerrainSupportCell cell) => ZoneSystem.GetZone(new Vector3((float)cell.X, 0f, (float)cell.Z))).Distinct().ToList(); bool flag = false; foreach (Vector2i item in list2) { if (!TryGetHeightmap(item, out Heightmap heightmap)) { throw new InvalidOperationException($"Target terrain zone ({item.x},{item.y}) is not loaded for blueprint support placement."); } flag |= ApplySupportCellsToHeightmap(heightmap, supportHeights, list); } return flag; } [IteratorStateMachine(typeof(d__7))] public static IEnumerator ApplyWorldSupportContactsAsync(IEnumerable supportContacts, Action onComplete) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(0) { supportContacts = supportContacts, onComplete = onComplete }; } public static void ApplyBaseLayer(Heightmap heightmap) { //IL_0006: 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_00d0: Unknown result type (might be due to invalid IL or missing references) TerrainComp val = TerrainComp.FindTerrainCompiler(((Component)heightmap).transform.position); if (!IsCompilerReady(val)) { return; } byte[] byteArray = val.m_nview.GetZDO().GetByteArray(SupportFillBaseLayerHash, (byte[])null); if (byteArray == null || byteArray.Length == 0 || !TryDeserializeBaseLayer(byteArray, heightmap, out int width, out float[] worldHeights, out Color[] paints) || width != heightmap.m_width + 1 || worldHeights.Length != heightmap.m_heights.Count || (paints.Length != 0 && paints.Length != worldHeights.Length)) { return; } float y = ((Component)heightmap).transform.position.y; for (int i = 0; i < worldHeights.Length; i++) { heightmap.m_heights[i] = worldHeights[i] - y; } if (paints.Length != worldHeights.Length) { return; } for (int j = 0; j < width; j++) { for (int k = 0; k < width; k++) { heightmap.m_paintMask.SetPixel(k, j, paints[j * width + k]); } } } internal static void ResetSupportFillBaseLayer(IEnumerable? heightNodes, IEnumerable? paintNodes, Vector3 position, float radius) { //IL_0235: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) Dictionary> dictionary = CollectTerrainNodeIndices(heightNodes); Dictionary> dictionary2 = CollectTerrainNodeIndices(paintNodes); if (dictionary.Count == 0 && dictionary2.Count == 0) { return; } HashSet hashSet = dictionary.Keys.Concat(dictionary2.Keys).ToHashSet(); int num = 0; foreach (TerrainComp item in hashSet) { if (!TryLoadSupportFillBaseLayer(item, out int width, out float[] worldHeights, out Color[] paints)) { continue; } bool flag = false; if (dictionary.TryGetValue(item, out var value)) { foreach (int item2 in value) { if (IsValidPayloadIndex(item2, width, worldHeights.Length)) { IndexToXZ(item2, width, out var x, out var z); Vector3 val = VertexToWorld(item.m_hmap, x, z); if (TryGetTerrainBaseHeight(val.x, val.z, out var height) && Mathf.Abs(worldHeights[item2] - height) > 0.01f) { worldHeights[item2] = height; flag = true; } } } } bool num2 = paints.Length == width * width; Color[] array = (num2 ? TryGetBasePaints(item.m_hmap, width) : null); if (num2 && array != null && dictionary2.TryGetValue(item, out var value2)) { foreach (int item3 in value2) { if (IsValidPayloadIndex(item3, width, paints.Length) && item3 < array.Length) { Color val2 = array[item3]; if (!Approximately(paints[item3], val2)) { paints[item3] = val2; flag = true; } } } } if (flag) { if (IsSupportFillBaseLayerNative(item.m_hmap, width, worldHeights, paints, array)) { item.m_nview.GetZDO().Set(SupportFillBaseLayerHash, Array.Empty()); } else { item.m_nview.GetZDO().Set(SupportFillBaseLayerHash, SerializeBaseLayer(item.m_hmap, width, worldHeights, paints)); } PersistCompiler(item); num++; } } if (num > 0) { ClutterSystem instance = ClutterSystem.instance; if (instance != null) { instance.ResetGrass(position, radius); } } } private static List BuildSupportCells(IEnumerable supportContacts) { return (from contact in supportContacts select new TerrainSupportCell(Mathf.RoundToInt(contact.x), Mathf.RoundToInt(contact.z), contact.y - 0.05f) into cell group cell by PackCell(cell.X, cell.Z) into @group select @group.OrderBy((TerrainSupportCell cell) => cell.Height).First()).ToList(); } private static bool ApplySupportCellsToHeightmap(Heightmap heightmap, Dictionary supportHeights, List supportCells) { //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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_008e: 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_00a0: 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) int num = heightmap.m_width + 1; float[] array = new float[num * num]; Color[] array2 = (Color[])(object)new Color[num * num]; float terrainSupportFeatherWidth = BlueprintConfig.TerrainSupportFeatherWidth; TerrainSupportCellIndex supportIndex = new TerrainSupportCellIndex(supportCells, terrainSupportFeatherWidth); bool flag = false; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { int num2 = i * num + j; Vector3 val = VertexToWorld(heightmap, j, i); float worldHeight = GetWorldHeight(heightmap, j, i); float height; float num3 = (TryGetTerrainBaseHeight(val.x, val.z, out height) ? height : worldHeight); float num4 = num3; array2[num2] = GetPaint(heightmap, j, i); float height2; if (supportHeights.TryGetValue(PackCell(Mathf.RoundToInt(val.x), Mathf.RoundToInt(val.z)), out var value)) { num4 = value; } else if (TryGetFeatheredSupportHeight(val, num3, supportIndex, terrainSupportFeatherWidth, out height2)) { num4 = height2; } array[num2] = num4; if (Mathf.Abs(worldHeight - num4) > 0.01f) { flag = true; } } } if (!flag) { return false; } PersistSupportFillBaseLayer(heightmap.GetAndCreateTerrainCompiler(), num, array, array2); heightmap.Poke(false); ClutterSystem instance = ClutterSystem.instance; if (instance != null) { instance.ResetGrass(((Component)heightmap).transform.position, 48f); } return true; } [IteratorStateMachine(typeof(d__12))] private static IEnumerator ApplySupportCellsToHeightmapAsync(Heightmap heightmap, Dictionary supportHeights, List supportCells, Action onComplete) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__12(0) { heightmap = heightmap, supportHeights = supportHeights, supportCells = supportCells, onComplete = onComplete }; } private static bool TryGetFeatheredSupportHeight(Vector3 node, float baseHeight, TerrainSupportCellIndex supportIndex, float featherWidth, out float height) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) height = baseHeight; if (featherWidth <= 0f) { return false; } float maxDistanceSqr = featherWidth * featherWidth; if (!supportIndex.TryGetNearest(node, maxDistanceSqr, out var nearest, out var bestDistanceSqr)) { return false; } float num = Mathf.Sqrt(bestDistanceSqr); float num2 = 1f - Mathf.Clamp01(num / featherWidth); num2 = num2 * num2 * (3f - 2f * num2); height = Mathf.Lerp(baseHeight, nearest.Height, num2); return true; } private static bool TryLoadSupportFillBaseLayer(TerrainComp compiler, out int width, out float[] worldHeights, out Color[] paints) { width = 0; worldHeights = Array.Empty(); paints = Array.Empty(); if (!IsCompilerReady(compiler)) { return false; } byte[] byteArray = compiler.m_nview.GetZDO().GetByteArray(SupportFillBaseLayerHash, (byte[])null); if (byteArray != null && byteArray.Length != 0 && TryDeserializeBaseLayer(byteArray, compiler.m_hmap, out width, out worldHeights, out paints) && width == compiler.m_hmap.m_width + 1 && worldHeights.Length == width * width) { if (paints.Length != 0) { return paints.Length == worldHeights.Length; } return true; } return false; } private static Dictionary> CollectTerrainNodeIndices(IEnumerable? nodes) { Dictionary> dictionary = new Dictionary>(); if (nodes == null) { return dictionary; } foreach (object node in nodes) { if (TryReadTerrainNode(node, out TerrainComp compiler, out int index)) { if (!dictionary.TryGetValue(compiler, out var value)) { value = (dictionary[compiler] = new HashSet()); } value.Add(index); } } return dictionary; } private static bool TryReadTerrainNode(object? node, out TerrainComp compiler, out int index) { compiler = null; index = -1; if (node == null) { return false; } Type type = node.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "Compiler"); FieldInfo fieldInfo2 = AccessTools.Field(type, "Index"); object? obj = fieldInfo?.GetValue(node); TerrainComp val = (TerrainComp)((obj is TerrainComp) ? obj : null); object obj2 = fieldInfo2?.GetValue(node); if ((Object)(object)val == (Object)null || !(obj2 is int num)) { return false; } compiler = val; index = num; return true; } private static byte[] SerializeBaseLayer(Heightmap heightmap, int width, float[] worldHeights, Color[] paints) { Color[] paints2 = (ShouldSerializePaints(heightmap, width, paints) ? paints : Array.Empty()); return SerializeSparseBaseLayer(heightmap, width, worldHeights, paints2); } private static byte[] SerializeSparseBaseLayer(Heightmap heightmap, int width, float[] worldHeights, Color[] paints) { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List list2 = new List(); for (int i = 0; i < worldHeights.Length; i++) { IndexToXZ(i, width, out var x, out var z); Vector3 val = VertexToWorld(heightmap, x, z); float height; float num = (TryGetTerrainBaseHeight(val.x, val.z, out height) ? height : GetWorldHeight(heightmap, x, z)); if (!(Mathf.Abs(worldHeights[i] - num) <= 0.01f)) { list.Add(i); list2.Add(worldHeights[i]); } } List list3 = new List(); List list4 = new List(); if (paints.Length == worldHeights.Length) { Color[] array = TryGetBasePaints(heightmap, width); for (int j = 0; j < paints.Length; j++) { Color b = ((array != null && array.Length == paints.Length) ? array[j] : GetPaint(heightmap, j % width, j / width)); if (!Approximately(paints[j], b)) { list3.Add(j); list4.Add(paints[j]); } } } ZPackage val2 = new ZPackage(); val2.Write(3); val2.Write(width); val2.Write(worldHeights.Length); val2.Write(list.Count); for (int k = 0; k < list.Count; k++) { val2.Write(list[k]); val2.Write(list2[k]); } val2.Write(list3.Count); for (int l = 0; l < list3.Count; l++) { val2.Write(list3[l]); WriteColor(val2, list4[l]); } return Utils.Compress(val2.GetArray()); } private static bool TryDeserializeBaseLayer(byte[] payload, Heightmap heightmap, out int width, out float[] worldHeights, out Color[] paints) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown width = 0; worldHeights = Array.Empty(); paints = Array.Empty(); try { ZPackage val = new ZPackage(Utils.Decompress(payload)); if (val.ReadInt() != 3) { return false; } width = val.ReadInt(); int heightCount = val.ReadInt(); return TryDeserializeSparseBaseLayer(val, heightmap, width, heightCount, out worldHeights, out paints); } catch { return false; } } private static bool TryDeserializeSparseBaseLayer(ZPackage package, Heightmap heightmap, int width, int heightCount, out float[] worldHeights, out Color[] paints) { //IL_0044: 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_004f: 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) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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) worldHeights = new float[heightCount]; paints = Array.Empty(); if ((Object)(object)heightmap == (Object)null || width <= 0 || width != heightmap.m_width + 1 || heightCount != width * width) { return false; } for (int i = 0; i < worldHeights.Length; i++) { IndexToXZ(i, width, out var x, out var z); Vector3 val = VertexToWorld(heightmap, x, z); worldHeights[i] = (TryGetTerrainBaseHeight(val.x, val.z, out var height) ? height : GetWorldHeight(heightmap, x, z)); } int num = package.ReadInt(); for (int j = 0; j < num; j++) { int num2 = package.ReadInt(); float num3 = package.ReadSingle(); if (num2 < 0 || num2 >= worldHeights.Length) { return false; } worldHeights[num2] = num3; } int num4 = package.ReadInt(); if (num4 <= 0) { return true; } paints = TryGetBasePaints(heightmap, width) ?? BuildCurrentPaintLayer(heightmap, width); if (paints.Length != worldHeights.Length) { return false; } for (int k = 0; k < num4; k++) { int num5 = package.ReadInt(); Color val2 = ReadColor(package); if (num5 < 0 || num5 >= paints.Length) { return false; } paints[num5] = val2; } return true; } private static void PersistSupportFillBaseLayer(TerrainComp compiler, int width, float[] worldHeights, Color[] paints) { if (!IsCompilerReady(compiler)) { throw new InvalidOperationException("Target terrain compiler is not network ready."); } if (!compiler.m_nview.IsOwner()) { compiler.m_nview.ClaimOwnership(); } Array.Clear(compiler.m_modifiedHeight, 0, compiler.m_modifiedHeight.Length); Array.Clear(compiler.m_levelDelta, 0, compiler.m_levelDelta.Length); Array.Clear(compiler.m_smoothDelta, 0, compiler.m_smoothDelta.Length); Array.Clear(compiler.m_modifiedPaint, 0, compiler.m_modifiedPaint.Length); Array.Clear(compiler.m_paintMask, 0, compiler.m_paintMask.Length); compiler.m_nview.GetZDO().Set(SupportFillBaseLayerHash, SerializeBaseLayer(compiler.m_hmap, width, worldHeights, paints)); PersistCompiler(compiler); } private static void PersistCompiler(TerrainComp compiler) { //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 ((Object)(object)compiler.m_nview != (Object)null && compiler.m_nview.IsValid() && !compiler.m_nview.IsOwner()) { compiler.m_nview.ClaimOwnership(); } compiler.m_operations++; compiler.m_lastOpPoint = Vector3.zero; compiler.m_lastOpRadius = 0f; compiler.Save(); compiler.m_hmap.Poke(false); } private static bool ShouldSerializePaints(Heightmap heightmap, int width, Color[] paints) { //IL_0025: 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) if (paints.Length != width * width) { return false; } Color[] array = TryGetBasePaints(heightmap, width); if (array == null || array.Length != paints.Length) { return true; } for (int i = 0; i < paints.Length; i++) { if (!Approximately(paints[i], array[i])) { return true; } } return false; } private static Color[] BuildCurrentPaintLayer(Heightmap heightmap, int width) { //IL_001a: 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) Color[] array = (Color[])(object)new Color[width * width]; for (int i = 0; i < width; i++) { for (int j = 0; j < width; j++) { array[i * width + j] = GetPaint(heightmap, j, i); } } return array; } private static Color[]? TryGetBasePaints(Heightmap heightmap, int width) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (HeightmapBuilder.instance == null || WorldGenerator.instance == null) { return null; } try { HMBuildData val = HeightmapBuilder.instance.RequestTerrainSync(((Component)heightmap).transform.position, heightmap.m_width, heightmap.m_scale, heightmap.IsDistantLod, WorldGenerator.instance); return (val.m_baseMask != null && val.m_baseMask.Length == width * width) ? val.m_baseMask : null; } catch { return null; } } private static bool IsSupportFillBaseLayerNative(Heightmap heightmap, int width, float[] worldHeights, Color[] paints, Color[]? basePaints) { //IL_002d: 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: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) //IL_006a: Unknown result type (might be due to invalid IL or missing references) bool flag = paints.Length == width * width; if (flag && (basePaints == null || basePaints.Length != paints.Length)) { return false; } for (int i = 0; i < worldHeights.Length; i++) { IndexToXZ(i, width, out var x, out var z); Vector3 val = VertexToWorld(heightmap, x, z); if (!TryGetTerrainBaseHeight(val.x, val.z, out var height) || Mathf.Abs(worldHeights[i] - height) > 0.01f || (flag && !Approximately(paints[i], basePaints[i]))) { return false; } } return true; } private static bool TryGetTerrainBaseHeight(float x, float z, out float height) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (WorldGenerator.instance != null) { height = WorldGenerator.instance.GetHeight(x, z); return true; } if (Heightmap.GetHeight(new Vector3(x, 0f, z), ref height)) { return true; } height = 0f; return false; } private static bool TryGetHeightmap(Vector2i zone, out Heightmap heightmap) { //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) //IL_0021: Unknown result type (might be due to invalid IL or missing references) heightmap = null; if ((Object)(object)ZoneSystem.instance == (Object)null || !ZoneSystem.instance.IsZoneLoaded(zone)) { return false; } heightmap = Heightmap.FindHeightmap(ZoneSystem.GetZonePos(zone)); return (Object)(object)heightmap != (Object)null; } private static float GetWorldHeight(Heightmap heightmap, int x, int z) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) return heightmap.GetHeight(x, z) + ((Component)heightmap).transform.position.y; } private static Color GetPaint(Heightmap heightmap, int x, int z) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(x, 0, heightmap.m_width); int num2 = Mathf.Clamp(z, 0, heightmap.m_width); return heightmap.GetPaintMask(num, num2); } private static bool IsCompilerReady(TerrainComp compiler) { if ((Object)(object)compiler == (Object)null || (Object)(object)compiler.m_hmap == (Object)null) { return false; } ZNetView component = ((Component)compiler).GetComponent(); if ((Object)(object)component != (Object)null) { return component.IsValid(); } return false; } private static bool IsValidPayloadIndex(int index, int width, int length) { if (width > 0 && index >= 0 && index < length) { return index < width * width; } return false; } private static void IndexToXZ(int index, int width, out int x, out int z) { z = index / width; x = index - z * width; } private static bool Approximately(Color a, Color b) { //IL_0000: 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_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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0051: Unknown result type (might be due to invalid IL or missing references) if (Mathf.Abs(a.r - b.r) < 0.001f && Mathf.Abs(a.g - b.g) < 0.001f && Mathf.Abs(a.b - b.b) < 0.001f) { return Mathf.Abs(a.a - b.a) < 0.001f; } return false; } private static bool TryGetWearNTearWorldBounds(GameObject prefab, Vector3 position, Quaternion rotation, Vector3 scale, out Bounds bounds) { //IL_0002: 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_0010: 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_0016: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_0096: 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_00b2: 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_00b9: 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_00a7: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); Collider[] componentsInChildren = prefab.GetComponentsInChildren(); Matrix4x4 val = Matrix4x4.TRS(position, rotation, scale); bool flag = false; Collider[] array = componentsInChildren; foreach (Collider val2 in array) { if ((Object)(object)val2 == (Object)null || !val2.enabled || val2.isTrigger || !TryGetColliderLocalBounds(val2, out var bounds2)) { continue; } Matrix4x4 val3 = prefab.transform.worldToLocalMatrix * ((Component)val2).transform.localToWorldMatrix; foreach (Vector3 boundsCorner in GetBoundsCorners(bounds2)) { Vector3 val4 = ((Matrix4x4)(ref val)).MultiplyPoint3x4(((Matrix4x4)(ref val3)).MultiplyPoint3x4(boundsCorner)); if (flag) { ((Bounds)(ref bounds)).Encapsulate(val4); continue; } bounds = new Bounds(val4, Vector3.zero); flag = true; } } return flag; } private static bool TryGetColliderLocalBounds(Collider collider, out Bounds bounds) { //IL_003d: 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_004d: 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) //IL_005b: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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) BoxCollider val = (BoxCollider)(object)((collider is BoxCollider) ? collider : null); if (val == null) { SphereCollider val2 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null); if (val2 == null) { CapsuleCollider val3 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null); if (val3 == null) { MeshCollider val4 = (MeshCollider)(object)((collider is MeshCollider) ? collider : null); if (val4 != null && (Object)(object)val4.sharedMesh != (Object)null) { bounds = val4.sharedMesh.bounds; return true; } Bounds bounds2 = collider.bounds; bounds = new Bounds(((Component)collider).transform.InverseTransformPoint(((Bounds)(ref bounds2)).center), ((Bounds)(ref bounds2)).size); return true; } Vector3 val5 = Vector3.one * (val3.radius * 2f); ((Vector3)(ref val5))[val3.direction] = Mathf.Max(val3.height, val3.radius * 2f); bounds = new Bounds(val3.center, val5); return true; } bounds = new Bounds(val2.center, Vector3.one * (val2.radius * 2f)); return true; } bounds = new Bounds(val.center, val.size); return true; } [IteratorStateMachine(typeof(d__37))] private static IEnumerable GetBoundsCorners(Bounds bounds) { //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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__37(-2) { <>3__bounds = bounds }; } private static long PackCell(int x, int z) { return ((long)x << 32) ^ (uint)z; } private static Vector3 VertexToWorld(Heightmap heightmap, int x, int z) { //IL_0006: 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_0046: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)heightmap).transform.position; position.x += (float)(x - heightmap.m_width / 2) * heightmap.m_scale; position.z += (float)(z - heightmap.m_width / 2) * heightmap.m_scale; return position; } private static void WriteColor(ZPackage package, Color color) { //IL_0001: 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_0019: 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) package.Write(color.r); package.Write(color.g); package.Write(color.b); package.Write(color.a); } private static Color ReadColor(ZPackage package) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Color(package.ReadSingle(), package.ReadSingle(), package.ReadSingle(), package.ReadSingle()); } } [HarmonyPatch(typeof(Heightmap), "ApplyModifiers")] internal static class HomesteadTerrainSupportBaseLayerPatch { private static void Prefix(Heightmap __instance) { HomesteadTerrainSupport.ApplyBaseLayer(__instance); } } internal static class HomesteadTimestamp { public static string Now() { return Format(DateTime.UtcNow); } public static string Format(DateTime utc) { if (utc == DateTime.MinValue) { return ""; } return new DateTimeOffset(DateTime.SpecifyKind(utc, DateTimeKind.Utc)).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture); } public static DateTime ParseUtc(string value) { if (string.IsNullOrWhiteSpace(value)) { return DateTime.MinValue; } if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out var result) || DateTimeOffset.TryParse(value, CultureInfo.CurrentCulture, DateTimeStyles.AllowWhiteSpaces, out result)) { return DateTime.SpecifyKind(result.UtcDateTime, DateTimeKind.Utc); } if (DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal, out var result2) || DateTime.TryParse(value, CultureInfo.CurrentCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal, out result2)) { return DateTime.SpecifyKind(result2, DateTimeKind.Utc); } return DateTime.MinValue; } public static bool IsExpired(string timestamp, DateTime utcNow) { DateTime dateTime = ParseUtc(timestamp); if (dateTime != DateTime.MinValue) { return dateTime <= DateTime.SpecifyKind(utcNow, DateTimeKind.Utc); } return false; } } internal static class HomesteadYaml { private static readonly ISerializer Serializer = new SerializerBuilder().DisableAliases().ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull).WithNamingConvention(CamelCaseNamingConvention.Instance) .WithTypeConverter(new FlowFloatArrayYamlConverter()) .Build(); private static readonly IDeserializer Deserializer = new DeserializerBuilder().IgnoreUnmatchedProperties().WithNamingConvention(CamelCaseNamingConvention.Instance).WithTypeConverter(new FlowFloatArrayYamlConverter()) .Build(); public static string Serialize(T value) { return Serializer.Serialize(value); } public static T Deserialize(string yaml) { return Deserializer.Deserialize(yaml) ?? throw new InvalidDataException("Failed to deserialize " + typeof(T).Name + "."); } } internal sealed class FlowFloatArrayYamlConverter : IYamlTypeConverter { public bool Accepts(Type type) { return type == typeof(float[]); } public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) { parser.Consume(); List list = new List(); SequenceEnd @event; while (!parser.TryConsume(out @event)) { YamlDotNet.Core.Events.Scalar scalar = parser.Consume(); if (!float.TryParse(scalar.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { Mark start = scalar.Start; Mark end = scalar.End; throw new YamlException(in start, in end, "Invalid float value '" + scalar.Value + "'."); } list.Add(result); } return list.ToArray(); } public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer) { float[] obj = (value as float[]) ?? Array.Empty(); emitter.Emit(new SequenceStart(AnchorName.Empty, TagName.Empty, isImplicit: true, SequenceStyle.Flow)); float[] array = obj; foreach (float num in array) { emitter.Emit(new YamlDotNet.Core.Events.Scalar(AnchorName.Empty, TagName.Empty, num.ToString("0.###", CultureInfo.InvariantCulture), ScalarStyle.Plain, isPlainImplicit: true, isQuotedImplicit: true)); } emitter.Emit(new SequenceEnd()); } } internal static class InventorySlotsCompat { private const string PluginGuid = "sighsorry.InventorySlots"; private const string ApiTypeName = "InventorySlots.InventorySlotsApi"; private static readonly BindingFlags PublicStaticFlags = BindingFlags.Static | BindingFlags.Public; private static bool _initialized; private static bool _loaded; private static MethodInfo? _tryGetCustomEquippedItemMethod; private static MethodInfo? _tryGetCustomEquipmentVisualRootsMethod; public static bool IsLoaded { get { EnsureInitialized(); return _loaded; } } public static bool TryGetCustomEquippedItem(Player player, Func predicate, out ItemData? item) { item = null; if (!IsLoaded || !Object.op_Implicit((Object)(object)player) || predicate == null || _tryGetCustomEquippedItemMethod == null) { return false; } try { object[] array = new object[3] { player, predicate, null }; object obj = _tryGetCustomEquippedItemMethod.Invoke(null, array); bool num = obj is bool && (bool)obj; object obj2 = array[2]; item = (ItemData?)((obj2 is ItemData) ? obj2 : null); return num && item != null; } catch { item = null; return false; } } public static bool TryGetCustomEquipmentVisualRoots(VisEquipment visEquipment, ItemData item, List roots) { roots.Clear(); if (!IsLoaded || !Object.op_Implicit((Object)(object)visEquipment) || item == null || _tryGetCustomEquipmentVisualRootsMethod == null) { return false; } try { if (!(_tryGetCustomEquipmentVisualRootsMethod.Invoke(null, new object[3] { visEquipment, item, roots }) is int num) || num == 0) { roots.Clear(); } return roots.Count > 0; } catch { roots.Clear(); return false; } } public static void ResetForWorldSession() { if (!_loaded) { _initialized = false; _tryGetCustomEquippedItemMethod = null; _tryGetCustomEquipmentVisualRootsMethod = null; } } private static void EnsureInitialized() { if (!_initialized) { _initialized = true; if (Chainloader.PluginInfos.TryGetValue("sighsorry.InventorySlots", out var value)) { Type? obj = (((object)value.Instance)?.GetType().Assembly)?.GetType("InventorySlots.InventorySlotsApi", throwOnError: false); _tryGetCustomEquippedItemMethod = obj?.GetMethod("TryGetCustomEquippedItem", PublicStaticFlags); _tryGetCustomEquipmentVisualRootsMethod = obj?.GetMethod("TryGetCustomEquipmentVisualRoots", PublicStaticFlags); _loaded = _tryGetCustomEquippedItemMethod != null && _tryGetCustomEquipmentVisualRootsMethod != null; } } } } internal sealed class ZoneHammerRefreshScheduler { private readonly float _delaySeconds; private readonly float _bulkDelaySeconds; private readonly float _minIntervalSeconds; private bool _pending; private bool _urgentPending; private float _refreshAt; private float _lastRefreshAt = -999f; private string _highlightName = ""; public ZoneHammerRefreshScheduler(float delaySeconds, float bulkDelaySeconds, float minIntervalSeconds) { _delaySeconds = delaySeconds; _bulkDelaySeconds = bulkDelaySeconds; _minIntervalSeconds = minIntervalSeconds; } public void Reset() { _pending = false; _urgentPending = false; _refreshAt = 0f; _lastRefreshAt = -999f; _highlightName = ""; } public void ClearPending() { _pending = false; _urgentPending = false; _refreshAt = 0f; _highlightName = ""; } public void Request(string? highlightName, bool deferForBatch) { if (!string.IsNullOrWhiteSpace(highlightName)) { _highlightName = highlightName; } float realtimeSinceStartup = Time.realtimeSinceStartup; float num = (deferForBatch ? _bulkDelaySeconds : _delaySeconds); float num2 = Mathf.Max(realtimeSinceStartup + num, _lastRefreshAt + _minIntervalSeconds); if (!_pending) { _refreshAt = num2; _urgentPending = !deferForBatch; } else if (!deferForBatch) { _refreshAt = Mathf.Min(_refreshAt, num2); _urgentPending = true; } else if (!_urgentPending) { _refreshAt = Mathf.Max(_refreshAt, num2); } _pending = true; } public bool TryConsumeDue(out string highlightName) { highlightName = ""; if (!_pending || Time.realtimeSinceStartup < _refreshAt) { return false; } highlightName = _highlightName; ClearPending(); return true; } public void MarkCompleted() { _lastRefreshAt = Time.realtimeSinceStartup; } } public static class ToggleExtensions { [SpecialName] public sealed class $7EB8D39D0590F52339A917419F61209D { [SpecialName] public static class $352DF56E54E9138FA9089CCF33D1E5A3 { } [ExtensionMarker("$352DF56E54E9138FA9089CCF33D1E5A3")] public bool IsOn() { throw new NotSupportedException(); } [ExtensionMarker("$352DF56E54E9138FA9089CCF33D1E5A3")] public bool IsOff() { throw new NotSupportedException(); } } public static bool IsOn(this HomesteadPlugin.Toggle value) { return value == HomesteadPlugin.Toggle.On; } public static bool IsOff(this HomesteadPlugin.Toggle value) { return value == HomesteadPlugin.Toggle.Off; } } public enum BlueprintAzuCraftyBoxesPullMode { Off, ConfirmOnly, OpenAndConfirm } public enum BlueprintTerrainSupportMode { Off, On, AdminDebug } public enum BlueprintAreaSaveCreatorMode { AllCreators, OwnedAndCreatorless, OwnedOnly } public enum BlueprintStoreIdentityMode { PlayerId, SteamId } public enum BlueprintStoreNotificationMode { Off, BadgeOnly, AutoOpenPanel } internal static class VeiledRecipesCompat { private const string PluginGuid = "sighsorry.VeiledRecipes"; private const string ApiTypeName = "VeiledRecipes.VeiledRecipesCompat"; private static readonly BindingFlags PublicStaticFlags = BindingFlags.Static | BindingFlags.Public; private static ManualLogSource? _logger; private static bool _initialized; private static bool _registered; private static MethodInfo? _registerKnownPieceOverrideMethod; private static readonly Func KnownPieceOverride = IsHomesteadVirtualPiece; public static void Initialize(ManualLogSource logger) { _logger = logger; Update(); } public static void Update() { if (!_registered) { EnsureInitialized(); RegisterKnownPieceOverride(); } } private static void EnsureInitialized() { if (!_initialized) { _initialized = true; if (Chainloader.PluginInfos.TryGetValue("sighsorry.VeiledRecipes", out var value)) { _registerKnownPieceOverrideMethod = ((((object)value.Instance)?.GetType().Assembly)?.GetType("VeiledRecipes.VeiledRecipesCompat", throwOnError: false))?.GetMethod("RegisterKnownPieceOverride", PublicStaticFlags, null, new Type[1] { typeof(Func) }, null); } } } private static void RegisterKnownPieceOverride() { if (_registerKnownPieceOverrideMethod == null) { return; } try { _registerKnownPieceOverrideMethod.Invoke(null, new object[1] { KnownPieceOverride }); _registered = true; ManualLogSource? logger = _logger; if (logger != null) { logger.LogDebug((object)"Registered Homestead virtual pieces with VeiledRecipes."); } } catch (Exception ex) { ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogDebug((object)("Could not register Homestead virtual pieces with VeiledRecipes: " + ex.Message)); } } } private static bool IsHomesteadVirtualPiece(Piece piece) { if ((Object)(object)piece != (Object)null) { return (Object)(object)((Component)piece).GetComponent() != (Object)null; } return false; } } internal static class VersionHandshakeLogger { public static ManualLogSource Log => HomesteadPlugin.HomesteadLogger; } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] public static class RegisterAndCheckVersion { private static void Prefix(ZNetPeer peer, ref ZNet __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown VersionHandshakeLogger.Log.LogDebug((object)"Registering version RPC handler"); peer.m_rpc.Register("Homestead_VersionCheck", (Action)RpcHandlers.RPC_ModVersion); VersionHandshakeLogger.Log.LogInfo((object)"Invoking version check"); ZPackage val = new ZPackage(); val.Write("1.1.2"); peer.m_rpc.Invoke("Homestead_VersionCheck", new object[1] { val }); } } [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; } VersionHandshakeLogger.Log.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; } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] public class ShowConnectionError { 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" + HomesteadPlugin.ConnectionError; } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] public static class RemoveDisconnectedPeerFromVerified { private static void Prefix(ZNetPeer peer, ref ZNet __instance) { if (__instance.IsServer()) { VersionHandshakeLogger.Log.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list")); RpcHandlers.ValidatedPeers.Remove(peer.m_rpc); } } } public static class RpcHandlers { public static readonly List ValidatedPeers = new List(); public static void RPC_ModVersion(ZRpc rpc, ZPackage pkg) { string text = pkg.ReadString(); VersionHandshakeLogger.Log.LogInfo((object)("Version check, local: 1.1.2, remote: " + text)); if (text != "1.1.2") { HomesteadPlugin.ConnectionError = "Homestead Installed: 1.1.2\n Needed: " + text; if (ZNet.instance.IsServer()) { VersionHandshakeLogger.Log.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting...")); rpc.Invoke("Error", new object[1] { 3 }); } } else if (!ZNet.instance.IsServer()) { VersionHandshakeLogger.Log.LogInfo((object)"Received same version from server!"); } else { VersionHandshakeLogger.Log.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list")); ValidatedPeers.Add(rpc); } } } internal static class ZoneAreaCameraZoomGuard { [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] private static class GameCameraUpdateCameraPatch { private static void Prefix(GameCamera __instance) { if (_suppressFrame == Time.frameCount) { _distance = __instance.m_distance; _zoomSensitivity = __instance.m_zoomSens; __instance.m_zoomSens = 0f; } } private static void Postfix(GameCamera __instance) { if (_suppressFrame == Time.frameCount) { __instance.m_zoomSens = _zoomSensitivity; __instance.m_distance = _distance; } } } private static int _suppressFrame = -1; private static float _distance; private static float _zoomSensitivity; public static void SuppressWheelZoomThisFrame() { if (!((Object)(object)GameCamera.instance == (Object)null) && _suppressFrame != Time.frameCount) { _distance = GameCamera.instance.m_distance; _zoomSensitivity = GameCamera.instance.m_zoomSens; _suppressFrame = Time.frameCount; } } } internal sealed class ZoneAreaToolController { internal sealed class Options { public float MinSide { get; set; } public float SizeStep { get; set; } public Func MaxSide { get; set; } public Func DefaultWidth { get; set; } public Func DefaultDepth { get; set; } public Func Color { get; set; } public string RangeLineName { get; set; } = ""; public string TargetOverlayName { get; set; } = ""; public float TargetOverlayRefreshInterval { get; set; } = 0.12f; public float StableTargetOverlayRefreshInterval { get; set; } = 1f; public Func GetSavedYaw { get; set; } = () => null; public Action SetSavedYaw { get; set; } = delegate { }; public Func IsLocked { get; set; } = () => false; public Func? GetEffectiveYaw { get; set; } public Action? OnLockedScroll { get; set; } public Action? OnFrame { get; set; } public Func ShouldBlockToolInput { get; set; } = () => false; public Func StatusTitle { get; set; } = () => ""; public Func> FindCandidates { get; set; } = (Player _, ZoneAreaSelection _) => Array.Empty(); public Action OnClick { get; set; } = delegate { }; } private readonly MonoBehaviour _owner; private readonly Options _options; private LineRenderer? _rangeLine; private ZoneAreaTargetOverlay? _targetOverlay; private Material? _material; private bool _active; private float _width; private float _depth; private float _yaw; private float _heightOffset; private Vector3 _horizontalOffset; private Vector3 _aimPoint; private Vector3 _rawAimPoint; private bool _hasAimPoint; private int _suppressInputFrames; private float _lastTargetOverlayRefreshTime = -999f; private int _lastTargetOverlaySignature; private bool _hasTargetOverlaySignature; public bool Active => _active; public bool HasAimPoint => _hasAimPoint; public Vector3 AimPoint => _aimPoint; public float EffectiveYaw => GetEffectiveYaw(); public Vector3 HorizontalOffset => _horizontalOffset; public float HeightOffset => _heightOffset; public ZoneAreaSelection CurrentArea => ZoneAreaToolShared.BuildArea(_aimPoint, ref _width, ref _depth, _yaw, _options.DefaultWidth(), _options.DefaultDepth(), _options.MinSide, _options.MaxSide()); public string FormattedSize => ZoneAreaToolShared.FormatSize(_width, _depth); public ZoneAreaToolController(MonoBehaviour owner, Options options) { _owner = owner; _options = options; } public void Activate(Player player) { //IL_00a1: 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 (!_active) { _width = Mathf.Clamp(_options.DefaultWidth(), _options.MinSide, _options.MaxSide()); _depth = Mathf.Clamp(_options.DefaultDepth(), _options.MinSide, _options.MaxSide()); _yaw = _options.GetSavedYaw().GetValueOrDefault(); _heightOffset = 0f; _horizontalOffset = Vector3.zero; } _active = true; _hasAimPoint = false; _suppressInputFrames = 2; EnsureRangeLine(); } public void Deactivate() { _active = false; ResetOffsets(); ClearTargetOverlay(); ZoneAreaToolStatusHud.Hide(); HideRange(); } public void ResetOffsets() { //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) _heightOffset = 0f; _horizontalOffset = Vector3.zero; } public void Destroy() { _targetOverlay?.Destroy(); _targetOverlay = null; if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); _material = null; } } public bool Tick() { //IL_0058: 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_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) if (!_active) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !ZonePlacementInput.IsHoldingBuildTool(localPlayer)) { return false; } if (!ZoneAreaToolShared.TryGetAimPoint(localPlayer, _options.MaxSide(), out var point)) { _hasAimPoint = false; HideRange(); ClearTargetOverlay(); ZoneAreaToolStatusHud.Hide(); return true; } _rawAimPoint = point; _aimPoint = GetAdjustedAimPoint(point); _hasAimPoint = true; bool flag = _options.IsLocked(); if (flag) { HideRange(); ClearTargetOverlay(); } else { DrawRange(); UpdateTargetOverlay(localPlayer); } _options.OnFrame?.Invoke(localPlayer); UpdateStatusHud(); if (ZoneAreaToolShared.ShouldBlockInput()) { return true; } if (_suppressInputFrames > 0) { _suppressInputFrames--; return true; } if (_options.ShouldBlockToolInput()) { return true; } HandleScroll(flag); HandleOffset(); UpdateStatusHud(); if (!flag && Input.GetMouseButtonDown(0)) { _options.OnClick(localPlayer, CurrentArea); } return true; } private void HandleScroll(bool locked) { float axis = Input.GetAxis("Mouse ScrollWheel"); if (Mathf.Abs(axis) <= 0.001f) { return; } ZoneAreaCameraZoomGuard.SuppressWheelZoomThisFrame(); if (locked && _options.OnLockedScroll != null) { _options.OnLockedScroll(axis); return; } float delta = ((axis > 0f) ? _options.SizeStep : (0f - _options.SizeStep)); if (PlacementControlConfig.IsAreaDepthModifierHeld()) { ZoneAreaToolShared.ResizeDepth(ref _depth, delta, _options.MinSide, _options.MaxSide()); ClearTargetOverlay(); return; } if (PlacementControlConfig.IsAreaWidthModifierHeld()) { ZoneAreaToolShared.ResizeWidth(ref _width, delta, _options.MinSide, _options.MaxSide()); ClearTargetOverlay(); return; } if (PlacementControlConfig.IsAreaUniformScaleModifierHeld()) { ZoneAreaToolShared.ResizeUniform(ref _width, ref _depth, delta, _options.MinSide, _options.MaxSide()); ClearTargetOverlay(); return; } float num = ((axis > 0f) ? PlacementControlConfig.RotationStep : (0f - PlacementControlConfig.RotationStep)); _yaw = ZoneAreaSelection.NormalizeYaw(_yaw + num); _options.SetSavedYaw(_yaw); ClearTargetOverlay(); } private void HandleOffset() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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 (ZonePlacementInput.ApplyOffset(ref _horizontalOffset, ref _heightOffset)) { _aimPoint = GetAdjustedAimPoint(_rawAimPoint); ClearTargetOverlay(); } } private Vector3 GetAdjustedAimPoint(Vector3 rawAimPoint) { //IL_0000: 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_0013: Unknown result type (might be due to invalid IL or missing references) return ZoneAreaToolShared.GetAdjustedAimPoint(rawAimPoint, GetEffectiveYaw(), _horizontalOffset, _heightOffset); } private float GetEffectiveYaw() { return _options.GetEffectiveYaw?.Invoke(_yaw) ?? _yaw; } private void DrawRange() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) EnsureRangeLine(); if (!((Object)(object)_rangeLine == (Object)null)) { ZoneAreaToolShared.DrawGroundRectangle(_rangeLine, CurrentArea, _aimPoint, _heightOffset, _options.Color()); } } private void UpdateTargetOverlay(Player player) { if (ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { return; } ZoneAreaSelection currentArea = CurrentArea; int num = BuildTargetOverlaySignature(currentArea); bool num2 = !_hasTargetOverlaySignature || num != _lastTargetOverlaySignature; float time = Time.time; float num3 = (num2 ? _options.TargetOverlayRefreshInterval : Mathf.Max(_options.TargetOverlayRefreshInterval, _options.StableTargetOverlayRefreshInterval)); if (!(time - _lastTargetOverlayRefreshTime < num3)) { _lastTargetOverlaySignature = num; _hasTargetOverlaySignature = true; _lastTargetOverlayRefreshTime = time; if (_targetOverlay == null) { _targetOverlay = new ZoneAreaTargetOverlay(((Component)_owner).transform, _options.TargetOverlayName); } _targetOverlay.Draw(_options.FindCandidates(player, currentArea), currentArea); } } private void ClearTargetOverlay() { _targetOverlay?.Clear(); _lastTargetOverlayRefreshTime = -999f; _hasTargetOverlaySignature = false; } private static int BuildTargetOverlaySignature(ZoneAreaSelection area) { //IL_0007: 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) return ((((17 * 31 + Mathf.RoundToInt(area.Center.x * 2f)) * 31 + Mathf.RoundToInt(area.Center.z * 2f)) * 31 + Mathf.RoundToInt(area.Width * 2f)) * 31 + Mathf.RoundToInt(area.Depth * 2f)) * 31 + Mathf.RoundToInt(area.Yaw * 10f); } private void UpdateStatusHud() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) ZoneAreaToolStatusHud.Show(_options.StatusTitle(), FormattedSize, GetEffectiveYaw(), _horizontalOffset, _heightOffset); } private void EnsureRangeLine() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rangeLine != (Object)null)) { EnsureMaterial(); _rangeLine = ZoneAreaToolShared.CreateLineRenderer(((Component)_owner).transform, _options.RangeLineName, 0.05f, _options.Color(), _material); ((Renderer)_rangeLine).enabled = false; } } private void EnsureMaterial() { if (_material == null) { _material = ZoneAreaToolShared.CreateLineMaterial(); } } private void HideRange() { if ((Object)(object)_rangeLine != (Object)null) { ((Renderer)_rangeLine).enabled = false; } } } internal sealed class ZoneAreaDismantleTool : MonoBehaviour { private readonly struct DismantleTarget { public ZDO Zdo { get; } public GameObject Prefab { get; } public DismantleTarget(ZDO zdo, GameObject prefab) { Zdo = zdo; Prefab = prefab; } } private sealed class MaterialRefund { public string PrefabName { get; } public string DisplayName { get; } public ItemData Prototype { get; } public GameObject DropPrefab { get; } public int Amount { get; set; } public MaterialRefund(string prefabName, string displayName, ItemData prototype, GameObject dropPrefab) { PrefabName = prefabName; DisplayName = displayName; Prototype = prototype; DropPrefab = dropPrefab; } } private readonly struct DismantleResult { public bool Success { get; } public string Message { get; } public bool PlayDestroySfx { get; } public Vector3 EffectPosition { get; } public DismantleResult(bool success, string message, bool playDestroySfx = false, Vector3 effectPosition = default(Vector3)) { //IL_0016: 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) Success = success; Message = message; PlayDestroySfx = playDestroySfx; EffectPosition = effectPosition; } public static DismantleResult Ok(string message, Vector3 effectPosition) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return new DismantleResult(success: true, message, playDestroySfx: true, effectPosition); } public static DismantleResult Fail(string message) { //IL_0005: 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) return new DismantleResult(success: false, message); } } private const float MinSideLength = 1f; private const float SizeStep = 1f; private const float TargetOverlayRefreshInterval = 0.3f; private const float RequestCooldownSeconds = 1f; private const float RequestCooldownCleanupSeconds = 60f; private const string RequestRpcName = "sighsorry.Homestead_AreaDismantleRequest"; private const string ResultRpcName = "sighsorry.Homestead_AreaDismantleResult"; private const string DestroySfxPrefab = "sfx_wood_destroyed"; private static ManualLogSource? _logger; private static ZoneAreaDismantleTool? _instance; private static readonly ZoneRpcRegistrar RpcRegistrar = new ZoneRpcRegistrar(); private static float? _lastAreaYaw; private static readonly Dictionary NextRequestAtBySender = new Dictionary(); private static float _nextCooldownCleanup; private readonly List _nearbyTargetZdos = new List(); private readonly List _targetCandidateZdos = new List(); private ZoneAreaToolController? _areaTool; private bool _active; private static float MaxSelectableSide => Mathf.Max(1f, BlueprintConfig.AreaDismantleMaxSide); public static bool IsActive { get { ZoneAreaDismantleTool? instance = _instance; if (instance == null) { return false; } return (instance._areaTool?.Active).GetValueOrDefault(); } } private ZoneAreaToolController AreaTool => _areaTool ?? (_areaTool = new ZoneAreaToolController((MonoBehaviour)(object)this, new ZoneAreaToolController.Options { MinSide = 1f, SizeStep = 1f, MaxSide = () => MaxSelectableSide, DefaultWidth = () => BlueprintConfig.AreaDismantleDefaultWidth, DefaultDepth = () => BlueprintConfig.AreaDismantleDefaultDepth, Color = () => BlueprintConfig.AreaDismantleBoundaryColor, RangeLineName = "HomesteadAreaDismantleRadius", TargetOverlayName = "HomesteadAreaDismantleTarget", TargetOverlayRefreshInterval = 0.3f, GetSavedYaw = () => _lastAreaYaw, SetSavedYaw = delegate(float yaw) { _lastAreaYaw = yaw; }, StatusTitle = () => HomesteadLocalization.Text("hs_area_dismantle_name"), FindCandidates = FindDismantlePreviewCandidates, OnClick = RequestDismantle })); public static void Initialize(ManualLogSource logger) { _logger = logger; EnsureInstance(); RegisterRpcs(); } internal static void RegisterRpcs() { RpcRegistrar.EnsureRegistered(delegate(ZRoutedRpc routedRpc) { routedRpc.Register("sighsorry.Homestead_AreaDismantleRequest", (Action)RPC_HandleRequest); routedRpc.Register("sighsorry.Homestead_AreaDismantleResult", (Action)RPC_HandleResult); }); } public static void Activate(Player player) { EnsureInstance(); _instance?.ActivateInternal(player); } public static void Deactivate() { _instance?.DeactivateInternal(); } private static void EnsureInstance() { //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 if (!((Object)(object)_instance != (Object)null) || !Object.op_Implicit((Object)(object)_instance)) { GameObject val = new GameObject("HomesteadAreaDismantleTool"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void ActivateInternal(Player player) { _active = true; AreaTool.Activate(player); } private void DeactivateInternal() { _active = false; _areaTool?.Deactivate(); } private void Update() { if (!_active) { ZoneAreaToolController? areaTool = _areaTool; if (areaTool == null || !areaTool.Active) { return; } } if (!AreaTool.Tick()) { DeactivateInternal(); } } private void OnDestroy() { _areaTool?.Destroy(); _areaTool = null; if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } private void RequestDismantle(Player player) { RequestDismantle(player, AreaTool.CurrentArea); } private void RequestDismantle(Player player, ZoneAreaSelection area) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_0086: 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) if (!AreaTool.HasAimPoint) { return; } if ((Object)(object)ZNet.instance == (Object)null || ZDOMan.instance == null) { ShowResult(DismantleResult.Fail(HomesteadLocalization.Text("hs_common_world_not_ready"))); return; } if (ZNet.instance.IsServer()) { long playerID = player.GetPlayerID(); if (!TryReserveLocalRequest(playerID, out string reason)) { ShowResult(DismantleResult.Fail(reason)); } else { ShowResult(ExecuteDismantle(playerID, ((Component)player).transform.position, area)); } return; } RegisterRpcs(); ZPackage val = new ZPackage(); val.Write(area.Center); val.Write(area.Width); val.Write(area.Depth); val.Write(area.Yaw); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "sighsorry.Homestead_AreaDismantleRequest", new object[1] { val }); } private static void RPC_HandleRequest(long sender, ZPackage package) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00da: 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) //IL_0034: 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_0069: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } DismantleResult dismantleResult; try { if (!TryReserveRequest(sender, out string reason)) { dismantleResult = DismantleResult.Fail(reason); } else { Vector3 center = package.ReadVector3(); float width = package.ReadSingle(); float depth = package.ReadSingle(); float yaw = package.ReadSingle(); dismantleResult = (TryResolveRemotePlayer(sender, out long playerId, out Vector3 playerPosition, out string reason2) ? ExecuteDismantle(playerId, playerPosition, new ZoneAreaSelection(center, width, depth, yaw)) : DismantleResult.Fail(reason2)); } } catch (Exception ex) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogError((object)$"Area dismantle RPC failed: {ex}"); } dismantleResult = DismantleResult.Fail(ex.Message); } ZPackage val = new ZPackage(); val.Write(dismantleResult.Success); val.Write(dismantleResult.Message); val.Write(dismantleResult.PlayDestroySfx); val.Write(dismantleResult.EffectPosition); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "sighsorry.Homestead_AreaDismantleResult", new object[1] { val }); } private static bool TryReserveRequest(long sender, out string reason) { reason = ""; if (sender == 0L) { return true; } float now = Time.realtimeSinceStartup; if (now >= _nextCooldownCleanup) { _nextCooldownCleanup = now + 60f; foreach (long item in (from pair in NextRequestAtBySender where pair.Value <= now select pair.Key).ToList()) { NextRequestAtBySender.Remove(item); } } if (NextRequestAtBySender.TryGetValue(sender, out var value) && now < value) { reason = HomesteadLocalization.Text("hs_dismantle_rpc_cooldown"); return false; } NextRequestAtBySender[sender] = now + 1f; return true; } private static bool TryReserveLocalRequest(long playerId, out string reason) { reason = ""; if (playerId == 0L) { return true; } return TryReserveRequest((playerId > 0) ? (-playerId) : playerId, out reason); } private static void RPC_HandleResult(long sender, ZPackage package) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()) { ShowResult(new DismantleResult(package.ReadBool(), package.ReadString(), package.ReadBool(), package.ReadVector3())); } } private IReadOnlyList FindDismantlePreviewCandidates(Player player, ZoneAreaSelection area) { _targetCandidateZdos.Clear(); if (ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)player == (Object)null) { return _targetCandidateZdos; } long playerID = player.GetPlayerID(); if (playerID == 0L) { return _targetCandidateZdos; } HashSet areaDismantlePrefabBlacklist = BlueprintConfig.AreaDismantlePrefabBlacklist; ZoneAreaTargetOverlay.CollectNearbyZdos(area, _nearbyTargetZdos); foreach (ZDO nearbyTargetZdo in _nearbyTargetZdos) { if (!ZoneBlueprintCommands.IsHomesteadBlueprintChest(nearbyTargetZdo) && nearbyTargetZdo.GetLong(ZDOVars.s_creator, 0L) == playerID && ZoneBlueprintCommands.TryReadWearNTear(nearbyTargetZdo, out GameObject prefab) && IsLoadedWearNTear(nearbyTargetZdo)) { string prefabName = Utils.GetPrefabName(prefab); if (!areaDismantlePrefabBlacklist.Contains(prefabName) && !HasProtectedContentsOrAttachments(nearbyTargetZdo, prefab)) { _targetCandidateZdos.Add(nearbyTargetZdo); } } } return _targetCandidateZdos; } private static bool IsLoadedWearNTear(ZDO zdo) { if ((Object)(object)ZNetScene.instance == (Object)null) { return false; } ZNetView val = ZNetScene.instance.FindInstance(zdo); if ((Object)(object)val != (Object)null) { return (Object)(object)((Component)val).GetComponent() != (Object)null; } return false; } private static DismantleResult ExecuteDismantle(long playerId, Vector3 playerPosition, ZoneAreaSelection area) { //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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) if (ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { return DismantleResult.Fail(HomesteadLocalization.Text("hs_common_world_not_ready")); } if (playerId == 0L) { return DismantleResult.Fail(HomesteadLocalization.Text("hs_dismantle_playerid_missing")); } float maxSelectableSide = MaxSelectableSide; area = area.Clamp(1f, maxSelectableSide); if (HorizontalDistance(area.Center, playerPosition) > area.HalfDiagonal + maxSelectableSide + 16f) { return DismantleResult.Fail(HomesteadLocalization.Text("hs_dismantle_too_far")); } List list = new List(); int num = 0; int num2 = 0; int num3 = 0; HashSet areaDismantlePrefabBlacklist = BlueprintConfig.AreaDismantlePrefabBlacklist; List list2 = new List(); ZoneAreaTargetOverlay.CollectNearbyZdos(area, list2); foreach (ZDO item in list2) { if (!ZoneBlueprintCommands.TryReadWearNTear(item, out GameObject prefab)) { continue; } string prefabName = Utils.GetPrefabName(prefab); if (area.Contains(item.GetPosition())) { if (ZoneBlueprintCommands.IsHomesteadBlueprintChest(item)) { num2++; } else if (areaDismantlePrefabBlacklist.Contains(prefabName) || ZoneBlueprintCommands.IsHomesteadBlueprintChestPrefab(prefab)) { num2++; } else if (item.GetLong(ZDOVars.s_creator, 0L) != playerId) { num++; } else if (HasProtectedContentsOrAttachments(item, prefab)) { num3++; } else { list.Add(new DismantleTarget(item, prefab)); } } } if (list.Count == 0) { string text = BuildSkippedMessage(num, num2, num3, verbose: true); return DismantleResult.Fail(HomesteadLocalization.Format("hs_dismantle_no_owned", Mathf.RoundToInt(area.Width), Mathf.RoundToInt(area.Depth), text)); } Dictionary dictionary = new Dictionary(); foreach (DismantleTarget item2 in list) { CollectRefundMaterials(item2.Prefab, dictionary); } int num4 = 0; foreach (DismantleTarget item3 in list) { if (item3.Zdo != null && item3.Zdo.IsValid()) { SavedZdoHelper.Destroy(item3.Zdo); num4++; } } SavedZdoHelper.FlushDestroyed(); int num5 = dictionary.Values.Sum((MaterialRefund refund) => refund.Amount); int num6 = DropRefundStacks(dictionary.Values, area.Center); string text2 = BuildSkippedMessage(num, num2, num3, verbose: false); return DismantleResult.Ok(HomesteadLocalization.Format("hs_dismantle_done", num4, num5, num6, text2), area.Center); } private static string BuildSkippedMessage(int skippedNotOwned, int skippedBlacklisted, int skippedWithContents, bool verbose) { List list = new List(); if (skippedNotOwned > 0) { list.Add(verbose ? HomesteadLocalization.Format("hs_dismantle_skipped_not_owned_verbose", skippedNotOwned) : HomesteadLocalization.Format("hs_dismantle_skipped_not_owned_short", skippedNotOwned)); } if (skippedBlacklisted > 0) { list.Add(verbose ? HomesteadLocalization.Format("hs_dismantle_skipped_blacklisted_verbose", skippedBlacklisted) : HomesteadLocalization.Format("hs_dismantle_skipped_blacklisted_short", skippedBlacklisted)); } if (skippedWithContents > 0) { list.Add(verbose ? HomesteadLocalization.Format("hs_dismantle_skipped_contents_verbose", skippedWithContents) : HomesteadLocalization.Format("hs_dismantle_skipped_contents_short", skippedWithContents)); } if (list.Count != 0) { return HomesteadLocalization.Format("hs_dismantle_skipped_suffix", string.Join(", ", list)); } return ""; } private static bool HasProtectedContentsOrAttachments(ZDO zdo, GameObject prefab) { if ((Object)(object)prefab.GetComponent() != (Object)null && HasContainerItems(zdo)) { return true; } if ((Object)(object)prefab.GetComponent() != (Object)null && !string.IsNullOrEmpty(zdo.GetString(ZDOVars.s_item, ""))) { return true; } ArmorStand component = prefab.GetComponent(); if ((Object)(object)component != (Object)null) { int num = Mathf.Max(component.m_slots?.Count ?? 0, 32); for (int i = 0; i < num; i++) { if (!string.IsNullOrEmpty(zdo.GetString(i + "_item", ""))) { return true; } } } return false; } private static bool HasContainerItems(ZDO zdo) { //IL_001a: 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) string @string = zdo.GetString(ZDOVars.s_items, ""); if (!string.IsNullOrEmpty(@string)) { try { ZPackage val = new ZPackage(@string); val.ReadInt(); return val.ReadInt() > 0; } catch { return true; } } ZNetScene instance = ZNetScene.instance; ZNetView val2 = ((instance != null) ? instance.FindInstance(zdo) : null); Container val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent() : null); if ((Object)(object)val3 == (Object)null) { return false; } try { val3.Load(); } catch { } Inventory inventory = val3.GetInventory(); if (inventory == null) { return false; } return inventory.NrOfItems() > 0; } private static bool TryResolveRemotePlayer(long sender, out long playerId, out Vector3 playerPosition, out string reason) { //IL_0005: 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_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_007b: Unknown result type (might be due to invalid IL or missing references) playerId = 0L; playerPosition = Vector3.zero; reason = ""; if ((Object)(object)ZNet.instance == (Object)null || ZDOMan.instance == null) { reason = "World is not ready."; return false; } ZNetPeer peer = ZNet.instance.GetPeer(sender); if (peer == null || !peer.IsReady()) { reason = "Player is not ready."; return false; } playerPosition = peer.m_refPos; if (((ZDOID)(ref peer.m_characterID)).IsNone()) { reason = "Could not resolve your character."; return false; } ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); playerId = ((zDO != null) ? zDO.GetLong(ZDOVars.s_playerID, 0L) : 0); if (playerId == 0L) { reason = "Could not resolve your playerID."; return false; } return true; } private static void CollectRefundMaterials(GameObject prefab, Dictionary refunds) { Piece component = prefab.GetComponent(); if ((Object)(object)component == (Object)null) { return; } Requirement[] resources = component.m_resources; foreach (Requirement val in resources) { if (!Object.op_Implicit((Object)(object)val.m_resItem) || val.m_amount <= 0 || !val.m_recover) { continue; } int amount = val.GetAmount(0); if (amount > 0) { string prefabName = Utils.GetPrefabName(((Component)val.m_resItem).gameObject); if (!refunds.TryGetValue(prefabName, out MaterialRefund value)) { value = (refunds[prefabName] = new MaterialRefund(prefabName, val.m_resItem.m_itemData.m_shared.m_name, val.m_resItem.m_itemData, ((Component)val.m_resItem).gameObject)); } value.Amount += amount; } } } private static int DropRefundStacks(IEnumerable refunds, Vector3 dropPosition) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_0090: 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_009a: 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_009f: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (MaterialRefund refund in refunds) { if (refund.Amount > 0) { int num2 = Mathf.Max(1, refund.Prototype.m_shared.m_maxStackSize); int num3 = refund.Amount; while (num3 > 0) { int num4 = Mathf.Min(num3, num2); ItemData obj = refund.Prototype.Clone(); obj.m_stack = num4; obj.m_dropPrefab = refund.DropPrefab; Vector2 val = Random.insideUnitCircle * 0.8f; Vector3 val2 = dropPosition + new Vector3(val.x, 0.85f, val.y); ItemDrop.DropItem(obj, 0, val2, Random.rotation); num3 -= num4; num++; } } } return num; } private static float HorizontalDistance(Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = a.x - b.x; float num2 = a.z - b.z; return Mathf.Sqrt(num * num + num2 * num2); } private static void ShowResult(DismantleResult result) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)result.Message); } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)(result.Success ? 1 : 2), result.Message, 0, (Sprite)null); } if (result.PlayDestroySfx) { PlayDestroySfx(result.EffectPosition); } } private static void PlayDestroySfx(Vector3 position) { //IL_0021: 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) ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab("sfx_wood_destroyed") : null); if (Object.op_Implicit((Object)(object)val)) { Object.Instantiate(val, position, Quaternion.identity); } } private static void Message(Player player, string message) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)message); } ((Character)player).Message((MessageType)1, message, 0, (Sprite)null); } } internal readonly struct ZoneAreaSelection { public Vector3 Center { get; } public float Width { get; } public float Depth { get; } public float Yaw { get; } public float MaxSide => Mathf.Max(Width, Depth); public float HalfDiagonal => Mathf.Sqrt(Width * Width + Depth * Depth) * 0.5f; public Quaternion Rotation => Quaternion.Euler(0f, Yaw, 0f); public ZoneAreaSelection(Vector3 center, float width, float depth, float yaw) { //IL_0001: 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) Center = center; Width = Mathf.Max(0.01f, width); Depth = Mathf.Max(0.01f, depth); Yaw = NormalizeYaw(yaw); } public ZoneAreaSelection Clamp(float minSide, float maxSide) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new ZoneAreaSelection(Center, Mathf.Clamp(Width, minSide, maxSide), Mathf.Clamp(Depth, minSide, maxSide), Yaw); } public bool Contains(Vector3 worldPosition) { //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_000b: 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_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_001c: 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_0036: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Quaternion.Inverse(Rotation) * (worldPosition - Center); if (Mathf.Abs(val.x) <= Width * 0.5f) { return Mathf.Abs(val.z) <= Depth * 0.5f; } return false; } public bool IntersectsBoundary(Bounds worldBounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) GetLocalBounds(worldBounds, out var minX, out var maxX, out var minZ, out var maxZ); float num = Width * 0.5f; float num2 = Depth * 0.5f; if (!(maxX >= 0f - num) || !(minX <= num) || !(maxZ >= 0f - num2) || !(minZ <= num2)) { return false; } return !(minX >= 0f - num) || !(maxX <= num) || !(minZ >= 0f - num2) || !(maxZ <= num2); } public Vector3 GetCorner(int index) { //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_0047: 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_0056: 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) //IL_006c: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_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) //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) float num = Width * 0.5f; float num2 = Depth * 0.5f; Vector3 val = (Vector3)(index switch { 0 => new Vector3(0f - num, 0f, 0f - num2), 1 => new Vector3(num, 0f, 0f - num2), 2 => new Vector3(num, 0f, num2), _ => new Vector3(0f - num, 0f, num2), }); return Center + Rotation * val; } private void GetLocalBounds(Bounds worldBounds, out float minX, out float maxX, out float minZ, out float maxZ) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_001a: 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_0036: 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) //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) //IL_0052: 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_0067: 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_0073: 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_007f: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_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_00ec: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Quaternion.Inverse(Rotation); Vector3 min = ((Bounds)(ref worldBounds)).min; Vector3 max = ((Bounds)(ref worldBounds)).max; minX = (minZ = float.PositiveInfinity); maxX = (maxZ = float.NegativeInfinity); Encapsulate(val * (new Vector3(min.x, 0f, min.z) - Center), ref minX, ref maxX, ref minZ, ref maxZ); Encapsulate(val * (new Vector3(min.x, 0f, max.z) - Center), ref minX, ref maxX, ref minZ, ref maxZ); Encapsulate(val * (new Vector3(max.x, 0f, min.z) - Center), ref minX, ref maxX, ref minZ, ref maxZ); Encapsulate(val * (new Vector3(max.x, 0f, max.z) - Center), ref minX, ref maxX, ref minZ, ref maxZ); } private static void Encapsulate(Vector3 local, ref float minX, ref float maxX, ref float minZ, ref float maxZ) { //IL_0003: 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_0021: 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) minX = Mathf.Min(minX, local.x); maxX = Mathf.Max(maxX, local.x); minZ = Mathf.Min(minZ, local.z); maxZ = Mathf.Max(maxZ, local.z); } public static float NormalizeYaw(float yaw) { yaw %= 360f; if (!(yaw < 0f)) { return yaw; } return yaw + 360f; } } internal static class ZoneAreaToolShared { private const float LineHeight = 0.25f; private const int MinEdgeSegments = 4; private const int MaxEdgeSegments = 64; public static ZoneAreaSelection BuildArea(Vector3 center, ref float width, ref float depth, float yaw, float defaultWidth, float defaultDepth, float minSide, float maxSide) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) width = Mathf.Clamp((width <= 0f) ? defaultWidth : width, minSide, maxSide); depth = Mathf.Clamp((depth <= 0f) ? defaultDepth : depth, minSide, maxSide); return new ZoneAreaSelection(center, width, depth, yaw).Clamp(minSide, maxSide); } public static void ResizeUniform(ref float width, ref float depth, float delta, float minSide, float maxSide) { float num = Mathf.Max(minSide, Mathf.Max(width, depth)); float num2 = Mathf.Clamp(num + delta, minSide, maxSide) / num; width = Mathf.Clamp(width * num2, minSide, maxSide); depth = Mathf.Clamp(depth * num2, minSide, maxSide); } public static void ResizeDepth(ref float depth, float delta, float minSide, float maxSide) { depth = Mathf.Clamp(depth + delta, minSide, maxSide); } public static void ResizeWidth(ref float width, float delta, float minSide, float maxSide) { width = Mathf.Clamp(width + delta, minSide, maxSide); } public static void DrawGroundRectangle(LineRenderer line, ZoneAreaSelection area, Vector3 center, float heightOffset, Color color) { //IL_0008: 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_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_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_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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00ea: 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_0062: 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_006f: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) ((Renderer)line).enabled = true; line.startColor = color; line.endColor = color; int num = Mathf.Clamp(Mathf.CeilToInt(area.MaxSide / 4f), 4, 64); line.positionCount = num * 4 + 1; int num2 = 0; for (int i = 0; i < 4; i++) { Vector3 corner = area.GetCorner(i); Vector3 corner2 = area.GetCorner((i + 1) % 4); for (int j = 0; j < num; j++) { Vector3 val = Vector3.Lerp(corner, corner2, (float)j / (float)num); val.y = ZoneToolAim.SampleGroundY(val.x, val.z, center.y) + 0.25f + heightOffset; line.SetPosition(num2++, val); } } Vector3 corner3 = area.GetCorner(0); corner3.y = ZoneToolAim.SampleGroundY(corner3.x, corner3.z, center.y) + 0.25f + heightOffset; line.SetPosition(num2, corner3); } public static LineRenderer CreateLineRenderer(Transform parent, string objectName, float width, Color color, Material? material) { //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_0052: 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) GameObject val = new GameObject(objectName); val.transform.SetParent(parent, false); LineRenderer obj = val.AddComponent(); obj.useWorldSpace = true; obj.startWidth = width; obj.endWidth = width; obj.numCornerVertices = 2; obj.numCapVertices = 2; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).material = material; obj.startColor = color; obj.endColor = color; return obj; } public static Material? CreateLineMaterial() { //IL_0025: 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_0036: Expected O, but got Unknown Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color"); if ((Object)(object)val == (Object)null) { return null; } return new Material(val) { color = Color.white }; } public static Vector3 GetAdjustedAimPoint(Vector3 aimPoint, float yaw, Vector3 horizontalOffset, float heightOffset) { //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_0004: 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) return aimPoint + ZonePlacementOffset.ToWorldOffset(yaw, horizontalOffset, heightOffset); } public static string FormatSize(float width, float depth) { return $"{Mathf.RoundToInt(width)}x{Mathf.RoundToInt(depth)}m"; } public static string FormatScaleInput() { if (!string.IsNullOrWhiteSpace(PlacementControlConfig.AreaUniformScaleInputLabel)) { return PlacementControlConfig.AreaUniformScaleInputLabel; } return HomesteadLocalization.Text("hs_common_unbound"); } public static string FormatDepthInput() { if (!string.IsNullOrWhiteSpace(BlueprintConfig.AreaToolDepthInputLabel)) { return BlueprintConfig.AreaToolDepthInputLabel; } return HomesteadLocalization.Text("hs_common_unbound"); } public static string FormatWidthInput() { if (!string.IsNullOrWhiteSpace(BlueprintConfig.AreaToolWidthInputLabel)) { return BlueprintConfig.AreaToolWidthInputLabel; } return HomesteadLocalization.Text("hs_common_unbound"); } public static bool TryGetAimPoint(Player player, float maxSelectableSide, out Vector3 point) { return ZoneToolAim.TryGetAimPoint(player, maxSelectableSide * 2f, out point); } public static bool ShouldBlockInput() { if (Hud.IsPieceSelectionVisible() || Console.IsVisible() || HomesteadInputBlockers.IsTextInputVisible() || Menu.IsVisible() || InventoryGui.IsVisible() || Minimap.IsOpen()) { return true; } if ((Object)(object)Chat.instance != (Object)null) { return Chat.instance.HasFocus(); } return false; } } internal sealed class ZoneAreaToolStatusHud : MonoBehaviour { private static ZoneAreaToolStatusHud? _instance; private static bool _missingFontLogged; private CanvasGroup? _canvasGroup; private TextMeshProUGUI? _text; private RectTransform? _rectTransform; private string _areaLine = ""; private string _placementLine = ""; private string _dvergrLine = ""; private string _buildCameraLine = ""; private string _pickupLine = ""; private string _lastAreaLine = ""; private string _lastPlacementLine = ""; private string _lastDvergrLine = ""; private float _areaHideAfter = float.MinValue; private float _placementHideAfter = float.MinValue; private float _dvergrHideAfter = float.MinValue; private float _buildCameraHideAfter = float.MinValue; private float _pickupHideAfter = float.MinValue; public static void Show(string title, string size, float yaw, Vector3 horizontalOffset, float heightOffset) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ShowPlacementLine(horizontalOffset, heightOffset, yaw, FormatAreaSize(size)); } public static void ShowBlueprint(string title, float yaw, Vector3 horizontalOffset, float heightOffset) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ShowPlacementLine(horizontalOffset, heightOffset, yaw); } public static void ShowOffset(string title, Vector3 horizontalOffset, float heightOffset, float xAxisRotation = 0f, float zAxisRotation = 0f) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) float degree = ((Mathf.Abs(xAxisRotation) >= 0.001f) ? xAxisRotation : zAxisRotation); ShowPlacementLine(horizontalOffset, heightOffset, degree); } public static void ShowDefaultPlacement(Vector3 horizontalOffset, float heightOffset, float yaw, float xAxisRotation, float zAxisRotation, bool keepVisible) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Hud.instance == (Object)null)) { EnsureInstance(); _instance?.SetAreaLine("", keepVisible: false); _instance?.SetPlacementLine(FormatDefaultPlacementLine(horizontalOffset, heightOffset, yaw, xAxisRotation, zAxisRotation), 1f, keepVisible); } } public static void ShowDvergrCirclet(bool lightOn, float intensityMultiplier, float rangeMultiplier) { if (!((Object)(object)Hud.instance == (Object)null)) { EnsureInstance(); _instance?.SetDvergrLine(HomesteadLocalization.Format("hs_dvergr_hud", lightOn ? HomesteadLocalization.Text("hs_common_on") : HomesteadLocalization.Text("hs_common_off"), rangeMultiplier * 100f, intensityMultiplier * 100f), 1f); } } public static void ShowCameraPickupBlocked(string message) { if (!((Object)(object)Hud.instance == (Object)null)) { EnsureInstance(); _instance?.SetPickupLine(message, 0.35f); } } public static void ShowBuildCameraDistance(float currentDistance, float maxDistance, string detail, float maxPlaceDistance, string placeDetail, float resourcePickupRange, string pickupDetail) { if (!((Object)(object)Hud.instance == (Object)null)) { EnsureInstance(); string text = (string.IsNullOrWhiteSpace(detail) ? "" : (" = " + detail)); string text2 = (string.IsNullOrWhiteSpace(placeDetail) ? "" : (" = " + placeDetail)); string text3 = (string.IsNullOrWhiteSpace(pickupDetail) ? "" : (" = " + pickupDetail)); string text4 = HomesteadLocalization.Format("hs_build_camera_distance_hud", FormatMeters(currentDistance), FormatMeters(maxDistance), text); string text5 = HomesteadLocalization.Format("hs_build_camera_place_distance_hud", FormatMeters(maxPlaceDistance), text2); string text6 = HomesteadLocalization.Format("hs_build_camera_pickup_range_hud", FormatMeters(resourcePickupRange), text3); _instance?.SetBuildCameraLine(text4 + "\n" + text5 + "\n" + text6); } } public static void HideBuildCameraDistance() { if (!((Object)(object)_instance == (Object)null)) { _instance._buildCameraLine = ""; _instance._buildCameraHideAfter = float.MinValue; _instance.RefreshText(); } } public static void Hide() { ClearPlacementLine(force: true); } public static void HideDefaultPlacement() { ClearPlacementLine(force: false); } private static void ClearPlacementLine(bool force) { if (((!ZoneBlueprintSaveTool.IsActive && !ZoneAreaDismantleTool.IsActive && !ZoneBlueprintPlacementTool.IsActive) || force) && !((Object)(object)_instance == (Object)null)) { _instance._placementLine = ""; _instance._areaLine = ""; _instance._lastPlacementLine = ""; _instance._lastAreaLine = ""; _instance._placementHideAfter = float.MinValue; _instance._areaHideAfter = float.MinValue; _instance.RefreshText(); } } private static void ShowPlacementLine(Vector3 horizontalOffset, float heightOffset, float degree, string areaSize = "") { //IL_001b: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Hud.instance == (Object)null)) { bool flag = !string.IsNullOrWhiteSpace(areaSize); bool keepVisible = flag || HasNonZeroPlacementValue(horizontalOffset, heightOffset, degree); EnsureInstance(); _instance?.SetAreaLine(flag ? areaSize : "", keepVisible); _instance?.SetPlacementLine("X " + Format(horizontalOffset.x) + " | Y " + Format(heightOffset) + " | Z " + Format(horizontalOffset.z) + " | θ " + FormatDegree(degree), 1f, keepVisible); } } private static void EnsureInstance() { if ((Object)(object)Hud.instance == (Object)null) { return; } if ((Object)(object)_instance != (Object)null && Object.op_Implicit((Object)(object)_instance)) { _instance.EnsureElements(); return; } _instance = ((Component)Hud.instance).GetComponent(); if ((Object)(object)_instance == (Object)null) { _instance = ((Component)Hud.instance).gameObject.AddComponent(); } _instance.EnsureElements(); } private void Update() { bool flag = false; if (!string.IsNullOrEmpty(_areaLine) && Time.unscaledTime > _areaHideAfter) { _areaLine = ""; flag = true; } if (!string.IsNullOrEmpty(_placementLine) && Time.unscaledTime > _placementHideAfter) { _placementLine = ""; flag = true; } if (!string.IsNullOrEmpty(_dvergrLine) && Time.unscaledTime > _dvergrHideAfter) { _dvergrLine = ""; flag = true; } if (!string.IsNullOrEmpty(_buildCameraLine) && Time.unscaledTime > _buildCameraHideAfter) { _buildCameraLine = ""; flag = true; } if (!string.IsNullOrEmpty(_pickupLine) && Time.unscaledTime > _pickupHideAfter) { _pickupLine = ""; flag = true; } if (flag) { RefreshText(); } ApplyLayout(); } private void SetAreaLine(string line, bool keepVisible) { EnsureElements(); if (!CanShow()) { return; } if (string.IsNullOrWhiteSpace(line)) { if (!string.IsNullOrEmpty(_areaLine) || !string.IsNullOrEmpty(_lastAreaLine)) { _areaLine = ""; _lastAreaLine = ""; _areaHideAfter = float.MinValue; RefreshText(); } } else if (!string.Equals(_lastAreaLine, line, StringComparison.Ordinal)) { _lastAreaLine = line; _areaLine = line; _areaHideAfter = (keepVisible ? float.PositiveInfinity : (Time.unscaledTime + 1f)); RefreshText(); } else if (keepVisible && !float.IsPositiveInfinity(_areaHideAfter)) { _areaLine = line; _areaHideAfter = float.PositiveInfinity; RefreshText(); } } private void SetPlacementLine(string line, float visibleSeconds, bool keepVisible) { EnsureElements(); if (CanShow()) { if (!string.Equals(_lastPlacementLine, line, StringComparison.Ordinal)) { _lastPlacementLine = line; _placementLine = line; _placementHideAfter = (keepVisible ? float.PositiveInfinity : (Time.unscaledTime + visibleSeconds)); RefreshText(); } else if (keepVisible && !float.IsPositiveInfinity(_placementHideAfter)) { _placementLine = line; _placementHideAfter = float.PositiveInfinity; RefreshText(); } } } private void SetDvergrLine(string line, float visibleSeconds) { EnsureElements(); if (CanShow()) { if (!string.Equals(_lastDvergrLine, line, StringComparison.Ordinal)) { _lastDvergrLine = line; _dvergrLine = line; _dvergrHideAfter = Time.unscaledTime + visibleSeconds; RefreshText(); } else if (Time.unscaledTime <= _dvergrHideAfter) { RefreshText(); } } } private void SetPickupLine(string line, float visibleSeconds) { EnsureElements(); if (CanShow()) { _pickupLine = line; _pickupHideAfter = Time.unscaledTime + visibleSeconds; RefreshText(); } } private void SetBuildCameraLine(string line) { EnsureElements(); if (CanShow()) { _buildCameraLine = line; _buildCameraHideAfter = float.PositiveInfinity; RefreshText(); } } private bool CanShow() { if ((Object)(object)_text != (Object)null && (Object)(object)_canvasGroup != (Object)null) { return (Object)(object)_rectTransform != (Object)null; } return false; } private void RefreshText() { if (CanShow()) { PruneExpiredLines(); string[] source = new string[5] { _areaLine, _placementLine, _dvergrLine, _buildCameraLine, _pickupLine }; ((TMP_Text)_text).text = string.Join("\n", source.Where((string line) => !string.IsNullOrEmpty(line))); _canvasGroup.alpha = (string.IsNullOrEmpty(((TMP_Text)_text).text) ? 0f : 1f); ((TMP_Text)_text).transform.SetAsLastSibling(); ApplyLayout(); } } private void EnsureElements() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Hud.instance == (Object)null) { return; } TextMeshProUGUI val = FindHudTextTemplate(); if ((Object)(object)((val != null) ? ((TMP_Text)val).font : null) == (Object)null) { LogMissingFontOnce(); return; } if ((Object)(object)_text == (Object)null || (Object)(object)_canvasGroup == (Object)null || (Object)(object)_rectTransform == (Object)null) { _text = Object.Instantiate(val, ((Component)Hud.instance).transform, false); GameObject gameObject = ((Component)_text).gameObject; ((Object)gameObject).name = "HomesteadUnifiedStatusHud"; gameObject.SetActive(true); gameObject.transform.SetAsLastSibling(); _rectTransform = (RectTransform)gameObject.transform; _rectTransform.anchorMin = new Vector2(0f, 1f); _rectTransform.anchorMax = new Vector2(0f, 1f); _rectTransform.pivot = new Vector2(0f, 1f); _canvasGroup = gameObject.GetComponent(); if ((Object)(object)_canvasGroup == (Object)null) { _canvasGroup = gameObject.AddComponent(); } _canvasGroup.alpha = 0f; ((Graphic)_text).color = new Color(1f, 0.86f, 0.45f, 1f); ((TMP_Text)_text).alignment = (TextAlignmentOptions)513; ((TMP_Text)_text).enableAutoSizing = false; ((TMP_Text)_text).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)_text).overflowMode = (TextOverflowModes)0; ((TMP_Text)_text).margin = Vector4.zero; ((Graphic)_text).raycastTarget = false; ((TMP_Text)_text).text = string.Empty; } if (!((Object)(object)_text == (Object)null)) { ((TMP_Text)_text).font = ((TMP_Text)val).font; if ((Object)(object)((TMP_Text)val).fontSharedMaterial != (Object)null) { ((TMP_Text)_text).fontSharedMaterial = ((TMP_Text)val).fontSharedMaterial; } ApplyLayout(); } } private void ApplyLayout() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rectTransform == (Object)null) && !((Object)(object)_text == (Object)null)) { _rectTransform.anchoredPosition = ClientConfig.StatusHudPosition; ((TMP_Text)_text).fontSize = ClientConfig.StatusHudFontSize; _rectTransform.sizeDelta = CalculateHudSize(((TMP_Text)_text).fontSize); } } private static TextMeshProUGUI? FindHudTextTemplate() { TMP_Text obj = Hud.instance?.m_buildSelection; TextMeshProUGUI val = (TextMeshProUGUI)(object)((obj is TextMeshProUGUI) ? obj : null); if ((Object)(object)((val != null) ? ((TMP_Text)val).font : null) != (Object)null) { return val; } Hud instance = Hud.instance; if (instance == null) { return null; } return ((IEnumerable)((Component)instance).GetComponentsInChildren(true)).FirstOrDefault((Func)((TextMeshProUGUI text) => (Object)(object)text != (Object)null && (Object)(object)((TMP_Text)text).font != (Object)null)); } private static void LogMissingFontOnce() { if (!_missingFontLogged) { _missingFontLogged = true; HomesteadPlugin.HomesteadLogger.LogWarning((object)"Homestead status HUD could not find a TextMeshPro font asset."); } } private static Vector2 CalculateHudSize(float fontSize) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) float num = fontSize * 7f * 1.45f + 12f; return new Vector2(Mathf.Clamp(fontSize * 34f, 220f, 1800f), Mathf.Clamp(num, 40f, 420f)); } private static string Format(float value) { return value.ToString("+0.##;-0.##;0", CultureInfo.InvariantCulture); } private static string FormatDegree(float value) { return value.ToString("0.#", CultureInfo.InvariantCulture); } private static string FormatMeters(float value) { return value.ToString("0.#", CultureInfo.InvariantCulture) + "m"; } private static string FormatDefaultPlacementLine(Vector3 horizontalOffset, float heightOffset, float yaw, float xAxisRotation, float zAxisRotation) { //IL_0010: 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) string text = "X " + Format(horizontalOffset.x) + " | Y " + Format(heightOffset) + " | Z " + Format(horizontalOffset.z) + " | θ " + FormatDegree(yaw); if (Mathf.Abs(xAxisRotation) >= 0.001f) { text = text + " | RX " + FormatDegree(xAxisRotation); } if (Mathf.Abs(zAxisRotation) >= 0.001f) { text = text + " | RZ " + FormatDegree(zAxisRotation); } return text; } private void PruneExpiredLines() { float unscaledTime = Time.unscaledTime; if (!string.IsNullOrEmpty(_areaLine) && unscaledTime > _areaHideAfter) { _areaLine = ""; } if (!string.IsNullOrEmpty(_placementLine) && unscaledTime > _placementHideAfter) { _placementLine = ""; } if (!string.IsNullOrEmpty(_dvergrLine) && unscaledTime > _dvergrHideAfter) { _dvergrLine = ""; } if (!string.IsNullOrEmpty(_buildCameraLine) && unscaledTime > _buildCameraHideAfter) { _buildCameraLine = ""; } if (!string.IsNullOrEmpty(_pickupLine) && unscaledTime > _pickupHideAfter) { _pickupLine = ""; } } private static bool HasNonZeroPlacementValue(Vector3 horizontalOffset, float heightOffset, float degree) { //IL_0000: 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) if (!(Mathf.Abs(horizontalOffset.x) > 0.001f) && !(Mathf.Abs(heightOffset) > 0.001f) && !(Mathf.Abs(horizontalOffset.z) > 0.001f)) { return Mathf.Abs(degree) > 0.001f; } return true; } private static string FormatAreaSize(string size) { string text = (size ?? "").Trim(); if (text.EndsWith("m", StringComparison.OrdinalIgnoreCase)) { string[] array = text.Substring(0, text.Length - 1).Split(new char[1] { 'x' }); if (array.Length == 2 && !string.IsNullOrWhiteSpace(array[0]) && !string.IsNullOrWhiteSpace(array[1])) { return array[0].Trim() + "m | " + array[1].Trim() + "m"; } } return text; } } internal sealed class ZoneAreaTargetOverlay { private readonly struct OverlayCandidate { public ZDO Zdo { get; } public float BoundaryPriority { get; } public OverlayCandidate(ZDO zdo, float boundaryPriority) { Zdo = zdo; BoundaryPriority = boundaryPriority; } } private const int MaxHighlightedTargets = 1600; private const int MaxCandidateInspections = 2500; public const float BoundaryCandidatePadding = 24f; private static readonly Color IncludedBoundaryColor = new Color(1f, 0.9f, 0.12f, 1f); private static readonly Color ExcludedBoundaryColor = new Color(1f, 0.45f, 0.05f, 1f); private readonly Dictionary _highlighted = new Dictionary(); private readonly Dictionary _nextHighlighted = new Dictionary(); private readonly List _candidateBuffer = new List(); public ZoneAreaTargetOverlay(Transform parent, string objectPrefix) { } public void Draw(IReadOnlyList candidates, ZoneAreaSelection selection) { //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) //IL_0049: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) _nextHighlighted.Clear(); _candidateBuffer.Clear(); float num = selection.HalfDiagonal + 24f; float num2 = num * num; for (int i = 0; i < candidates.Count; i++) { ZDO val = candidates[i]; if (val != null && val.IsValid()) { Vector3 position = val.GetPosition(); if (!(HorizontalDistanceSqr(position, selection.Center) > num2) && TryEstimateBoundaryPriority(position, selection, out var boundaryPriority)) { _candidateBuffer.Add(new OverlayCandidate(val, boundaryPriority)); } } } _candidateBuffer.Sort((OverlayCandidate left, OverlayCandidate right) => left.BoundaryPriority.CompareTo(right.BoundaryPriority)); int num3 = 0; int num4 = 0; foreach (OverlayCandidate item in _candidateBuffer) { if (num3 >= 1600 || num4 >= 2500) { break; } num4++; ZDO zdo = item.Zdo; if (TryClassifyBoundary(zdo, selection, out var included) && TryGetWearNTear(zdo, out WearNTear wearNTear)) { _nextHighlighted[zdo.m_uid] = included; if (!_highlighted.TryGetValue(zdo.m_uid, out var value) || value != included) { ApplyTint(wearNTear, included ? IncludedBoundaryColor : ExcludedBoundaryColor); } num3++; } } _candidateBuffer.Clear(); foreach (KeyValuePair item2 in _highlighted) { if (!_nextHighlighted.ContainsKey(item2.Key)) { ResetTint(item2.Key); } } _highlighted.Clear(); foreach (KeyValuePair item3 in _nextHighlighted) { _highlighted[item3.Key] = item3.Value; } } public void Clear() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) foreach (ZDOID key in _highlighted.Keys) { ResetTint(key); } _highlighted.Clear(); _nextHighlighted.Clear(); _candidateBuffer.Clear(); } public void Destroy() { Clear(); } private static bool TryGetWearNTear(ZDO zdo, out WearNTear wearNTear) { wearNTear = null; if (zdo == null || !zdo.IsValid() || (Object)(object)ZNetScene.instance == (Object)null) { return false; } ZNetView val = ZNetScene.instance.FindInstance(zdo); if ((Object)(object)val == (Object)null) { return false; } wearNTear = ((Component)val).GetComponent(); return (Object)(object)wearNTear != (Object)null; } public static void CollectNearbyZdos(ZoneAreaSelection selection, List buffer) { //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) buffer.Clear(); if (ZDOMan.instance != null) { float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_zoneSize : 64f); int num2 = Mathf.CeilToInt((selection.HalfDiagonal + 24f) / Mathf.Max(1f, num)); ZDOMan.instance.FindSectorObjects(ZoneSystem.GetZone(selection.Center), num2, 0, buffer, (List)null); } } private static bool TryClassifyBoundary(ZDO zdo, ZoneAreaSelection selection, out bool included) { //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_0024: 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_003c: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_007a: Unknown result type (might be due to invalid IL or missing references) included = false; if (zdo == null || !zdo.IsValid() || !ZoneBlueprintCommands.TryReadWearNTear(zdo, out GameObject prefab)) { return false; } Vector3 position = zdo.GetPosition(); included = selection.Contains(position); float num = selection.HalfDiagonal + 24f; if (HorizontalDistanceSqr(position, selection.Center) > num * num) { return false; } Vector3 vec = zdo.GetVec3(ZDOVars.s_scaleHash, prefab.transform.localScale); if (!HomesteadTerrainSupport.TryGetWearNTearBounds(prefab, position, zdo.GetRotation(), vec, out var bounds)) { return false; } return selection.IntersectsBoundary(bounds); } private static void ApplyTint(WearNTear wearNTear, Color color) { //IL_0026: 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) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MaterialMan.instance == (Object)null) { wearNTear.Highlight(); return; } GameObject gameObject = ((Component)wearNTear).gameObject; MaterialMan.instance.SetValue(gameObject, ShaderProps._Color, color); MaterialMan.instance.SetValue(gameObject, ShaderProps._EmissionColor, color * 0.35f); } private static void ResetTint(WearNTear wearNTear) { if ((Object)(object)MaterialMan.instance == (Object)null) { wearNTear.ResetHighlight(); return; } GameObject gameObject = ((Component)wearNTear).gameObject; MaterialMan.instance.ResetValue(gameObject, ShaderProps._Color); MaterialMan.instance.ResetValue(gameObject, ShaderProps._EmissionColor); } private static void ResetTint(ZDOID id) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(id) : null); WearNTear val2 = (((Object)(object)val != (Object)null) ? val.GetComponent() : null); if ((Object)(object)val2 != (Object)null) { ResetTint(val2); } } private static float HorizontalDistanceSqr(Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = a.x - b.x; float num2 = a.z - b.z; return num * num + num2 * num2; } private static bool TryEstimateBoundaryPriority(Vector3 position, ZoneAreaSelection selection, out float boundaryPriority) { //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_000c: 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_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_003a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Quaternion.Inverse(selection.Rotation) * (position - selection.Center); float num = selection.Width * 0.5f; float num2 = selection.Depth * 0.5f; float num3 = Mathf.Abs(val.x); float num4 = Mathf.Abs(val.z); float num5 = Mathf.Abs(num3 - num); float num6 = Mathf.Abs(num4 - num2); float num7 = Mathf.Max(num3 - num, 0f); float num8 = Mathf.Max(num4 - num2, 0f); float num9 = Mathf.Min(num - num3, num2 - num4); boundaryPriority = Mathf.Min(num5, num6); if (num7 <= 24f && num8 <= 24f) { return num9 <= 24f; } return false; } } [HarmonyPatch] internal static class ZoneBuildKeyHints { private sealed class HintWidgets { public TextMeshProUGUI? Label; public LayoutElement? Layout; public Transform? Key0Root; public Transform? Key1Root; public TextMeshProUGUI? Key0Text; public TextMeshProUGUI? Key1Text; public bool LastVisible; public string LastLabel = ""; public string LastKey0 = ""; public string LastKey1 = ""; public float LastPreferredWidth; } private const string TemplatePath = "BuildHints/Keyboard/AltPlace"; private const string FallbackTemplatePath = "BuildHints/Keyboard/Snap"; private const float BuildCameraConditionRefreshInterval = 0.35f; private static GameObject? _offsetHint; private static GameObject? _gridHint; private static GameObject? _toolHint; private static GameObject? _buildCameraHint; private static readonly Dictionary HintWidgetCache = new Dictionary(); private static Player? _cachedBuildCameraConditionPlayer; private static float _nextBuildCameraConditionRefresh; private static string _cachedBuildCameraCondition = ""; [HarmonyPostfix] [HarmonyPatch(typeof(KeyHints), "Awake")] private static void KeyHintsAwakePostfix(KeyHints __instance) { EnsureHints(__instance); UpdateHints(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(KeyHints), "UpdateHints")] private static void KeyHintsUpdateHintsPostfix(KeyHints __instance) { UpdateHints(__instance); } private static void EnsureHints(KeyHints keyHints) { if (Object.op_Implicit((Object)(object)keyHints) && !Object.op_Implicit((Object)(object)_offsetHint)) { Transform val = ((Component)keyHints).transform.Find("BuildHints/Keyboard/AltPlace") ?? ((Component)keyHints).transform.Find("BuildHints/Keyboard/Snap"); if ((Object)(object)val == (Object)null) { HomesteadPlugin.HomesteadLogger.LogDebug((object)"Homestead key hints: build hint template was not found."); return; } Transform parent = val.parent; _offsetHint = CreateHint(val, parent, "HomesteadOffsetHint", 0); _gridHint = CreateHint(val, parent, "HomesteadGridHint", 1); _toolHint = CreateHint(val, parent, "HomesteadToolHint", 2); _buildCameraHint = CreateHint(val, parent, "HomesteadBuildCameraHint", 3); HintWidgetCache.Clear(); } } private static GameObject CreateHint(Transform template, Transform parent, string name, int siblingIndex) { GameObject obj = Object.Instantiate(((Component)template).gameObject, parent); ((Object)obj).name = name; obj.transform.SetSiblingIndex(Mathf.Clamp(siblingIndex, 0, parent.childCount - 1)); EnsureKeyCount(obj, 2); return obj; } private static void UpdateHints(KeyHints keyHints) { //IL_00e5: 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_00ee: 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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_025e: 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_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Invalid comparison between Unknown and I4 //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) EnsureHints(keyHints); if ((Object)(object)_offsetHint == (Object)null || (Object)(object)_gridHint == (Object)null || (Object)(object)_toolHint == (Object)null || (Object)(object)_buildCameraHint == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; bool flag = keyHints.m_keyHintsEnabled && (Object)(object)localPlayer != (Object)null && ((Character)localPlayer).InPlaceMode() && !ZInput.IsGamepadActive(); if (ZoneBlueprintSaveToolMenu.IsStoreToolSelected(localPlayer)) { HideHomesteadHints(); return; } bool flag2 = ZoneBlueprintSaveTool.IsActive || ZoneAreaDismantleTool.IsActive || ZoneBlueprintPlacementTool.IsActive; string text = ""; if (flag && (Object)(object)localPlayer != (Object)null && ZoneBuildCamera.IsEnabled()) { text = GetCachedBuildCameraConditionText(localPlayer); } GetPlacementAdjustHintKeys(out string key, out string key2, out float preferredWidth); SetHint(_offsetHint, flag && (PlacementControlConfig.PlacementAdjustEnabled || flag2), HomesteadLocalization.Text("hs_keyhint_adjust_offset"), key, key2, preferredWidth); GameObject? gridHint = _gridHint; KeyboardShortcut val; int visible; if (flag) { val = PlacementControlConfig.GridSnapToggleHotkey; if ((int)((KeyboardShortcut)(ref val)).MainKey != 0) { visible = ((!flag2) ? 1 : 0); goto IL_00fc; } } visible = 0; goto IL_00fc; IL_00fc: SetHint(gridHint, (byte)visible != 0, ZoneGridSnap.IsActive ? HomesteadLocalization.Text("hs_keyhint_grid_on") : HomesteadLocalization.Text("hs_keyhint_grid_off"), FormatShortcut(PlacementControlConfig.GridSnapToggleHotkey), "", 102f); if (ZoneBlueprintSaveTool.IsActive || ZoneAreaDismantleTool.IsActive) { string text2 = (string.IsNullOrWhiteSpace(PlacementControlConfig.AreaUniformScaleInputLabel) ? "" : ("+" + PlacementControlConfig.PlacementAdjustModifierLabel)); val = BlueprintConfig.AreaToolDepthModifierKey; string text3 = (((int)((KeyboardShortcut)(ref val)).MainKey == 0) ? "" : ("+" + BlueprintConfig.AreaToolDepthModifierLabel)); val = BlueprintConfig.AreaToolWidthModifierKey; string text4 = (((int)((KeyboardShortcut)(ref val)).MainKey == 0) ? "" : ("+" + BlueprintConfig.AreaToolWidthModifierLabel)); string key3 = string.Join("/", new string[3] { text2, text3, text4 }.Where((string value) => !string.IsNullOrWhiteSpace(value))); SetHint(_toolHint, flag, HomesteadLocalization.Text("hs_keyhint_area_shape"), "Wheel", key3, 166f); } else if (ZoneBlueprintPlacementTool.IsActive) { SetHint(_toolHint, flag, HomesteadLocalization.Text("hs_keyhint_blueprint_place"), "Wheel", "Mouse0", 128f); } else { _toolHint.SetActive(false); } int num; if (ZoneBuildCamera.InBuildMode()) { val = BuildCameraConfig.LookAtLockHotkey; num = (((int)((KeyboardShortcut)(ref val)).MainKey > 0) ? 1 : 0); } else { num = 0; } bool flag3 = (byte)num != 0; SetHint(_buildCameraHint, flag && ZoneBuildCamera.IsEnabled(), flag3 ? HomesteadLocalization.Text("hs_keyhint_build_camera_lock") : HomesteadLocalization.Format("hs_keyhint_build_camera", text), FormatShortcut(BuildCameraConfig.ToggleHotkey), flag3 ? FormatShortcut(BuildCameraConfig.LookAtLockHotkey) : "", flag3 ? 190f : 160f); } private static void HideHomesteadHints() { SetActiveIfChanged(_offsetHint, active: false); SetActiveIfChanged(_gridHint, active: false); SetActiveIfChanged(_toolHint, active: false); SetActiveIfChanged(_buildCameraHint, active: false); } private static void SetHint(GameObject hint, bool visible, string label, string key0, string key1, float preferredTextWidth) { HintWidgets hintWidgets = GetHintWidgets(hint); SetActiveIfChanged(hint, visible); hintWidgets.LastVisible = visible; if (visible) { SetText(hintWidgets, label, preferredTextWidth); SetKeyText(hintWidgets.Key0Root, hintWidgets.Key0Text, key0, ref hintWidgets.LastKey0); SetKeyText(hintWidgets.Key1Root, hintWidgets.Key1Text, key1, ref hintWidgets.LastKey1); } } private static void SetText(HintWidgets widgets, string text, float preferredWidth) { TextMeshProUGUI label = widgets.Label; if ((Object)(object)label != (Object)null && !string.Equals(widgets.LastLabel, text, StringComparison.Ordinal)) { Localization instance = Localization.instance; if (instance != null) { instance.RemoveTextFromCache((TMP_Text)(object)label); } ((TMP_Text)label).text = text; widgets.LastLabel = text; } LayoutElement layout = widgets.Layout; if ((Object)(object)layout != (Object)null && Math.Abs(widgets.LastPreferredWidth - preferredWidth) > 0.1f) { layout.preferredWidth = preferredWidth; widgets.LastPreferredWidth = preferredWidth; } } private static void SetKeyText(Transform? keyRoot, TextMeshProUGUI? label, string text, ref string lastText) { if ((Object)(object)keyRoot == (Object)null) { return; } SetActiveIfChanged(((Component)keyRoot).gameObject, !string.IsNullOrWhiteSpace(text)); if ((Object)(object)label != (Object)null && !string.Equals(lastText, text, StringComparison.Ordinal)) { Localization instance = Localization.instance; if (instance != null) { instance.RemoveTextFromCache((TMP_Text)(object)label); } ((TMP_Text)label).text = text; lastText = text; } } private static HintWidgets GetHintWidgets(GameObject hint) { int instanceID = ((Object)hint).GetInstanceID(); if (HintWidgetCache.TryGetValue(instanceID, out HintWidgets value)) { return value; } TextMeshProUGUI val = FindLabelText(hint); Transform keyRoot = GetKeyRoot(hint, 0); Transform keyRoot2 = GetKeyRoot(hint, 1); LayoutElement val2 = default(LayoutElement); value = new HintWidgets { Label = val, Layout = (((Object)(object)val != (Object)null && ((Component)val).TryGetComponent(ref val2)) ? val2 : null), Key0Root = keyRoot, Key1Root = keyRoot2, Key0Text = (((Object)(object)keyRoot != (Object)null) ? FindKeyText(keyRoot) : null), Key1Text = (((Object)(object)keyRoot2 != (Object)null) ? FindKeyText(keyRoot2) : null), LastVisible = hint.activeSelf, LastPreferredWidth = float.NaN }; HintWidgetCache[instanceID] = value; return value; } private static void SetActiveIfChanged(GameObject? target, bool active) { if ((Object)(object)target != (Object)null && Object.op_Implicit((Object)(object)target) && target.activeSelf != active) { target.SetActive(active); } } private static string GetCachedBuildCameraConditionText(Player player) { if ((Object)(object)_cachedBuildCameraConditionPlayer != (Object)(object)player || Time.unscaledTime >= _nextBuildCameraConditionRefresh) { _cachedBuildCameraConditionPlayer = player; _cachedBuildCameraCondition = ZoneBuildCamera.GetKeyHintConditionText(player); _nextBuildCameraConditionRefresh = Time.unscaledTime + 0.35f; } return _cachedBuildCameraCondition; } private static Transform? GetKeyRoot(GameObject hint, int index) { List list = FindKeyRoots(hint); if (index < 0 || index >= list.Count) { return null; } return list[index]; } private static void EnsureKeyCount(GameObject hint, int count) { Transform keyRoot = GetKeyRoot(hint, 0); if ((Object)(object)keyRoot == (Object)null) { return; } for (int i = 1; i < count; i++) { if (!((Object)(object)GetKeyRoot(hint, i) != (Object)null)) { ((Object)Object.Instantiate(((Component)keyRoot).gameObject, keyRoot.parent).transform).name = $"key_bkg ({i})"; } } } private static TextMeshProUGUI? FindLabelText(GameObject hint) { TextMeshProUGUI[] componentsInChildren = hint.GetComponentsInChildren(true); return ((IEnumerable)componentsInChildren).FirstOrDefault((Func)((TextMeshProUGUI text) => !IsKeyText(((TMP_Text)text).transform))) ?? componentsInChildren.OrderByDescending((TextMeshProUGUI text) => ((TMP_Text)text).fontSize).FirstOrDefault(); } private static TextMeshProUGUI? FindKeyText(Transform keyRoot) { return ((IEnumerable)((Component)keyRoot).GetComponentsInChildren(true)).FirstOrDefault((Func)((TextMeshProUGUI text) => IsKeyText(((TMP_Text)text).transform))) ?? ((Component)keyRoot).GetComponentInChildren(true); } private static List FindKeyRoots(GameObject hint) { GameObject hint2 = hint; List list = (from transform in hint2.GetComponentsInChildren(true) where (Object)(object)transform != (Object)(object)hint2.transform && IsKeyRoot(transform) orderby transform.GetSiblingIndex() select transform).ToList(); if (list.Count > 0) { return list; } return (from transform in (from text in hint2.GetComponentsInChildren(true) where IsKeyText(((TMP_Text)text).transform) select ((TMP_Text)text).transform.parent ?? ((TMP_Text)text).transform).Distinct() orderby transform.GetSiblingIndex() select transform).ToList(); } private static bool IsKeyRoot(Transform transform) { string name = ((Object)transform).name; if (name.IndexOf("key_bkg", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("keybkg", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("key background", StringComparison.OrdinalIgnoreCase) < 0) { return name.Equals("key_bkg", StringComparison.OrdinalIgnoreCase); } return true; } private static bool IsKeyText(Transform transform) { if (((Object)transform).name.Equals("Key", StringComparison.OrdinalIgnoreCase)) { return true; } Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { if (IsKeyRoot(parent)) { return true; } parent = parent.parent; } return false; } private static string FormatShortcut(KeyboardShortcut shortcut) { string text = ((object)(KeyboardShortcut)(ref shortcut)).ToString(); if (string.IsNullOrWhiteSpace(text)) { return HomesteadLocalization.Text("hs_common_unbound"); } return text.Replace(" + ", "+"); } private static void GetPlacementAdjustHintKeys(out string key0, out string key1, out float preferredWidth) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) KeyboardShortcut placementAdjustModifierKey = PlacementControlConfig.PlacementAdjustModifierKey; if ((int)((KeyboardShortcut)(ref placementAdjustModifierKey)).MainKey == 0) { key0 = "Arrows"; key1 = "PgUp/PgDn"; preferredWidth = 104f; } else { key0 = PlacementControlConfig.PlacementAdjustModifierLabel; key1 = "+Arrows/+PgUpDn"; preferredWidth = 128f; } } } internal static class ZoneBuildCamera { internal struct EyeOriginOverrideState { public bool Changed; public Vector3 OriginalEyePosition; } private struct BuildCameraView { public float Yaw; public float Pitch; } private struct NearbyCraftingStation { public Vector3 Position; public float Distance; public float RangeBuild; } private const string ExternalBuildCameraGuid = "Azumatt.BuildCameraCHE"; private static readonly Dictionary InBuildModeByPlayer = new Dictionary(); private static readonly Dictionary OriginalMaxPlaceDistanceByPlayer = new Dictionary(); private static readonly Collider[] PickupOverlapBuffer = (Collider[])(object)new Collider[128]; private static ManualLogSource Log = null; private static BuildCameraView _viewDirection; private static bool _externalBuildCameraWarningLogged; private static float _nextMessageTime; private static Transform? _lookAtTarget; private static Vector3 _lookAtTargetOffset = Vector3.zero; internal static void Initialize(ManualLogSource logger) { Log = logger; } internal static void Shutdown() { DisableBuildMode(); RestoreAllMaxPlaceDistances(); InBuildModeByPlayer.Clear(); ZoneBuildCameraDvergerLight.CleanupAll(); } internal static void Update() { UpdateMaxPlaceDistanceOverride(); } internal static bool IsEnabled() { if (!BuildCameraConfig.Enabled) { return false; } if (!Chainloader.PluginInfos.ContainsKey("Azumatt.BuildCameraCHE")) { return true; } if (!_externalBuildCameraWarningLogged) { _externalBuildCameraWarningLogged = true; Log.LogWarning((object)"Standalone BuildCameraCHE is loaded. Homestead built-in build camera is disabled to avoid duplicate camera patches."); } return false; } internal static bool IsLocalPlayer(Player player) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return (Object)(object)player == (Object)(object)Player.m_localPlayer; } return false; } internal static bool InBuildMode() { Player localPlayer = Player.m_localPlayer; bool value = default(bool); return IsEnabled() && Object.op_Implicit((Object)(object)localPlayer) && InBuildModeByPlayer.TryGetValue(localPlayer, out value) && value; } internal static bool EnableBuildMode() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!IsEnabled() || !Object.op_Implicit((Object)(object)localPlayer)) { return false; } if (ShouldRestrictCameraEntry() && !MeetsComfortGate()) { NotifyNeedCozyForCurrentMode(); return false; } InBuildModeByPlayer[localPlayer] = true; SetViewDirectionFromRotation(((Component)((Character)localPlayer).m_eye).transform.rotation); ResetCameraSessionState(); ApplyMaxPlaceDistanceOverride(localPlayer); ((Character)localPlayer).Message((MessageType)1, HomesteadLocalization.Text("hs_build_camera_enter"), 0, (Sprite)null); return true; } internal static void DisableBuildMode() { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { InBuildModeByPlayer[localPlayer] = false; } RestoreAllMaxPlaceDistances(); ResetCameraSessionState(); ZoneAreaToolStatusHud.HideBuildCameraDistance(); } internal static bool ToolIsEquipped(Player player) { ItemData rightItem = ((Humanoid)player).m_rightItem; if (rightItem != null && rightItem.m_shared != null) { return Object.op_Implicit((Object)(object)rightItem.m_shared.m_buildPieces); } return false; } internal static bool ShouldDeactivateBuildMode(Player player) { if (ToolIsEquipped(player)) { if (ShouldRestrictCameraEntry()) { return !MeetsComfortGate(); } return false; } return true; } internal static void ApplyMaxPlaceDistanceOverride(Player player) { if (Object.op_Implicit((Object)(object)player) && InBuildModeByPlayer.TryGetValue(player, out var value) && value) { if (!OriginalMaxPlaceDistanceByPlayer.ContainsKey(player)) { OriginalMaxPlaceDistanceByPlayer[player] = player.m_maxPlaceDistance; } player.m_maxPlaceDistance = GetMaxPlaceDistance(player); } } internal static bool BuildStationInRange(Player player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) NearbyCraftingStation? nearestBuildStation = GetNearestBuildStation(GetBuildInteractionOrigin(player)); if (nearestBuildStation.HasValue) { return nearestBuildStation.Value.Distance <= nearestBuildStation.Value.RangeBuild; } return false; } internal static Vector3 GetBuildInteractionOrigin(Player player) { //IL_0019: 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) if (!InBuildMode() || !Object.op_Implicit((Object)(object)GameCamera.instance)) { return ((Component)player).transform.position; } return ((Component)GameCamera.instance).transform.position; } internal static bool TryGetBuildCameraOrigin(out Vector3 origin) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0023: Unknown result type (might be due to invalid IL or missing references) if (InBuildMode() && Object.op_Implicit((Object)(object)GameCamera.instance)) { origin = ((Component)GameCamera.instance).transform.position; return true; } origin = Vector3.zero; return false; } internal static EyeOriginOverrideState BeginEyeOriginOverride(Player player) { //IL_0040: 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_0051: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)((Character)player).m_eye) || !TryGetBuildCameraOrigin(out var origin)) { return default(EyeOriginOverrideState); } EyeOriginOverrideState eyeOriginOverrideState = default(EyeOriginOverrideState); eyeOriginOverrideState.Changed = true; eyeOriginOverrideState.OriginalEyePosition = ((Character)player).m_eye.position; EyeOriginOverrideState result = eyeOriginOverrideState; ((Character)player).m_eye.position = origin; return result; } internal static void EndEyeOriginOverride(Player player, EyeOriginOverrideState state) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (state.Changed && Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)((Character)player).m_eye)) { ((Character)player).m_eye.position = state.OriginalEyePosition; } } internal static string GetKeyHintConditionText(Player player) { if (!IsEnabled() || !Object.op_Implicit((Object)(object)player)) { return ""; } if (InBuildMode()) { return HomesteadLocalization.Text("hs_build_camera_active"); } if (!ToolIsEquipped(player)) { return HomesteadLocalization.Text("hs_build_camera_need_tool"); } if (!BuildStationInRange(player)) { return HomesteadLocalization.Text("hs_build_camera_need_station"); } if (ShouldRestrictCameraEntry()) { string text = FormatComfortProgress(); if (!MeetsComfortGate()) { return HomesteadLocalization.Format("hs_build_camera_need_cozy", text); } return HomesteadLocalization.Format("hs_build_camera_station_cozy", text); } return HomesteadLocalization.Text("hs_build_camera_station_ready"); } internal static void UpdateBuildCamera(float dt, GameCamera camera) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //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_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) //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_006d: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || IsInputBlocked(blockPieceSelection: true)) { return; } UpdateLookAtLock(camera); if (((Character)localPlayer).TakeInput()) { Vector3 untransformedMovementVelocity = GetUntransformedMovementVelocity(dt); Vector3 val = ((Component)camera).transform.TransformVector(untransformedMovementVelocity); Transform transform = ((Component)camera).transform; transform.position += val * dt; StayNearAvatar(localPlayer, camera); StayAboveGround(camera); ShowDistanceHud(localPlayer, camera); Quaternion val2 = UpdateBuildCameraViewDirection(dt); if (TryGetLookAtRotation(camera, out var rotation)) { val2 = rotation; SetViewDirectionFromRotation(val2); } ((Component)camera).transform.rotation = val2; } } internal static bool IsInputBlocked(bool blockPieceSelection) { if ((!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !HomesteadInputBlockers.IsTextInputVisible() && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible() && (!Object.op_Implicit((Object)(object)TextViewer.instance) || !TextViewer.instance.IsVisible()) && !Minimap.IsOpen() && !Hud.InRadial() && (!blockPieceSelection || !Hud.IsPieceSelectionVisible()) && !PlayerCustomizaton.BarberBlocksLook() && !PlayerCustomizaton.IsBarberGuiVisible() && !UnifiedPopup.IsVisible()) { return ZNet.IsPasswordDialogShowing(); } return true; } private static void ResetCameraSessionState() { ClearLookAtLock(); } private static void UpdateMaxPlaceDistanceOverride() { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { if (InBuildMode()) { ApplyMaxPlaceDistanceOverride(localPlayer); } else { RestoreMaxPlaceDistance(localPlayer); } } } private static void RestoreMaxPlaceDistance(Player player) { if (Object.op_Implicit((Object)(object)player) && OriginalMaxPlaceDistanceByPlayer.TryGetValue(player, out var value)) { player.m_maxPlaceDistance = value; OriginalMaxPlaceDistanceByPlayer.Remove(player); } } private static void RestoreAllMaxPlaceDistances() { KeyValuePair[] array = OriginalMaxPlaceDistanceByPlayer.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair keyValuePair = array[i]; if (Object.op_Implicit((Object)(object)keyValuePair.Key)) { keyValuePair.Key.m_maxPlaceDistance = keyValuePair.Value; } } OriginalMaxPlaceDistanceByPlayer.Clear(); } private static void UpdateLookAtLock(GameCamera camera) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!ConfigValueHelpers.IsShortcutDown(BuildCameraConfig.LookAtLockHotkey)) { return; } if (Object.op_Implicit((Object)(object)_lookAtTarget)) { ClearLookAtLock(); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, HomesteadLocalization.Text("hs_build_camera_lock_off"), 0, (Sprite)null); } return; } int mask = LayerMask.GetMask(new string[8] { "Default", "static_solid", "terrain", "vehicle", "character", "piece", "character_net", "viewblock" }); RaycastHit val = default(RaycastHit); if (Physics.Raycast(((Component)camera).transform.position, ((Component)camera).transform.forward, ref val, 10000f, mask) && Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider)) { _lookAtTarget = ((Component)((RaycastHit)(ref val)).collider).transform; _lookAtTargetOffset = _lookAtTarget.InverseTransformPoint(((RaycastHit)(ref val)).point); Player localPlayer2 = Player.m_localPlayer; if (localPlayer2 != null) { ((Character)localPlayer2).Message((MessageType)1, HomesteadLocalization.Text("hs_build_camera_lock_on"), 0, (Sprite)null); } } } private static void ClearLookAtLock() { //IL_0006: 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) _lookAtTarget = null; _lookAtTargetOffset = Vector3.zero; } private static bool TryGetLookAtRotation(GameCamera camera, out Quaternion rotation) { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_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_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) //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) rotation = ((Component)camera).transform.rotation; if (!Object.op_Implicit((Object)(object)_lookAtTarget)) { ClearLookAtLock(); return false; } Vector3 val = _lookAtTarget.TransformPoint(_lookAtTargetOffset) - ((Component)camera).transform.position; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return false; } rotation = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); return true; } internal static void AutoPickup(float dt, GameCamera camera) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0042: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsTeleporting() || !Player.m_enableAutoPickup || (ShouldRestrictCameraEntry() && !MeetsComfortGate())) { return; } Vector3 val = ((Component)camera).transform.position + Vector3.up; float resourcePickupRange = GetResourcePickupRange(localPlayer); int num = Physics.OverlapSphereNonAlloc(val, resourcePickupRange, PickupOverlapBuffer, localPlayer.m_autoPickupMask); Collider[] array = PickupOverlapBuffer; if (num >= PickupOverlapBuffer.Length) { array = Physics.OverlapSphere(val, resourcePickupRange, localPlayer.m_autoPickupMask); num = array.Length; } for (int i = 0; i < num; i++) { Collider val2 = array[i]; if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.attachedRigidbody)) { continue; } FloatingTerrainDummy val3 = null; ItemDrop component = ((Component)val2.attachedRigidbody).GetComponent(); if ((Object)(object)component == (Object)null) { FloatingTerrainDummy component2 = ((Component)val2.attachedRigidbody).gameObject.GetComponent(); if (component2 != null && Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component2.m_parent)) { val3 = component2; component = ((Component)component2.m_parent).gameObject.GetComponent(); } } if (!IsPickupCandidate(localPlayer, component)) { continue; } if (!component.CanPickup(true)) { component.RequestOwn(); continue; } component.Load(); float num2 = Vector3.Distance(((Component)component).transform.position, val); if (num2 > resourcePickupRange) { continue; } if (num2 < resourcePickupRange) { ((Humanoid)localPlayer).Pickup(((Component)component).gameObject, true, true); continue; } Vector3 val4 = Vector3.Normalize(val - ((Component)component).transform.position) * 15f * dt; Transform transform = ((Component)component).transform; transform.position += val4; if (Object.op_Implicit((Object)(object)val3)) { Transform transform2 = ((Component)val3).transform; transform2.position += val4; } } } private static NearbyCraftingStation? GetNearestBuildStation(Vector3 position) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) NearbyCraftingStation? result = null; foreach (CraftingStation allStation in CraftingStation.m_allStations) { if (Object.op_Implicit((Object)(object)allStation)) { float num = Vector3.Distance(((Component)allStation).transform.position, position); if (!result.HasValue || !(num >= result.Value.Distance)) { NearbyCraftingStation value = default(NearbyCraftingStation); value.Position = ((Component)allStation).transform.position; value.Distance = num; value.RangeBuild = allStation.m_rangeBuild; result = value; } } } return result; } private static void StayNearAvatar(Player player, GameCamera camera) { //IL_0006: 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_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_001f: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0042: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)player).transform.position; Vector3 position2 = ((Component)camera).transform.position; float maxDistanceFromAvatar = GetMaxDistanceFromAvatar(player); float num = Vector3.Distance(position2, position); if (!(num <= maxDistanceFromAvatar) && !(num <= 0.001f)) { Transform transform = ((Component)camera).transform; Vector3 val = position2 - position; transform.position = position + ((Vector3)(ref val)).normalized * maxDistanceFromAvatar; } } private static void ShowDistanceHud(Player player, GameCamera camera) { //IL_0006: 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) ZoneAreaToolStatusHud.ShowBuildCameraDistance(Vector3.Distance(((Component)camera).transform.position, ((Component)player).transform.position), GetMaxDistanceFromAvatar(player), maxPlaceDistance: GetMaxPlaceDistance(player), resourcePickupRange: GetResourcePickupRange(player), detail: GetDistanceDetail(player), placeDetail: GetMaxPlaceDistanceDetail(player), pickupDetail: GetResourcePickupRangeDetail(player)); } private static float GetMaxDistanceFromAvatar(Player player) { int distanceComfortLevel = GetDistanceComfortLevel(player); return BuildCameraConfig.BaseDistanceFromAvatar + (float)distanceComfortLevel * BuildCameraConfig.DistancePerComfortLevel; } private static string GetDistanceDetail(Player player) { int distanceComfortLevel = GetDistanceComfortLevel(player); return FormatDistanceNumber(BuildCameraConfig.BaseDistanceFromAvatar) + "+" + $"{FormatDistanceNumber(BuildCameraConfig.DistancePerComfortLevel)}*{distanceComfortLevel}({GetComfortLabel()})"; } private static float GetMaxPlaceDistance(Player player) { int distanceComfortLevel = GetDistanceComfortLevel(player); return BuildCameraConfig.MaxPlaceDistance + (float)distanceComfortLevel * BuildCameraConfig.MaxPlaceDistancePerComfortLevel; } private static string GetMaxPlaceDistanceDetail(Player player) { int distanceComfortLevel = GetDistanceComfortLevel(player); return FormatDistanceNumber(BuildCameraConfig.MaxPlaceDistance) + "+" + $"{FormatDistanceNumber(BuildCameraConfig.MaxPlaceDistancePerComfortLevel)}*{distanceComfortLevel}({GetComfortLabel()})"; } private static float GetResourcePickupRange(Player player) { int distanceComfortLevel = GetDistanceComfortLevel(player); return BuildCameraConfig.ResourcePickupRange + (float)distanceComfortLevel * BuildCameraConfig.ResourcePickupRangePerComfortLevel; } private static string GetResourcePickupRangeDetail(Player player) { int distanceComfortLevel = GetDistanceComfortLevel(player); return FormatDistanceNumber(BuildCameraConfig.ResourcePickupRange) + "+" + $"{FormatDistanceNumber(BuildCameraConfig.ResourcePickupRangePerComfortLevel)}*{distanceComfortLevel}({GetComfortLabel()})"; } private static int GetDistanceComfortLevel(Player player) { if (!Object.op_Implicit((Object)(object)player) || !IsComfortActive(player)) { return 0; } return Mathf.Max(0, player.GetComfortLevel()); } private static string FormatDistanceNumber(float value) { return value.ToString("0.##", CultureInfo.InvariantCulture); } private static void StayAboveGround(GameCamera camera) { //IL_0017: 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_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_0053: Unknown result type (might be due to invalid IL or missing references) float num = default(float); if (Object.op_Implicit((Object)(object)ZoneSystem.instance) && ZoneSystem.instance.GetGroundHeight(((Component)camera).transform.position, ref num) && ((Component)camera).transform.position.y < num) { Vector3 position = ((Component)camera).transform.position; position.y = num; ((Component)camera).transform.position = position; } } private static Quaternion UpdateBuildCameraViewDirection(float dt) { //IL_009c: 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_00ba: Unknown result type (might be due to invalid IL or missing references) _viewDirection.Yaw += PlayerController.m_mouseSens * Input.GetAxis("Mouse X") + ZInput.GetJoyRightStickX(true) * 110f * dt; float num = (PlayerController.m_invertMouse ? (-1f) : 1f); float num2 = _viewDirection.Pitch - (num * (PlayerController.m_mouseSens * Input.GetAxis("Mouse Y")) - ZInput.GetJoyRightStickY(true) * 110f * dt); _viewDirection.Pitch = Mathf.Clamp(num2, -89f, 89f); return Quaternion.Euler(0f, _viewDirection.Yaw, 0f) * Quaternion.Euler(_viewDirection.Pitch, 0f, 0f); } private static void SetViewDirectionFromRotation(Quaternion rotation) { //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_000d: 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) Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles; _viewDirection.Yaw = eulerAngles.y; _viewDirection.Pitch = NormalizePitch(eulerAngles.x); } private static float NormalizePitch(float pitch) { if (pitch > 180f) { pitch -= 360f; } return Mathf.Clamp(pitch, -89f, 89f); } private static Vector3 GetUntransformedMovementVelocity(float dt) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_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_001d: 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_0030: 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_0042: 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_004d: 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) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_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_00dc: 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_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_00f2: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: 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) Vector3 val = Vector3.zero; if (ZInput.GetButton("Left")) { val -= Vector3.right; } if (ZInput.GetButton("Right")) { val += Vector3.right; } if (ZInput.GetButton("Forward")) { val += Vector3.forward; } if (ZInput.GetButton("Backward")) { val -= Vector3.forward; } Character.takeInputDelay = Mathf.Max(0f, Character.takeInputDelay - dt); if ((ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump")) && Character.takeInputDelay <= 0f && !Hud.IsPieceSelectionVisible()) { val += Vector3.up; } if (ZInput.GetButton("Crouch") || ZInput.GetButtonPressedTimer("JoyCrouch") > 0.33f) { val -= Vector3.up; } val += Vector3.right * ZInput.GetJoyLeftStickX(false); val += -Vector3.forward * ZInput.GetJoyLeftStickY(true); val += Vector3.up * ZInput.GetJoyRTrigger(); val -= Vector3.up * ZInput.GetJoyLTrigger(); if (((Vector3)(ref val)).sqrMagnitude > 1f) { ((Vector3)(ref val)).Normalize(); } Player localPlayer = Player.m_localPlayer; float num = (ZInput.GetButton("Run") ? ((Character)localPlayer).m_runSpeed : ((Character)localPlayer).m_walkSpeed); return val * (num * BuildCameraConfig.MoveSpeedMultiplier); } private static bool ShouldRestrictCameraEntry() { return BuildCameraConfig.MinimumComfortLevel > 0; } private static bool MeetsComfortGate() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return false; } int minimumComfortLevel = BuildCameraConfig.MinimumComfortLevel; if (minimumComfortLevel <= 0) { return true; } if (localPlayer.GetComfortLevel() < minimumComfortLevel) { return false; } return IsComfortActive(localPlayer); } private static bool IsComfortActive(Player player) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan == null) { return false; } if (sEMan.HaveStatusEffect(SEMan.s_statusEffectResting)) { return true; } bool num = sEMan.HaveStatusEffect(SEMan.s_statusEffectCampFire); bool flag = player.InShelter() || ((Character)player).IsSitting(); bool flag2 = player.IsSensed(); bool flag3 = sEMan.HaveStatusEffect(SEMan.s_statusEffectCold) || sEMan.HaveStatusEffect(SEMan.s_statusEffectFreezing); bool flag4 = sEMan.HaveStatusEffect(SEMan.s_statusEffectBurning); bool flag5 = Object.op_Implicit((Object)(object)EffectArea.IsPointInsideArea(((Component)player).transform.position, (Type)64, 1f)); bool flag6 = sEMan.HaveStatusEffect(SEMan.s_statusEffectWet) && !flag5; if (num && flag && !flag2 && !flag3 && !flag6) { return !flag4; } return false; } private static bool IsPickupCandidate(Player player, ItemDrop? itemDrop) { if ((Object)(object)itemDrop == (Object)null || !itemDrop.m_autoPickup || itemDrop.InTar()) { return false; } ZNetView component = ((Component)itemDrop).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return false; } if (((Humanoid)player).HaveUniqueKey(itemDrop.m_itemData.m_shared.m_name)) { return false; } if (!itemDrop.CanPickup(true)) { return true; } itemDrop.Load(); if (((Humanoid)player).m_inventory.CanAddItem(itemDrop.m_itemData, -1)) { return itemDrop.m_itemData.GetWeight(-1) + ((Humanoid)player).m_inventory.GetTotalWeight() <= player.GetMaxCarryWeight(); } return false; } private static void NotifyNeedCozyForCurrentMode() { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && !(Time.time < _nextMessageTime)) { _nextMessageTime = Time.time + 1.5f; string text = HomesteadLocalization.Format("hs_build_camera_need_cozy_center", GetComfortLabel(), BuildCameraConfig.MinimumComfortLevel); ((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null); } } private static string GetComfortLabel() { return HomesteadLocalization.Text("hs_common_comfort"); } private static string FormatComfortProgress() { Player localPlayer = Player.m_localPlayer; int num = (Object.op_Implicit((Object)(object)localPlayer) ? localPlayer.GetComfortLevel() : 0); return $"C{num}/{BuildCameraConfig.MinimumComfortLevel}"; } } [HarmonyPatch(typeof(SE_Demister), "UpdateStatusEffect")] internal static class ZoneBuildCameraDemisterPatch { private struct ForceFieldData { public float EndRange; } private const float BuildCameraDemisterRangeMultiplier = 2.5f; private static readonly Dictionary OriginalForceFields = new Dictionary(); private static bool Prefix(SE_Demister __instance, float dt) { Character character = ((StatusEffect)__instance).m_character; Player val = (Player)(object)((character is Player) ? character : null); if ((Object)(object)val == (Object)null || !ZoneBuildCamera.IsLocalPlayer(val) || !ZoneBuildCamera.InBuildMode()) { RestoreNormalForceField(__instance); return true; } IncreaseForceFieldRange(__instance); UpdateDemisterForCamera(__instance, val, dt); return false; } internal static void CleanupBall(GameObject ball) { if (Object.op_Implicit((Object)(object)ball)) { OriginalForceFields.Remove(ball); } } private static void IncreaseForceFieldRange(SE_Demister instance) { if (Object.op_Implicit((Object)(object)instance.m_ballInstance) && !OriginalForceFields.ContainsKey(instance.m_ballInstance)) { ParticleSystemForceField componentInChildren = instance.m_ballInstance.GetComponentInChildren(); if (Object.op_Implicit((Object)(object)componentInChildren)) { OriginalForceFields[instance.m_ballInstance] = new ForceFieldData { EndRange = componentInChildren.endRange }; componentInChildren.endRange *= 2.5f; } } } private static void RestoreNormalForceField(SE_Demister instance) { if (Object.op_Implicit((Object)(object)instance.m_ballInstance) && OriginalForceFields.TryGetValue(instance.m_ballInstance, out var value)) { ParticleSystemForceField componentInChildren = instance.m_ballInstance.GetComponentInChildren(); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.endRange = value.EndRange; } OriginalForceFields.Remove(instance.m_ballInstance); } } private static void UpdateDemisterForCamera(SE_Demister instance, Player player, float dt) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0020: 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) //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_0064: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: 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) //IL_0200: 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_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_023d: 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_025e: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: 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_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) Vector3 cameraPosition = GetCameraPosition(); Vector3 cameraForward = GetCameraForward(); if (!Object.op_Implicit((Object)(object)instance.m_ballInstance)) { instance.m_ballInstance = Object.Instantiate(instance.m_ballPrefab, cameraPosition + cameraForward * 0.5f, Quaternion.identity); return; } bool num = IsUnderRoof(instance); Vector3 val = instance.m_ballInstance.transform.position; Vector3 val2 = (num ? instance.m_offsetInterior : instance.m_offset); float num2 = (num ? instance.m_noiseDistanceInterior : instance.m_noiseDistance); Vector3 val3 = GetCameraRight() * val2.x + GetCameraUp() * val2.y + cameraForward * val2.z; Vector3 val4 = cameraPosition + val3; float num3 = Time.time * instance.m_noiseSpeed; Vector3 val5 = new Vector3(Mathf.Sin(num3 * 4f), Mathf.Sin(num3 * 2f) * instance.m_noiseDistanceYScale, Mathf.Cos(num3 * 5f)) * num2; Vector3 val6 = val4 + val5; float num4 = Vector3.Distance(val6, val); Vector3 val7; if (num4 > instance.m_maxDistance * 2f) { val = val6; } else if (num4 > instance.m_maxDistance) { val7 = val - val6; Vector3 normalized = ((Vector3)(ref val7)).normalized; val = val6 + normalized * instance.m_maxDistance; } Vector3 ballVel = instance.m_ballVel; val7 = val6 - val; instance.m_ballVel = ballVel + ((Vector3)(ref val7)).normalized * instance.m_ballAcceleration * dt; if (((Vector3)(ref instance.m_ballVel)).magnitude > instance.m_ballMaxSpeed) { instance.m_ballVel = ((Vector3)(ref instance.m_ballVel)).normalized * instance.m_ballMaxSpeed; } if (!num) { instance.m_ballVel += ((Character)player).GetVelocity() * instance.m_characterVelocityFactor * dt; } instance.m_ballVel -= instance.m_ballVel * instance.m_ballFriction; instance.m_ballInstance.transform.position = val + instance.m_ballVel * dt; Transform transform = instance.m_ballInstance.transform; transform.rotation *= Quaternion.Euler(instance.m_rotationSpeed, 0f, instance.m_rotationSpeed * 0.5321f); } private static Vector3 GetCameraPosition() { //IL_001c: 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) if (!Object.op_Implicit((Object)(object)GameCamera.instance)) { return Vector3.zero; } return ((Component)GameCamera.instance).transform.position; } private static Vector3 GetCameraForward() { //IL_001c: 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) if (!Object.op_Implicit((Object)(object)GameCamera.instance)) { return Vector3.forward; } return ((Component)GameCamera.instance).transform.forward; } private static Vector3 GetCameraRight() { //IL_001c: 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) if (!Object.op_Implicit((Object)(object)GameCamera.instance)) { return Vector3.right; } return ((Component)GameCamera.instance).transform.right; } private static Vector3 GetCameraUp() { //IL_001c: 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) if (!Object.op_Implicit((Object)(object)GameCamera.instance)) { return Vector3.up; } return ((Component)GameCamera.instance).transform.up; } private static bool IsUnderRoof(SE_Demister instance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); return Physics.Raycast(GetCameraPosition(), Vector3.up, ref val, 4f, instance.m_coverRayMask); } } [HarmonyPatch(typeof(SE_Demister), "RemoveEffects")] internal static class ZoneBuildCameraDemisterCleanupPatch { private static void Prefix(SE_Demister __instance) { ZoneBuildCameraDemisterPatch.CleanupBall(__instance.m_ballInstance); } } internal static class ZoneBuildCameraDvergerLight { private sealed class ProxyLightState { public Light Source; public int SourceVisibleCullingMask; public Light ProxyLight; public GameObject ProxyObject; } private sealed class CircletExtendedApi { public MethodInfo? GetCircletMethod; public MethodInfo? GetCircletDataMethod; public FieldInfo? CircletItemInstanceField; public Type? VisEquipmentCircletType; public Func? GetCircletFast; public Func? GetCircletDataFast; public Func? GetCircletInstanceFast; } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] private static class GameCameraUpdatePatch { private static void Postfix(GameCamera __instance) { try { UpdateProxyLights(__instance); } catch (Exception ex) { if (Time.time >= _nextWarningLogTime) { _nextWarningLogTime = Time.time + 2f; HomesteadPlugin.HomesteadLogger.LogWarning((object)("Dvergr circlet build camera light failed: " + ex.Message)); } CleanupAll(); } } } [HarmonyPatch(typeof(Player), "SetLocalPlayer")] private static class PlayerSetLocalPlayerPatch { private static void Postfix() { CleanupAll(); } } private const string CircletExtendedGuid = "shudnal.CircletExtended"; private static readonly Dictionary ProxyBySourceId = new Dictionary(); private static readonly BindingFlags StaticMethodFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly BindingFlags InstanceFieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly List TempLights = new List(); private static readonly List TempVisualRoots = new List(); private static readonly HashSet TempSourceIdSet = new HashSet(); private static readonly List TempRemoveSourceIds = new List(); private static CircletExtendedApi? _circletExtendedApi; private static bool _circletExtendedApiInitialized; private static float _nextWarningLogTime; internal static void CleanupAll() { foreach (KeyValuePair item in ProxyBySourceId) { RestoreSourceAndDestroyProxy(item.Value.Source, item.Value); } ProxyBySourceId.Clear(); } private static void UpdateProxyLights(GameCamera camera) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)camera) || !ZoneBuildCamera.InBuildMode() || !IsAnySupportedCircletEquipped(localPlayer)) { CleanupAll(); return; } if (!TryGetHelmetLights(localPlayer, TempLights) || TempLights.Count == 0) { CleanupAll(); return; } Vector3 cameraOffset = default(Vector3); ((Vector3)(ref cameraOffset))..ctor(0f, BuildCameraConfig.HelmetLightOffsetUp, BuildCameraConfig.HelmetLightOffsetForward); RemoveStaleSources(TempLights); AddNewSources(TempLights, ((Component)camera).transform, cameraOffset); UpdateExistingProxies(((Component)camera).transform, cameraOffset); } private static bool IsAnySupportedCircletEquipped(Player player) { if (ZoneDvergrCirclet.TryGetEquippedDvergrCirclet(player, out ItemData _)) { return true; } return IsDvergrCircletItem(GetCircletExtendedEquippedCirclet(player)); } private static bool IsDvergrCircletItem(ItemData? item) { if (item == null) { return false; } string text = (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : string.Empty); if (text.Equals("HelmetDverger", StringComparison.OrdinalIgnoreCase) || text.StartsWith("HelmetDverger", StringComparison.OrdinalIgnoreCase)) { return true; } string text2 = item.m_shared?.m_name ?? string.Empty; if (text2.IndexOf("helmet_dverger", StringComparison.OrdinalIgnoreCase) < 0) { if (text2.IndexOf("dverger", StringComparison.OrdinalIgnoreCase) >= 0) { if (text2.IndexOf("helmet", StringComparison.OrdinalIgnoreCase) < 0) { return text2.IndexOf("circlet", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } return false; } return true; } private static ItemData? GetCircletExtendedEquippedCirclet(Player player) { CircletExtendedApi circletExtendedApi = GetCircletExtendedApi(); if (circletExtendedApi == null) { return null; } if (circletExtendedApi.GetCircletFast != null) { try { return circletExtendedApi.GetCircletFast((Humanoid)(object)player); } catch { } } if (circletExtendedApi.GetCircletMethod == null) { return null; } try { object? obj2 = circletExtendedApi.GetCircletMethod.Invoke(null, new object[1] { player }); return (ItemData?)((obj2 is ItemData) ? obj2 : null); } catch { return null; } } private static bool TryGetHelmetLights(Player player, List output) { output.Clear(); VisEquipment visEquipment = ((Humanoid)player).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment)) { return false; } if (Object.op_Implicit((Object)(object)visEquipment.m_helmetItemInstance)) { AppendLightsFromRoot(visEquipment.m_helmetItemInstance, output); } if (ZoneDvergrCirclet.TryGetEquippedDvergrCirclet(player, out ItemData item) && item != null && AzuExtendedPlayerInventoryCompat.TryGetCustomEquipVisualRoots(visEquipment, item, TempVisualRoots)) { foreach (GameObject tempVisualRoot in TempVisualRoots) { if (Object.op_Implicit((Object)(object)tempVisualRoot)) { AppendLightsFromRoot(tempVisualRoot, output); } } } ZoneDvergrCirclet.TryAppendFallbackLight(output); if (TryGetCircletExtendedItemInstance(visEquipment, out GameObject circletItemInstance) && Object.op_Implicit((Object)(object)circletItemInstance)) { AppendLightsFromRoot(circletItemInstance, output); } return output.Count > 0; } private static void AppendLightsFromRoot(GameObject root, List output) { root.GetComponentsInChildren(true, output); for (int num = output.Count - 1; num >= 0; num--) { if ((Object)(object)output[num] == (Object)null) { output.RemoveAt(num); } } } private static bool TryGetCircletExtendedItemInstance(VisEquipment visEquipment, out GameObject? circletItemInstance) { circletItemInstance = null; CircletExtendedApi circletExtendedApi = GetCircletExtendedApi(); if (circletExtendedApi == null || (circletExtendedApi.GetCircletDataFast == null && circletExtendedApi.GetCircletDataMethod == null) || (circletExtendedApi.GetCircletInstanceFast == null && circletExtendedApi.CircletItemInstanceField == null)) { return false; } try { object obj = ((circletExtendedApi.GetCircletDataFast != null) ? circletExtendedApi.GetCircletDataFast(visEquipment) : circletExtendedApi.GetCircletDataMethod?.Invoke(null, new object[1] { visEquipment })); if (obj == null) { return false; } GameObject val = (GameObject)((circletExtendedApi.GetCircletInstanceFast != null) ? ((object)circletExtendedApi.GetCircletInstanceFast(obj)) : ((object)/*isinst with value type is only supported in some contexts*/)); if (Object.op_Implicit((Object)(object)val)) { circletItemInstance = val; return true; } } catch { } return false; } private static void RemoveStaleSources(List currentSources) { TempSourceIdSet.Clear(); foreach (Light currentSource in currentSources) { if (Object.op_Implicit((Object)(object)currentSource)) { TempSourceIdSet.Add(((Object)currentSource).GetInstanceID()); } } TempRemoveSourceIds.Clear(); foreach (KeyValuePair item in ProxyBySourceId) { if (!Object.op_Implicit((Object)(object)item.Value.Source) || !TempSourceIdSet.Contains(item.Key)) { TempRemoveSourceIds.Add(item.Key); } } foreach (int tempRemoveSourceId in TempRemoveSourceIds) { RemoveProxyState(tempRemoveSourceId); } } private static void AddNewSources(List currentSources, Transform cameraTransform, Vector3 cameraOffset) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) foreach (Light currentSource in currentSources) { if (Object.op_Implicit((Object)(object)currentSource)) { int instanceID = ((Object)currentSource).GetInstanceID(); if (!ProxyBySourceId.ContainsKey(instanceID)) { ProxyBySourceId[instanceID] = CreateProxyState(currentSource, cameraTransform, cameraOffset); } } } } private static void UpdateExistingProxies(Transform cameraTransform, Vector3 cameraOffset) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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) TempRemoveSourceIds.Clear(); foreach (KeyValuePair item in ProxyBySourceId) { ProxyLightState value = item.Value; Light source = value.Source; if (!Object.op_Implicit((Object)(object)source) || (Object)(object)value.ProxyLight == (Object)null || (Object)(object)value.ProxyObject == (Object)null) { TempRemoveSourceIds.Add(item.Key); continue; } CopyLightState(source, value.ProxyLight); SuppressSourceLight(source, value); value.ProxyObject.transform.position = CalculateCameraFollowPosition(cameraTransform, cameraOffset); value.ProxyObject.transform.rotation = cameraTransform.rotation; value.ProxyObject.SetActive(((Component)source).gameObject.activeInHierarchy); } foreach (int tempRemoveSourceId in TempRemoveSourceIds) { RemoveProxyState(tempRemoveSourceId); } } private static ProxyLightState CreateProxyState(Light source, Transform cameraTransform, Vector3 cameraOffset) { //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_001e: Expected O, but got Unknown //IL_005f: 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_0076: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Homestead_DvergrBuildCameraLight_" + ((Object)source).name) { hideFlags = (HideFlags)61 }; Light val2 = val.AddComponent(); CopyLightState(source, val2); ProxyLightState proxyLightState = new ProxyLightState { Source = source, SourceVisibleCullingMask = source.cullingMask, ProxyLight = val2, ProxyObject = val }; proxyLightState.ProxyObject.transform.position = CalculateCameraFollowPosition(cameraTransform, cameraOffset); proxyLightState.ProxyObject.transform.rotation = cameraTransform.rotation; SuppressSourceLight(source, proxyLightState); return proxyLightState; } private static void RemoveProxyState(int sourceId) { if (ProxyBySourceId.TryGetValue(sourceId, out ProxyLightState value)) { RestoreSourceAndDestroyProxy(value.Source, value); ProxyBySourceId.Remove(sourceId); } } private static void RestoreSourceAndDestroyProxy(Light? source, ProxyLightState? state) { if ((Object)(object)source != (Object)null && state != null) { source.cullingMask = state.SourceVisibleCullingMask; } if ((Object)(object)state?.ProxyObject != (Object)null) { Object.Destroy((Object)(object)state.ProxyObject); } } private static void SuppressSourceLight(Light source, ProxyLightState state) { if (source.cullingMask != 0) { state.SourceVisibleCullingMask = source.cullingMask; source.cullingMask = 0; } } private static Vector3 CalculateCameraFollowPosition(Transform cameraTransform, Vector3 cameraOffset) { //IL_0001: 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_000c: 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_001d: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) return cameraTransform.position + cameraTransform.right * cameraOffset.x + cameraTransform.up * cameraOffset.y + cameraTransform.forward * cameraOffset.z; } private static void CopyLightState(Light src, Light dst) { //IL_0002: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) dst.type = src.type; dst.color = src.color; dst.colorTemperature = src.colorTemperature; dst.useColorTemperature = src.useColorTemperature; dst.intensity = src.intensity; dst.range = src.range; dst.spotAngle = src.spotAngle; dst.cookie = src.cookie; dst.cookieSize = src.cookieSize; dst.shadows = src.shadows; dst.shadowStrength = src.shadowStrength; dst.shadowResolution = src.shadowResolution; dst.renderMode = src.renderMode; dst.cullingMask = ((src.cullingMask != 0) ? src.cullingMask : dst.cullingMask); ((Behaviour)dst).enabled = ((Behaviour)src).enabled; } private static CircletExtendedApi? GetCircletExtendedApi() { if (_circletExtendedApiInitialized) { return _circletExtendedApi; } _circletExtendedApiInitialized = true; if (!Chainloader.PluginInfos.TryGetValue("shudnal.CircletExtended", out var value)) { return null; } Assembly obj = ((object)value.Instance)?.GetType().Assembly; Type type = obj?.GetType("CircletExtended.HumanoidExtension", throwOnError: false); Type type2 = obj?.GetType("CircletExtended.VisEquipmentExtension", throwOnError: false); Type type3 = obj?.GetType("CircletExtended.VisEquipmentCirclet", throwOnError: false); MethodInfo methodInfo = FindStaticMethod(type, "GetCirclet", typeof(Humanoid)); MethodInfo methodInfo2 = FindStaticMethod(type2, "GetCircletData", typeof(VisEquipment)); FieldInfo fieldInfo = type3?.GetField("m_circletItemInstance", InstanceFieldFlags); _circletExtendedApi = new CircletExtendedApi { GetCircletMethod = methodInfo, GetCircletDataMethod = methodInfo2, CircletItemInstanceField = fieldInfo, VisEquipmentCircletType = type3, GetCircletFast = CreateCircletExtendedGetCircletDelegate(methodInfo), GetCircletDataFast = CreateCircletExtendedGetCircletDataDelegate(methodInfo2), GetCircletInstanceFast = CreateCircletExtendedGetCircletInstanceDelegate(type3, fieldInfo) }; return _circletExtendedApi; } private static MethodInfo? FindStaticMethod(Type? type, string name, params Type[] parameterTypes) { if (type == null) { return null; } MethodInfo[] methods = type.GetMethods(StaticMethodFlags); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != name) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length != parameterTypes.Length) { continue; } bool flag = true; for (int j = 0; j < parameters.Length; j++) { if (parameters[j].ParameterType != parameterTypes[j]) { flag = false; break; } } if (flag) { return methodInfo; } } return null; } private static Func? CreateCircletExtendedGetCircletDelegate(MethodInfo? method) { if (method == null) { return null; } try { return (Func)Delegate.CreateDelegate(typeof(Func), method); } catch { return null; } } private static Func? CreateCircletExtendedGetCircletDataDelegate(MethodInfo? method) { if (method == null) { return null; } try { return (Func)Delegate.CreateDelegate(typeof(Func), method); } catch { return null; } } private static Func? CreateCircletExtendedGetCircletInstanceDelegate(Type? circletType, FieldInfo? itemInstanceField) { if (itemInstanceField == null || circletType == null) { return null; } try { ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "obj"); return Expression.Lambda>(Expression.Convert(Expression.Field(Expression.Convert(parameterExpression, circletType), itemInstanceField), typeof(GameObject)), new ParameterExpression[1] { parameterExpression }).Compile(); } catch { return null; } } } [HarmonyPatch(typeof(Player), "SetLocalPlayer")] internal static class ZoneBuildCameraPlayerSetLocalPlayerPatch { private static void Postfix() { ZoneBuildCamera.DisableBuildMode(); HomesteadFeatureBootstrap.OnLocalPlayerSet(); } } [HarmonyPatch(typeof(CraftingStation), "HaveBuildStationInRange")] internal static class ZoneBuildCameraCraftingStationHaveBuildStationInRangePatch { private static void Prefix(ref Vector3 point) { //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) if (ZoneBuildCamera.TryGetBuildCameraOrigin(out var origin)) { point = origin; } } } [HarmonyPatch(typeof(Player), "PieceRayTest")] internal static class ZoneBuildCameraPlayerPieceRayTestPatch { private static void Prefix(Player __instance, ref ZoneBuildCamera.EyeOriginOverrideState __state) { __state = ZoneBuildCamera.BeginEyeOriginOverride(__instance); } private static void Postfix(Player __instance, ZoneBuildCamera.EyeOriginOverrideState __state) { ZoneBuildCamera.EndEyeOriginOverride(__instance, __state); } } [HarmonyPatch(typeof(Player), "UpdateWearNTearHover")] internal static class ZoneBuildCameraPlayerUpdateWearNTearHoverPatch { private static void Prefix(Player __instance, ref ZoneBuildCamera.EyeOriginOverrideState __state) { __state = ZoneBuildCamera.BeginEyeOriginOverride(__instance); } private static void Postfix(Player __instance, ZoneBuildCamera.EyeOriginOverrideState __state) { ZoneBuildCamera.EndEyeOriginOverride(__instance, __state); } } [HarmonyPatch(typeof(Player), "CopyPiece")] internal static class ZoneBuildCameraPlayerCopyPiecePatch { private static void Prefix(Player __instance, ref ZoneBuildCamera.EyeOriginOverrideState __state) { __state = ZoneBuildCamera.BeginEyeOriginOverride(__instance); } private static void Postfix(Player __instance, ZoneBuildCamera.EyeOriginOverrideState __state) { ZoneBuildCamera.EndEyeOriginOverride(__instance, __state); } } [HarmonyPatch(typeof(Player), "RemovePiece")] internal static class ZoneBuildCameraPlayerRemovePiecePatch { private static void Prefix(Player __instance, ref ZoneBuildCamera.EyeOriginOverrideState __state) { __state = ZoneBuildCamera.BeginEyeOriginOverride(__instance); } private static void Postfix(Player __instance, ZoneBuildCamera.EyeOriginOverrideState __state) { ZoneBuildCamera.EndEyeOriginOverride(__instance, __state); } } [HarmonyPatch(typeof(Player), "Update")] internal static class ZoneBuildCameraPlayerUpdatePatch { private static void Prefix(Player __instance, ref bool __runOriginal) { if (!ZoneBuildCamera.IsLocalPlayer(__instance) || !ZoneBuildCamera.InBuildMode()) { return; } if (ZoneBuildCamera.ShouldDeactivateBuildMode(__instance)) { ZoneBuildCamera.DisableBuildMode(); return; } __runOriginal = false; ZoneBuildCamera.ApplyMaxPlaceDistanceOverride(__instance); if (!ZoneBuildCamera.IsInputBlocked(blockPieceSelection: false) && ((Character)__instance).TakeInput()) { UpdateHotbarAndHideInputs(__instance); __instance.UpdatePlacement(true, Time.deltaTime); } } private static void Postfix(Player __instance) { //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) if (!ZoneBuildCamera.IsLocalPlayer(__instance) || !ZoneBuildCamera.IsEnabled()) { return; } KeyboardShortcut toggleHotkey = BuildCameraConfig.ToggleHotkey; if (((KeyboardShortcut)(ref toggleHotkey)).IsDown() && !ZoneBuildCamera.IsInputBlocked(blockPieceSelection: true) && ((Character)__instance).TakeInput()) { if (ZoneBuildCamera.InBuildMode()) { ZoneBuildCamera.DisableBuildMode(); } else if (ZoneBuildCamera.ToolIsEquipped(__instance) && ZoneBuildCamera.BuildStationInRange(__instance)) { ZoneBuildCamera.EnableBuildMode(); } } } private static void UpdateHotbarAndHideInputs(Player player) { if (Input.GetKeyDown((KeyCode)49) || ZInput.GetButtonDown("Hotbar1")) { player.UseHotbarItem(1); } if (Input.GetKeyDown((KeyCode)50) || ZInput.GetButtonDown("Hotbar2")) { player.UseHotbarItem(2); } if (Input.GetKeyDown((KeyCode)51) || ZInput.GetButtonDown("Hotbar3")) { player.UseHotbarItem(3); } if (Input.GetKeyDown((KeyCode)52) || ZInput.GetButtonDown("Hotbar4")) { player.UseHotbarItem(4); } if (Input.GetKeyDown((KeyCode)53) || ZInput.GetButtonDown("Hotbar5")) { player.UseHotbarItem(5); } if (Input.GetKeyDown((KeyCode)54) || ZInput.GetButtonDown("Hotbar6")) { player.UseHotbarItem(6); } if (Input.GetKeyDown((KeyCode)55) || ZInput.GetButtonDown("Hotbar7")) { player.UseHotbarItem(7); } if (Input.GetKeyDown((KeyCode)56) || ZInput.GetButtonDown("Hotbar8")) { player.UseHotbarItem(8); } if ((ZInput.GetButtonDown("Hide") || ZInput.GetButtonDown("JoyHide")) && (((Humanoid)player).GetRightItem() != null || ((Humanoid)player).GetLeftItem() != null) && !((Character)player).InAttack()) { ((Humanoid)player).HideHandItems(false, true); } } } [HarmonyPatch(typeof(PlayerController), "TakeInput")] internal static class ZoneBuildCameraPlayerControllerTakeInputPatch { private static void Prefix(ref bool __result, ref bool __runOriginal) { if (ZoneBuildCamera.InBuildMode()) { __result = false; __runOriginal = false; } } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] [HarmonyBefore(new string[] { "Azumatt.FirstPersonMode" })] [HarmonyPriority(700)] internal static class ZoneBuildCameraGameCameraUpdatePatch { private static void Prefix(float dt, GameCamera __instance, ref bool __runOriginal) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (ZoneBuildCamera.InBuildMode()) { ZoneBuildCamera.UpdateBuildCamera(dt, __instance); if (ZoneBuildCameraWardCompat.CheckAccess(((Component)__instance).transform.position, flash: false)) { ZoneBuildCamera.AutoPickup(dt, __instance); } __runOriginal = false; } } } internal static class ZoneBuildCameraWardCompat { private const string WardIsLoveGuid = "Azumatt.WardIsLove"; private static readonly System.Version WardIsLoveMinimumVersion = new System.Version(2, 3, 3); private static MethodInfo? _checkAccessMethod; private static bool _checkedWardIsLove; internal static bool CheckAccess(Vector3 point, bool flash) { //IL_007a: 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) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return false; } if (IsWardIsLoveLoaded()) { try { object obj = _checkAccessMethod?.Invoke(null, new object[4] { localPlayer.GetPlayerID(), point, 0f, flash }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } return PrivateArea.CheckAccess(point, 0f, flash, true); } private static bool IsWardIsLoveLoaded() { if (_checkedWardIsLove) { return _checkAccessMethod != null; } _checkedWardIsLove = true; if (!Chainloader.PluginInfos.TryGetValue("Azumatt.WardIsLove", out var value) || value.Metadata.Version < WardIsLoveMinimumVersion) { return false; } _checkAccessMethod = ((((object)value.Instance)?.GetType().Assembly)?.GetType("WardIsLove.Util.CustomCheck", throwOnError: false))?.GetMethod("CheckAccess", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); return _checkAccessMethod != null; } } internal static class ZoneContentsWithinBlueprintChestPreview { private sealed class PreviewCache { public Inventory Inventory { get; } public string Signature { get; } public float LastUsedAt { get; set; } public PreviewCache(Inventory inventory, string signature, float lastUsedAt) { Inventory = inventory; Signature = signature; LastUsedAt = lastUsedAt; } } private const string ContentsWithinPatchTypeName = "ContentsWithin.ContentsWithin+InventoryGuiPatch"; private const int PreviewWidth = 8; private const int MaxPreviewRows = 8; private static readonly Color RequirementIconColor = new Color(1f, 1f, 1f, 0.45f); private static readonly Color RequirementAmountColor = new Color(0.86f, 0.86f, 0.86f, 0.75f); private static readonly Color RequirementBackgroundColor = new Color(0.18f, 0.18f, 0.18f, 0.55f); private static readonly Dictionary PreviewInventories = new Dictionary(StringComparer.Ordinal); private static Type? _contentsWithinPatchType; private static bool _contentsWithinTypeResolved; public static bool IsContentsWithinLoaded() { Type type; return TryGetContentsWithinPatchType(out type); } public static bool TryGetContentsWithinPatchType(out Type type) { if (_contentsWithinTypeResolved) { type = _contentsWithinPatchType; return type != null; } _contentsWithinTypeResolved = true; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type2 = assemblies[i].GetType("ContentsWithin.ContentsWithin+InventoryGuiPatch", throwOnError: false, ignoreCase: false); if (!(type2 == null)) { _contentsWithinPatchType = type2; type = type2; return true; } } type = null; return false; } public static void ResetForWorldSession() { PreviewInventories.Clear(); } public static bool TryHandleAccess(Container? container, ref bool result) { if (!Object.op_Implicit((Object)(object)container)) { return false; } if (IsBlockedPriceChest(container)) { result = false; return true; } if (CanShowVirtualRequirements(container)) { result = true; return true; } return false; } public static bool TryReplacePreviewInventory(Inventory? source, out Inventory preview) { preview = null; if (source == null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } GameObject hoverObject = ((Humanoid)Player.m_localPlayer).GetHoverObject(); Container val = (((Object)(object)hoverObject != (Object)null) ? hoverObject.GetComponentInParent() : null); if (!Object.op_Implicit((Object)(object)val) || val.GetInventory() != source) { return false; } return TryCreateVirtualRequirementInventory(val, out preview); } public static void GreyOutRequirementGrid(InventoryGrid? grid) { if ((Object)(object)grid == (Object)null || !IsVirtualRequirementInventory(grid.GetInventory())) { return; } Inventory inventory = grid.GetInventory(); int num = Mathf.Max(1, grid.m_width); int num2 = 0; foreach (Element element in grid.m_elements) { ItemData itemAt = inventory.GetItemAt(num2 % num, num2 / num); num2++; if (element.m_used) { ApplyRequirementSlotStyle(element, itemAt); } } } private static bool CanShowVirtualRequirements(Container container) { List requirements; string cacheKey; return TryGetMissingRequirements(container, out requirements, out cacheKey); } private static bool IsVirtualRequirementInventory(Inventory? inventory) { if (inventory == null) { return false; } foreach (PreviewCache value in PreviewInventories.Values) { if (value.Inventory == inventory) { return true; } } return false; } private static bool TryCreateVirtualRequirementInventory(Container container, out Inventory preview) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown preview = null; if (!TryGetMissingRequirements(container, out List requirements, out string cacheKey)) { return false; } string text = CreateRequirementSignature(requirements); if (PreviewInventories.TryGetValue(cacheKey, out PreviewCache value) && string.Equals(value.Signature, text, StringComparison.Ordinal)) { value.LastUsedAt = Time.realtimeSinceStartup; preview = value.Inventory; return true; } int num = Mathf.Clamp(Mathf.CeilToInt((float)Mathf.Max(1, requirements.Count) / 8f), 1, 8); Inventory val = new Inventory("HomesteadRequirementsPreview", container.m_bkg, 8, num); FillPreviewInventory(val, requirements); PreviewInventories[cacheKey] = new PreviewCache(val, text, Time.realtimeSinceStartup); PrunePreviewInventories(); preview = val; return true; } private static bool TryGetMissingRequirements(Container container, out List requirements, out string cacheKey) { requirements = new List(); cacheKey = ""; if (ZoneBlueprintPlanAnchor.TryGetAnchor(container, out ZoneBlueprintPlanAnchor anchor)) { requirements = anchor.GetMissingRequirementList(); cacheKey = CreateCacheKey(container, "plan"); return true; } ZoneBlueprintStoreChest component = ((Component)container).GetComponent(); if ((Object)(object)component != (Object)null && component.IsPurchaseChest()) { requirements = component.GetMissingPurchaseRequirementList(); cacheKey = CreateCacheKey(container, "purchase"); return true; } return false; } private static void FillPreviewInventory(Inventory inventory, IReadOnlyList requirements) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) int num = inventory.m_width * inventory.m_height; int num2 = Mathf.Min(requirements.Count, num); for (int i = 0; i < num2; i++) { ZoneBlueprintRequirement zoneBlueprintRequirement = requirements[i]; GameObject val = ZoneBlueprintStoreVisuals.FindItemPrefab(zoneBlueprintRequirement.PrefabName) ?? ZoneBlueprintStoreVisuals.FindItemPrefab(zoneBlueprintRequirement.ItemName); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent() : null); if (!((Object)(object)val2 == (Object)null)) { ItemData val3 = val2.m_itemData.Clone(); val3.m_stack = Mathf.Max(1, zoneBlueprintRequirement.Amount); val3.m_dropPrefab = val; val3.m_gridPos = new Vector2i(i % inventory.m_width, i / inventory.m_width); inventory.m_inventory.Add(val3); } } inventory.Changed(); } private static void ApplyRequirementSlotStyle(Element element, ItemData? item) { //IL_0061: 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_0047: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)element.m_icon != (Object)null) { Transform parent = ((Component)element.m_icon).transform.parent; if ((Object)(object)parent != (Object)null) { Image[] componentsInChildren = ((Component)parent).GetComponentsInChildren(true); foreach (Image val in componentsInChildren) { if (!((Object)(object)val == (Object)(object)element.m_icon)) { ((Graphic)val).color = RequirementBackgroundColor; } } } ((Graphic)element.m_icon).color = RequirementIconColor; } if ((Object)(object)element.m_amount != (Object)null) { if (item != null) { element.m_amount.text = item.m_stack.ToString(); } ((Graphic)element.m_amount).color = RequirementAmountColor; } if ((Object)(object)element.m_quality != (Object)null) { ((Behaviour)element.m_quality).enabled = false; } if ((Object)(object)element.m_equiped != (Object)null) { ((Behaviour)element.m_equiped).enabled = false; } if ((Object)(object)element.m_queued != (Object)null) { ((Behaviour)element.m_queued).enabled = false; } if ((Object)(object)element.m_noteleport != (Object)null) { ((Behaviour)element.m_noteleport).enabled = false; } if ((Object)(object)element.m_food != (Object)null) { ((Behaviour)element.m_food).enabled = false; } if ((Object)(object)element.m_durability != (Object)null) { ((Component)element.m_durability).gameObject.SetActive(false); } } private static bool IsBlockedPriceChest(Container container) { ZoneBlueprintStoreChest component = ((Component)container).GetComponent(); if ((Object)(object)component != (Object)null && (component.IsPriceChest() || component.IsPriceChestPrefab())) { return true; } ZNetView component2 = ((Component)container).GetComponent(); if ((Object)(object)component2 != (Object)null && component2.IsValid()) { return component2.GetZDO().GetPrefab() == ZoneBlueprintStoreChestPrefab.PricePrefabHash; } return false; } private static string CreateCacheKey(Container container, string kind) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)container).GetComponent(); if ((Object)(object)component != (Object)null && component.IsValid()) { return $"{kind}:{component.GetZDO().m_uid}"; } return $"{kind}:local:{((Object)container).GetInstanceID()}"; } private static string CreateRequirementSignature(IReadOnlyList requirements) { if (requirements.Count == 0) { return "empty"; } List list = new List(requirements.Count); foreach (ZoneBlueprintRequirement requirement in requirements) { list.Add($"{requirement.ItemName}|{requirement.PrefabName}|{requirement.Amount}"); } return string.Join(";", list); } private static void PrunePreviewInventories() { if (PreviewInventories.Count <= 64) { return; } float num = Time.realtimeSinceStartup - 60f; List list = new List(); foreach (KeyValuePair previewInventory in PreviewInventories) { if (previewInventory.Value.LastUsedAt < num) { list.Add(previewInventory.Key); } } foreach (string item in list) { PreviewInventories.Remove(item); } while (PreviewInventories.Count > 64) { string text = ""; float num2 = float.PositiveInfinity; foreach (KeyValuePair previewInventory2 in PreviewInventories) { if (!(previewInventory2.Value.LastUsedAt >= num2)) { num2 = previewInventory2.Value.LastUsedAt; text = previewInventory2.Key; } } if (!string.IsNullOrEmpty(text)) { PreviewInventories.Remove(text); continue; } break; } } } [HarmonyPatch] internal static class ZoneContentsWithinAccessCompat { private static bool Prepare() { return ZoneContentsWithinBlueprintChestPreview.IsContentsWithinLoaded(); } private static MethodBase? TargetMethod() { if (!ZoneContentsWithinBlueprintChestPreview.TryGetContentsWithinPatchType(out Type type)) { return null; } return AccessTools.Method(type, "HasContainerAccess", new Type[1] { typeof(Container) }, (Type[])null); } private static bool Prefix(Container container, ref bool __result) { return !ZoneContentsWithinBlueprintChestPreview.TryHandleAccess(container, ref __result); } } [HarmonyPatch] internal static class ZoneContentsWithinPreviewCompat { private static bool Prepare() { return ZoneContentsWithinBlueprintChestPreview.IsContentsWithinLoaded(); } private static MethodBase? TargetMethod() { if (!ZoneContentsWithinBlueprintChestPreview.TryGetContentsWithinPatchType(out Type type)) { return null; } return AccessTools.Method(type, "ShowPreviewContainer", new Type[1] { typeof(Inventory) }, (Type[])null); } private static void Prefix(ref Inventory container) { if (ZoneContentsWithinBlueprintChestPreview.TryReplacePreviewInventory(container, out Inventory preview)) { container = preview; } } } [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] internal static class ZoneContentsWithinRequirementGridCompat { private static void Postfix(InventoryGrid __instance) { ZoneContentsWithinBlueprintChestPreview.GreyOutRequirementGrid(__instance); } } internal static class ZoneBlueprintCommands { internal sealed class BlueprintLoadPlan { public List Entries { get; } public List Positions { get; } public List SupportContacts { get; } public BlueprintLoadPlan(List entries, List positions, List supportContacts) { Entries = entries; Positions = positions; SupportContacts = supportContacts; } } internal sealed class BlueprintLoadEntry { public ZoneBlueprintEntry Entry { get; } public GameObject Prefab { get; } public Vector3 Position { get; } public Quaternion Rotation { get; } public Vector3 Scale { get; } public BlueprintLoadEntry(ZoneBlueprintEntry entry, GameObject prefab, Vector3 position, Quaternion rotation, Vector3 scale) { //IL_0015: 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) //IL_001c: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Entry = entry; Prefab = prefab; Position = position; Rotation = rotation; Scale = scale; } } [CompilerGenerated] private sealed class <>c__DisplayClass19_0 { public BlueprintLoadPlan plan; public string planError; public bool terrainApplied; public int created; internal void b__0(BlueprintLoadPlan? value, string error) { plan = value; planError = error; } internal void b__1(bool result) { terrainApplied = result; } internal void b__2(int value) { created = value; } } [CompilerGenerated] private sealed class <>c__DisplayClass19_1 { public string accessReason; public List requirements; internal void b__3(string value) { accessReason = value; } internal void b__4(List value) { requirements = value; } } [CompilerGenerated] private sealed class d__52 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public IEnumerable entries; public Action> onComplete; private Dictionary 5__2; private int 5__3; private IEnumerator <>7__wrap3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__52(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__2 = null; <>7__wrap3 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = new Dictionary(); 5__3 = 0; <>7__wrap3 = entries.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap3.MoveNext()) { BlueprintLoadEntry current = <>7__wrap3.Current; AccumulateRequirements(5__2, current); 5__3++; if (5__3 >= 250) { 5__3 = 0; <>2__current = null; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap3 = null; onComplete(5__2.Values.OrderBy((ZoneBlueprintRequirement requirement) => requirement.ItemName, StringComparer.Ordinal).ToList()); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap3 != null) { <>7__wrap3.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__40 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZoneBlueprintFile blueprint; public Vector3 anchor; public Quaternion anchorRotation; public Action onComplete; private List 5__2; private List 5__3; private int 5__4; private List 5__5; private List.Enumerator <>7__wrap5; private List.Enumerator <>7__wrap6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__40(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 1: try { } finally { <>m__Finally1(); } break; case -4: case 2: try { } finally { <>m__Finally2(); } break; } 5__2 = null; 5__3 = null; 5__5 = null; <>7__wrap5 = default(List.Enumerator); <>7__wrap6 = default(List.Enumerator); <>1__state = -2; } private bool MoveNext() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018c: 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_00b9: Unknown result type (might be due to invalid IL or missing references) bool result; try { switch (<>1__state) { default: result = false; goto end_IL_0000; case 0: <>1__state = -1; 5__2 = new List(); 5__3 = new List(); 5__4 = 0; <>7__wrap5 = blueprint.Entries.GetEnumerator(); <>1__state = -3; goto IL_0106; case 1: <>1__state = -3; goto IL_0106; case 2: { <>1__state = -4; break; } IL_0106: while (true) { if (!<>7__wrap5.MoveNext()) { <>m__Finally1(); <>7__wrap5 = default(List.Enumerator); 5__5 = new List(blueprint.TerrainContacts.Count); <>7__wrap6 = blueprint.TerrainContacts.GetEnumerator(); <>1__state = -4; break; } ZoneBlueprintEntry current = <>7__wrap5.Current; if (!TryCreateLoadEntry(blueprint, current, anchor, anchorRotation, out BlueprintLoadEntry loadEntry, out string error)) { onComplete(null, error); result = false; <>m__Finally1(); } else { if (loadEntry != null) { 5__2.Add(loadEntry); 5__3.Add(loadEntry.Position); } 5__4++; if (5__4 < 250) { continue; } 5__4 = 0; <>2__current = null; <>1__state = 1; result = true; } goto end_IL_0000; } break; } while (true) { if (<>7__wrap6.MoveNext()) { ZoneBlueprintTerrainContact current2 = <>7__wrap6.Current; 5__5.Add(ToWorldTerrainContact(current2, anchor, anchorRotation)); 5__4++; if (5__4 >= 250) { 5__4 = 0; <>2__current = null; <>1__state = 2; result = true; break; } continue; } <>m__Finally2(); <>7__wrap6 = default(List.Enumerator); onComplete(new BlueprintLoadPlan(5__2, 5__3, 5__5), ""); result = false; break; } end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap5).Dispose(); } private void <>m__Finally2() { <>1__state = -1; ((IDisposable)<>7__wrap6).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__19 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string name; public Action onComplete; public Vector3 anchor; public Quaternion anchorRotation; private <>c__DisplayClass19_0 <>8__1; public Player player; private <>c__DisplayClass19_1 <>8__2; public Dictionary depositedMaterials; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>8__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0086: 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) switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass19_0(); ZoneBlueprintFile blueprint; try { blueprint = LoadPlanBlueprint(name); } catch (Exception ex) { onComplete(HomesteadCommandResult.Fail(ex.Message)); return false; } <>8__1.plan = null; <>8__1.planError = ""; <>2__current = CreateLoadPlanAsync(blueprint, anchor, anchorRotation, delegate(BlueprintLoadPlan? value, string error) { <>8__1.plan = value; <>8__1.planError = error; }); <>1__state = 1; return true; } case 1: { <>1__state = -1; if (<>8__1.plan == null) { onComplete(HomesteadCommandResult.Fail(string.IsNullOrWhiteSpace(<>8__1.planError) ? HomesteadLocalization.Format("hs_blueprint_load_failed_plain", name) : <>8__1.planError)); return false; } if (<>8__1.plan.Entries.Count == 0) { onComplete(HomesteadCommandResult.Fail(HomesteadLocalization.Format("hs_blueprint_no_valid_entries", name))); return false; } if (!ZoneLimitCompat.CanAddWearNTears(<>8__1.plan.Positions, out string reason)) { onComplete(HomesteadCommandResult.Fail(reason)); return false; } if (!player.NoCostCheat()) { <>8__2 = new <>c__DisplayClass19_1(); <>8__2.accessReason = ""; <>2__current = ValidateBuildAccessWithoutInventoryAsync(player, <>8__1.plan.Entries, delegate(string value) { <>8__2.accessReason = value; }); <>1__state = 2; return true; } goto IL_0318; } case 2: <>1__state = -1; if (!string.IsNullOrEmpty(<>8__2.accessReason)) { onComplete(HomesteadCommandResult.Fail(<>8__2.accessReason)); return false; } <>8__2.requirements = new List(); <>2__current = CollectRequirementsAsync(<>8__1.plan.Entries, delegate(List value) { <>8__2.requirements = value; }); <>1__state = 3; return true; case 3: <>1__state = -1; foreach (ZoneBlueprintRequirement requirement in <>8__2.requirements) { depositedMaterials.TryGetValue(requirement.ItemName, out var value2); if (value2 < requirement.Amount) { onComplete(HomesteadCommandResult.Fail(HomesteadLocalization.Format("hs_blueprint_missing_deposited", HomesteadLocalization.MaybeLocalize(requirement.DisplayName), value2, requirement.Amount))); return false; } } <>8__2 = null; goto IL_0318; case 4: <>1__state = -1; goto IL_0385; case 5: { <>1__state = -1; onComplete(HomesteadCommandResult.Ok(HomesteadLocalization.Format("hs_blueprint_confirmed", name, <>8__1.created, <>8__1.terrainApplied ? HomesteadLocalization.Text("hs_common_yes") : HomesteadLocalization.Text("hs_common_no")))); return false; } IL_0385: <>8__1.created = 0; <>2__current = SpawnPlanAsync(<>8__1.plan, player, delegate(int value) { <>8__1.created = value; }); <>1__state = 5; return true; IL_0318: <>8__1.terrainApplied = false; if (BlueprintConfig.ShouldApplyTerrainSupport(player) && <>8__1.plan.SupportContacts.Count > 0) { <>2__current = BlueprintTerrainApplier.ApplySupportContactsAsync(<>8__1.plan.SupportContacts, delegate(bool result) { <>8__1.terrainApplied = result; }); <>1__state = 4; return true; } goto IL_0385; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__47 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Player player; public BlueprintLoadPlan plan; public Action onComplete; private long 5__2; private string 5__3; private int 5__4; private int 5__5; private List.Enumerator <>7__wrap5; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__47(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__3 = null; <>7__wrap5 = default(List.Enumerator); <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = player.GetPlayerID(); 5__3 = player.GetPlayerName(); 5__4 = 0; 5__5 = 0; <>7__wrap5 = plan.Entries.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap5.MoveNext()) { BlueprintLoadEntry current = <>7__wrap5.Current; 5__4 += (TrySpawnPlanEntry(current, 5__2, 5__3) ? 1 : 0); 5__5++; if (5__5 >= 250) { 5__5 = 0; <>2__current = null; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap5 = default(List.Enumerator); onComplete(5__4); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap5).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__55 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public IEnumerable entries; public Player player; public Action onComplete; private int 5__2; private IEnumerator <>7__wrap2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__55(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) bool result; try { switch (<>1__state) { default: result = false; goto end_IL_0000; case 0: <>1__state = -1; 5__2 = 0; <>7__wrap2 = entries.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (true) { if (<>7__wrap2.MoveNext()) { BlueprintLoadEntry current = <>7__wrap2.Current; Piece component = current.Prefab.GetComponent(); if ((Object)(object)component != (Object)null) { if (!player.HaveRequirements(component, (RequirementMode)1)) { onComplete(HomesteadLocalization.Format("hs_blueprint_missing_known_station_or_materials", current.Entry.Prefab)); result = false; } else { if (!((Object)(object)component.m_craftingStation != (Object)null) || Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(component.m_craftingStation.m_name, ((Component)player).transform.position)) || ZoneSystem.instance.GetGlobalKey((GlobalKeys)22)) { goto IL_0117; } onComplete(HomesteadLocalization.Format("hs_blueprint_missing_crafting_station", current.Entry.Prefab)); result = false; } <>m__Finally1(); break; } goto IL_0117; } <>m__Finally1(); <>7__wrap2 = null; onComplete(""); result = false; break; IL_0117: 5__2++; if (5__2 >= 250) { 5__2 = 0; <>2__current = null; <>1__state = 1; result = true; break; } } end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap2 != null) { <>7__wrap2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const int BlueprintPlanBatchSize = 250; private const float PlanGhostCleanupStartupDelaySeconds = 600f; private const float PlanGhostCleanupRegistryRetrySeconds = 60f; private const float PlanGhostCleanupIntervalSeconds = 21600f; private const string BlueprintPieceMarkerKey = "sighsorry.Homestead.blueprint_piece"; private static readonly int BlueprintPlacedHash = StringExtensionMethods.GetStableHashCode("sighsorry.Homestead.blueprint_piece"); private static readonly Dictionary BuildRecipeCache = new Dictionary(StringComparer.Ordinal); private static readonly HashSet MissingPrefabWarnings = new HashSet(StringComparer.OrdinalIgnoreCase); private static ManualLogSource _logger = null; private static bool _initialized; private static int _buildRecipeCacheObjectDbCount = -1; private static float _nextPlanGhostCleanupAt; public static void Initialize(ManualLogSource logger) { if (!_initialized) { _initialized = true; _logger = logger; ResetForWorldSession(); ZoneBlueprintPlanRpc.Initialize(logger); } } public static void Update() { CleanupPlanGhostFilesIfDue(); } public static void ResetForWorldSession() { _nextPlanGhostCleanupAt = Time.realtimeSinceStartup + 600f; MissingPrefabWarnings.Clear(); } internal static HomesteadCommandResult SaveSelectedBlueprint(string name, Player player) { EnsureWorldReady(); name = (name ?? "").Trim(); if (string.IsNullOrWhiteSpace(name)) { return HomesteadCommandResult.Fail(HomesteadLocalization.Text("hs_blueprint_name_required")); } if (!ZoneBlueprintSaveTool.TryGetSelectedBlueprint(name, player, out ZoneBlueprintFile blueprint, out string reason)) { return HomesteadCommandResult.Fail(reason); } if (blueprint.Entries.Count == 0) { return HomesteadCommandResult.Fail(HomesteadLocalization.Text("hs_blueprint_no_selected_wearnttear")); } string text = SaveBlueprint(name, blueprint); return HomesteadCommandResult.Ok(HomesteadLocalization.Format("hs_blueprint_saved_to_path", name, blueprint.Entries.Count, blueprint.TerrainContacts.Count, text)); } internal static HomesteadCommandResult PlaceBlueprintPlanAt(string name, Player player, Vector3 anchor, Quaternion anchorRotation) { //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_0004: Unknown result type (might be due to invalid IL or missing references) return PlaceBlueprintPlanAt(name, player, anchor, anchorRotation, anchorRotation); } internal static HomesteadCommandResult PlaceBlueprintPlanAt(string name, Player player, Vector3 anchor, Quaternion anchorRotation, Quaternion chestRotation) { //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_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_0052: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) ZoneBlueprintFile blueprint = LoadBlueprint(name); Vector3 planChestPosition = GetPlanChestPosition(blueprint, anchor, anchorRotation, chestRotation); if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { ZoneBlueprintPlanRpc.RequestPlace(name, blueprint, anchor, anchorRotation, planChestPosition, chestRotation); return HomesteadCommandResult.Ok(HomesteadLocalization.Format("hs_blueprint_plan_request_sent", name)); } if (CreateLoadPlan(blueprint, anchor, anchorRotation).Entries.Count == 0) { return HomesteadCommandResult.Fail(HomesteadLocalization.Format("hs_blueprint_no_valid_entries", name)); } return ZoneBlueprintPlanChestPrefab.PlacePlanChest(name, player, anchor, anchorRotation, planChestPosition, chestRotation); } internal static HomesteadCommandResult FinalizeBlueprintPlan(string name, Player player, Vector3 anchor, Quaternion anchorRotation, IReadOnlyDictionary depositedMaterials) { //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) BlueprintLoadPlan blueprintLoadPlan = CreateLoadPlan(LoadBlueprint(name), anchor, anchorRotation); if (blueprintLoadPlan.Entries.Count == 0) { return HomesteadCommandResult.Fail(HomesteadLocalization.Format("hs_blueprint_no_valid_entries", name)); } if (!ZoneLimitCompat.CanAddWearNTears(blueprintLoadPlan.Positions, out string reason)) { return HomesteadCommandResult.Fail(reason); } if (!player.NoCostCheat()) { string text = ValidateBuildAccessWithoutInventory(player, blueprintLoadPlan.Entries); if (!string.IsNullOrEmpty(text)) { return HomesteadCommandResult.Fail(text); } foreach (ZoneBlueprintRequirement item in CollectRequirements(blueprintLoadPlan)) { depositedMaterials.TryGetValue(item.ItemName, out var value); if (value < item.Amount) { return HomesteadCommandResult.Fail(HomesteadLocalization.Format("hs_blueprint_missing_deposited", HomesteadLocalization.MaybeLocalize(item.DisplayName), value, item.Amount)); } } } bool flag = false; if (BlueprintConfig.ShouldApplyTerrainSupport(player) && blueprintLoadPlan.SupportContacts.Count > 0) { flag = BlueprintTerrainApplier.ApplySupportContacts(blueprintLoadPlan.SupportContacts); } int num = SpawnPlan(blueprintLoadPlan, player); return HomesteadCommandResult.Ok(HomesteadLocalization.Format("hs_blueprint_confirmed", name, num, flag ? HomesteadLocalization.Text("hs_common_yes") : HomesteadLocalization.Text("hs_common_no"))); } [IteratorStateMachine(typeof(d__19))] internal static IEnumerator FinalizeBlueprintPlanAsync(string name, Player player, Vector3 anchor, Quaternion anchorRotation, Dictionary depositedMaterials, Action onComplete) { //IL_0015: 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) //IL_001c: 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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0) { name = name, player = player, anchor = anchor, anchorRotation = anchorRotation, depositedMaterials = depositedMaterials, onComplete = onComplete }; } internal static List GetBlueprintNames() { string worldBlueprintDirectory = GetWorldBlueprintDirectory(); if (!Directory.Exists(worldBlueprintDirectory)) { return new List(); } return (from name in Directory.GetFiles(worldBlueprintDirectory, "*.blueprint").Select(Path.GetFileNameWithoutExtension) where !string.IsNullOrWhiteSpace(name) select (name)).OrderBy((string name) => name, StringComparer.OrdinalIgnoreCase).ToList(); } internal static bool TryLoadBlueprint(string name, out ZoneBlueprintFile blueprint) { try { blueprint = LoadBlueprint(name); return true; } catch { blueprint = null; return false; } } internal static string SerializeBlueprintForStore(string name) { return ZoneBlueprintFileFormat.Serialize(LoadBlueprint(name)); } internal static string SaveBlueprintFromStore(string preferredName, ZoneBlueprintFile blueprint) { string name = (blueprint.Name = GetUniqueBlueprintName(preferredName)); return SaveBlueprint(name, blueprint); } internal static List FindBlueprintWearNTearZdos(Player player, ZoneAreaSelection selection, BlueprintAreaSaveCreatorMode creatorMode) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) long playerID = player.GetPlayerID(); List list = new List(); List list2 = new List(); ZoneAreaTargetOverlay.CollectNearbyZdos(selection, list2); foreach (ZDO item in list2) { if (!IsHomesteadBlueprintChest(item) && TryReadSavableWearNTear(item, out GameObject _) && selection.Contains(item.GetPosition())) { long @long = item.GetLong(ZDOVars.s_creator, 0L); if (IsAreaSaveCreatorAllowed(playerID, @long, creatorMode)) { list.Add(item); } } } return list; } internal static bool IsAreaSaveCreatorAllowed(long playerId, long creator, BlueprintAreaSaveCreatorMode creatorMode) { if (creator == playerId) { return true; } return creatorMode switch { BlueprintAreaSaveCreatorMode.AllCreators => true, BlueprintAreaSaveCreatorMode.OwnedAndCreatorless => creator == 0, _ => false, }; } internal static bool IsHomesteadBlueprintChest(ZDO zdo) { if (zdo == null || !zdo.IsValid()) { return false; } int prefab = zdo.GetPrefab(); if (prefab != ZoneBlueprintPlanChestPrefab.PrefabHash) { return ZoneBlueprintStoreChestPrefab.IsStorePrefab(prefab); } return true; } internal static bool IsHomesteadBlueprintChestPrefab(GameObject? prefab) { if (!Object.op_Implicit((Object)(object)prefab)) { return false; } string prefabName = Utils.GetPrefabName(prefab); if (!string.Equals(prefabName, "piece_chest_wood_blueprint", StringComparison.OrdinalIgnoreCase)) { return ZoneBlueprintStoreChestPrefab.IsStorePrefabName(prefabName); } return true; } internal static ZoneBlueprintFile CaptureBlueprintFromZdos(string name, Player player, Vector3 anchor, Quaternion anchorRotation, IEnumerable sourceZdos, float radius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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_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_0047: 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_0052: 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_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_005c: 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_0062: 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_0069: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Quaternion.Inverse(anchorRotation); List list = new List(); List list2 = new List(); foreach (ZDO item in sourceZdos.ToList()) { if (TryReadSavableWearNTear(item, out GameObject prefab)) { Vector3 position = item.GetPosition(); Quaternion rotation = item.GetRotation(); Vector3 val2 = ReadScale(item, prefab); Vector3 value = val * (position - anchor); Quaternion value2 = val * rotation; list.Add(new ZoneBlueprintEntry { Prefab = Utils.GetPrefabName(prefab), LocalPos = ToArray(value), LocalRot = ToArray(value2), Scale = ToArray(val2), Text = ReadBlueprintText(item, prefab) }); list2.Add(new TerrainContactSource(prefab, position, rotation, val2)); } } return new ZoneBlueprintFile { Name = name, Creator = player.GetPlayerName(), World = GetWorldName(), SavedAt = HomesteadTimestamp.Now(), Radius = radius, Entries = list.OrderBy((ZoneBlueprintEntry entry) => entry.Prefab, StringComparer.Ordinal).ThenBy((ZoneBlueprintEntry entry) => entry.LocalPos[0]).ThenBy((ZoneBlueprintEntry entry) => entry.LocalPos[2]) .ThenBy((ZoneBlueprintEntry entry) => entry.LocalPos[1]) .ToList(), TerrainContacts = BlueprintTerrainApplier.CaptureContacts(anchor, val, list2) }; } internal static ZoneBlueprintFile LoadBlueprintForPlan(string name) { return LoadPlanBlueprint(name); } internal static BlueprintLoadPlan CreateLoadPlanForBlueprint(string name, Vector3 anchor, Quaternion anchorRotation) { //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 CreateLoadPlan(LoadPlanBlueprint(name), anchor, anchorRotation); } internal static BlueprintLoadPlan CreateLoadPlanForBlueprint(ZoneBlueprintFile blueprint, Vector3 anchor, Quaternion anchorRotation) { //IL_0001: 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) return CreateLoadPlan(blueprint, anchor, anchorRotation); } internal static HomesteadCommandResult SaveUploadedBlueprintForPlan(string preferredName, ZoneBlueprintFile blueprint, long playerId, out string savedName) { savedName = ""; string text = ValidateBlueprintFile(blueprint); if (!string.IsNullOrWhiteSpace(text)) { return HomesteadCommandResult.Fail(text); } string text2 = SanitizePathSegment(string.IsNullOrWhiteSpace(preferredName) ? blueprint.Name : preferredName); string planGhostBlueprintPath = GetPlanGhostBlueprintPath(text2); Directory.CreateDirectory(Path.GetDirectoryName(planGhostBlueprintPath)); blueprint.World = GetWorldName(); if (File.Exists(planGhostBlueprintPath)) { try { string a = ZoneBlueprintFileFormat.Serialize(ZoneBlueprintFileFormat.ReadFile(planGhostBlueprintPath)); string b = ZoneBlueprintFileFormat.Serialize(CloneForName(blueprint, text2)); if (string.Equals(a, b, StringComparison.Ordinal)) { savedName = text2; return HomesteadCommandResult.Ok(HomesteadLocalization.Format("hs_blueprint_server_already_has", savedName)); } } catch { } text2 = GetUniquePlanGhostBlueprintName($"{text2}_p{Math.Abs(playerId)}"); } blueprint.Name = text2; string planGhostBlueprintPath2 = GetPlanGhostBlueprintPath(text2); Directory.CreateDirectory(Path.GetDirectoryName(planGhostBlueprintPath2)); ZoneBlueprintFileFormat.WriteFile(planGhostBlueprintPath2, blueprint); savedName = text2; return HomesteadCommandResult.Ok(HomesteadLocalization.Format("hs_blueprint_uploaded_to_server", savedName)); } internal static string SerializePreviewBlueprintForPlan(string name) { if (!ZoneBlueprintNetworkPayload.TryCreatePreviewText(LoadPlanBlueprint(name), out string previewText, out string reason)) { throw new InvalidOperationException(reason); } return previewText; } internal static void EnsureLocalPlanBlueprintCopy(string name, string blueprintText) { if (!string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(blueprintText)) { ZoneBlueprintFile zoneBlueprintFile = ZoneBlueprintFileFormat.Deserialize(blueprintText, name); zoneBlueprintFile.Name = name; string planGhostBlueprintPath = GetPlanGhostBlueprintPath(name); Directory.CreateDirectory(Path.GetDirectoryName(planGhostBlueprintPath)); ZoneBlueprintFileFormat.WriteFile(planGhostBlueprintPath, zoneBlueprintFile); } } internal static List CollectRequirements(BlueprintLoadPlan plan) { return CollectRequirements(plan.Entries); } internal static List CollectCraftingStations(BlueprintLoadPlan plan) { Dictionary dictionary = new Dictionary(StringComparer.Ordinal); foreach (BlueprintLoadEntry entry in plan.Entries) { Piece component = entry.Prefab.GetComponent(); CraftingStation val = (((Object)(object)component != (Object)null) ? component.m_craftingStation : null); if (!((Object)(object)val == (Object)null)) { string name = val.m_name; if (!string.IsNullOrWhiteSpace(name) && !dictionary.ContainsKey(name)) { dictionary[name] = new ZoneBlueprintCraftingStationRequirement { StationName = name, PrefabName = Utils.GetPrefabName(((Component)val).gameObject), DisplayName = name }; } } } return dictionary.Values.OrderBy((ZoneBlueprintCraftingStationRequirement station) => station.StationName, StringComparer.Ordinal).ToList(); } internal static Vector3 GetPlanChestPosition(ZoneBlueprintFile blueprint, Vector3 anchor, Quaternion anchorRotation) { //IL_0001: 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_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) return GetPlanChestPosition(blueprint, anchor, anchorRotation, anchorRotation); } internal static Vector3 GetPlanChestPosition(ZoneBlueprintFile blueprint, Vector3 anchor, Quaternion anchorRotation, Quaternion chestRotation) { //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_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) //IL_0023: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0100: 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_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_0111: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (blueprint.Entries.Count == 0) { return anchor; } Quaternion inverseChestRotation = Quaternion.Inverse(chestRotation); List list = (from entry in blueprint.Entries.Where(IsLoadableBlueprintEntry) select inverseChestRotation * (anchorRotation * FromVector(entry.LocalPos))).ToList(); if (list.Count == 0) { return anchor; } float num = list.Min((Vector3 position) => position.x); float num2 = list.Max((Vector3 position) => position.x); float num3 = list.Min((Vector3 position) => position.z); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor((num + num2) * 0.5f, 0f, num3 - 2.5f); Vector3 val2 = anchor + chestRotation * val; val2.y = SampleGroundY(val2.x, val2.z, anchor.y); return val2; } private static BlueprintLoadPlan CreateLoadPlan(ZoneBlueprintFile blueprint, Vector3 anchor, Quaternion anchorRotation) { //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_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_003c: 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_0069: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List list2 = new List(); foreach (ZoneBlueprintEntry entry in blueprint.Entries) { if (!TryCreateLoadEntry(blueprint, entry, anchor, anchorRotation, out BlueprintLoadEntry loadEntry, out string error)) { throw new InvalidOperationException(error); } if (loadEntry != null) { list.Add(loadEntry); list2.Add(loadEntry.Position); } } List supportContacts = blueprint.TerrainContacts.Select((ZoneBlueprintTerrainContact contact) => ToWorldTerrainContact(contact, anchor, anchorRotation)).ToList(); return new BlueprintLoadPlan(list, list2, supportContacts); } [IteratorStateMachine(typeof(d__40))] private static IEnumerator CreateLoadPlanAsync(ZoneBlueprintFile blueprint, Vector3 anchor, Quaternion anchorRotation, Action onComplete) { //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_0015: 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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__40(0) { blueprint = blueprint, anchor = anchor, anchorRotation = anchorRotation, onComplete = onComplete }; } private static bool TryCreateLoadEntry(ZoneBlueprintFile blueprint, ZoneBlueprintEntry entry, Vector3 anchor, Quaternion anchorRotation, out BlueprintLoadEntry? loadEntry, out string error) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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) loadEntry = null; error = ""; GameObject prefab = ZNetScene.instance.GetPrefab(entry.Prefab); if (!Object.op_Implicit((Object)(object)prefab)) { LogMissingPrefabOnce(blueprint.Name, entry.Prefab); return true; } if ((Object)(object)prefab.GetComponent() == (Object)null || !HasBuildRecipe(prefab)) { return true; } if (entry.LocalPos.Length < 3 || entry.LocalRot.Length < 4 || entry.Scale.Length < 3) { error = "Blueprint '" + blueprint.Name + "' contains an invalid transform for '" + entry.Prefab + "'."; return false; } Vector3 position = anchor + anchorRotation * FromVector(entry.LocalPos); Quaternion rotation = anchorRotation * FromQuaternion(entry.LocalRot); Vector3 scale = FromVector(entry.Scale); loadEntry = new BlueprintLoadEntry(entry, prefab, position, rotation, scale); return true; } internal static bool IsLoadableBlueprintEntry(ZoneBlueprintEntry entry) { bool missingPrefab; return IsLoadableBlueprintEntry(entry, out missingPrefab); } internal static bool IsLoadableBlueprintEntry(ZoneBlueprintEntry entry, out bool missingPrefab) { missingPrefab = false; if (entry.LocalPos.Length < 3 || entry.LocalRot.Length < 4 || entry.Scale.Length < 3) { return false; } ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab(entry.Prefab) : null); if (!Object.op_Implicit((Object)(object)val)) { missingPrefab = true; return false; } if (Object.op_Implicit((Object)(object)val) && (Object)(object)val.GetComponent() != (Object)null) { return HasBuildRecipe(val); } return false; } private static void LogMissingPrefabOnce(string blueprintName, string prefabName) { string item = blueprintName + "\n" + prefabName; if (MissingPrefabWarnings.Add(item)) { _logger.LogWarning((object)("Skipping missing prefab '" + prefabName + "' while loading blueprint '" + blueprintName + "'.")); } } private static Vector3 ToWorldTerrainContact(ZoneBlueprintTerrainContact contact, Vector3 anchor, Quaternion anchorRotation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_001e: Unknown result type (might be due to invalid IL or missing references) return anchor + anchorRotation * new Vector3(contact.LocalX, contact.LocalY, contact.LocalZ); } private static int SpawnPlan(BlueprintLoadPlan plan, Player player) { long playerID = player.GetPlayerID(); string playerName = player.GetPlayerName(); int num = 0; foreach (BlueprintLoadEntry entry in plan.Entries) { num += (TrySpawnPlanEntry(entry, playerID, playerName) ? 1 : 0); } return num; } [IteratorStateMachine(typeof(d__47))] private static IEnumerator SpawnPlanAsync(BlueprintLoadPlan plan, Player player, Action onComplete) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__47(0) { plan = plan, player = player, onComplete = onComplete }; } private static bool TrySpawnPlanEntry(BlueprintLoadEntry item, long playerId, string playerName) { //IL_0007: 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_0013: Unknown result type (might be due to invalid IL or missing references) ZDO val = InitBlueprintZdo(item.Prefab, item.Position, item.Rotation, item.Scale); if (val == null) { return false; } ApplyBlueprintText(item, val); val.Set(ZDOVars.s_creator, playerId); val.Set(ZDOVars.s_creatorName, playerName); val.Set(BlueprintPlacedHash, true); ZNetScene.instance.CreateObject(val); return true; } private static ZDO? InitBlueprintZdo(GameObject prefab, Vector3 position, Quaternion rotation, Vector3 scale) { //IL_0022: 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_0072: 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) if (ZDOMan.instance == null || !Object.op_Implicit((Object)(object)prefab)) { return null; } int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name); ZDO val = ZDOMan.instance.CreateNewZDO(position, stableHashCode); val.SetPrefab(stableHashCode); val.SetRotation(rotation); ZNetView component = prefab.GetComponent(); if ((Object)(object)component != (Object)null) { val.Persistent = component.m_persistent; val.Distant = component.m_distant; val.Type = component.m_type; } val.Set(ZDOVars.s_scaleHash, scale); return val; } private static void ApplyBlueprintText(BlueprintLoadEntry item, ZDO zdo) { if (!string.IsNullOrEmpty(item.Entry.Text) && item.Prefab.GetComponent() != null) { zdo.Set(ZDOVars.s_text, item.Entry.Text); } } private static List CollectRequirements(IEnumerable entries) { Dictionary dictionary = new Dictionary(); foreach (BlueprintLoadEntry entry in entries) { AccumulateRequirements(dictionary, entry); } return dictionary.Values.OrderBy((ZoneBlueprintRequirement requirement) => requirement.ItemName, StringComparer.Ordinal).ToList(); } [IteratorStateMachine(typeof(d__52))] private static IEnumerator CollectRequirementsAsync(IEnumerable entries, Action> onComplete) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__52(0) { entries = entries, onComplete = onComplete }; } private static void AccumulateRequirements(Dictionary requirements, BlueprintLoadEntry entry) { Piece component = entry.Prefab.GetComponent(); if ((Object)(object)component == (Object)null) { return; } Requirement[] resources = component.m_resources; foreach (Requirement val in resources) { if (Object.op_Implicit((Object)(object)val.m_resItem) && val.m_amount > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; if (!requirements.TryGetValue(name, out ZoneBlueprintRequirement value)) { value = (requirements[name] = new ZoneBlueprintRequirement { ItemName = name, PrefabName = Utils.GetPrefabName(((Component)val.m_resItem).gameObject), DisplayName = val.m_resItem.m_itemData.m_shared.m_name }); } value.Amount += val.GetAmount(0); } } } private static string ValidateBuildAccessWithoutInventory(Player player, IEnumerable entries) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) foreach (BlueprintLoadEntry entry in entries) { Piece component = entry.Prefab.GetComponent(); if (!((Object)(object)component == (Object)null)) { if (!player.HaveRequirements(component, (RequirementMode)1)) { return HomesteadLocalization.Format("hs_blueprint_missing_known_station_or_materials", entry.Entry.Prefab); } if ((Object)(object)component.m_craftingStation != (Object)null && !Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(component.m_craftingStation.m_name, ((Component)player).transform.position)) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)22)) { return HomesteadLocalization.Format("hs_blueprint_missing_crafting_station", entry.Entry.Prefab); } } } return ""; } [IteratorStateMachine(typeof(d__55))] private static IEnumerator ValidateBuildAccessWithoutInventoryAsync(Player player, IEnumerable entries, Action onComplete) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__55(0) { player = player, entries = entries, onComplete = onComplete }; } internal static bool TryReadWearNTear(ZDO zdo, out GameObject prefab) { prefab = null; if (zdo == null || !zdo.IsValid()) { return false; } prefab = ZNetScene.instance.GetPrefab(zdo.GetPrefab()); if (Object.op_Implicit((Object)(object)prefab) && (Object)(object)prefab.GetComponent() != (Object)null) { return (Object)(object)prefab.GetComponent() != (Object)null; } return false; } internal static bool TryReadSavableWearNTear(ZDO zdo, out GameObject prefab) { if (TryReadWearNTear(zdo, out prefab)) { return HasBuildRecipe(prefab); } return false; } internal static bool HasBuildRecipe(GameObject? prefab) { if (!Object.op_Implicit((Object)(object)prefab)) { return false; } Piece component = prefab.GetComponent(); if ((Object)(object)component == (Object)null || component.m_resources == null) { return false; } if (HasResourceCost(component)) { return IsRegisteredPlayerBuildPiece(prefab); } return false; } private static bool HasResourceCost(Piece piece) { return piece.m_resources.Any((Requirement requirement) => Object.op_Implicit((Object)(object)requirement.m_resItem) && requirement.m_amount > 0); } private static bool IsRegisteredPlayerBuildPiece(GameObject prefab) { string prefabName = Utils.GetPrefabName(prefab); if (string.IsNullOrWhiteSpace(prefabName)) { return false; } ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || instance.m_items == null) { return false; } if (_buildRecipeCacheObjectDbCount != instance.m_items.Count) { BuildRecipeCache.Clear(); _buildRecipeCacheObjectDbCount = instance.m_items.Count; } if (BuildRecipeCache.TryGetValue(prefabName, out var value)) { return value; } foreach (GameObject item in instance.m_items) { PieceTable val = (Object.op_Implicit((Object)(object)item) ? item.GetComponent() : null)?.m_itemData.m_shared.m_buildPieces; if (val?.m_pieces != null && val.m_pieces.Any((GameObject piecePrefab) => Object.op_Implicit((Object)(object)piecePrefab) && string.Equals(Utils.GetPrefabName(piecePrefab), prefabName, StringComparison.Ordinal))) { BuildRecipeCache[prefabName] = true; return true; } } BuildRecipeCache[prefabName] = false; return false; } private static ZoneBlueprintFile LoadBlueprint(string name) { string blueprintPath = GetBlueprintPath(name); if (!File.Exists(blueprintPath)) { throw new FileNotFoundException("Homestead blueprint not found: " + blueprintPath); } return ZoneBlueprintFileFormat.ReadFile(blueprintPath); } private static ZoneBlueprintFile LoadPlanBlueprint(string name) { string planGhostBlueprintPath = GetPlanGhostBlueprintPath(name); if (File.Exists(planGhostBlueprintPath)) { return ZoneBlueprintFileFormat.ReadFile(planGhostBlueprintPath); } return LoadBlueprint(name); } private static string SaveBlueprint(string name, ZoneBlueprintFile blueprint) { string blueprintPath = GetBlueprintPath(name); Directory.CreateDirectory(Path.GetDirectoryName(blueprintPath)); ZoneBlueprintFileFormat.WriteFile(blueprintPath, blueprint); bool iconReady = false; try { iconReady = (Object)(object)ZoneBlueprintVisuals.RenderAndCacheIcon(name, blueprint) != (Object)null; } catch (Exception ex) { _logger.LogWarning((object)("Failed to render Homestead blueprint icon '" + name + "' immediately: " + ex.Message)); } ZoneBlueprintSaveToolMenu.RefreshAfterBlueprintSaved(name, blueprint, iconReady); return blueprintPath; } private static ZoneBlueprintFile CloneForName(ZoneBlueprintFile blueprint, string name) { return new ZoneBlueprintFile { Version = blueprint.Version, Name = name, Creator = blueprint.Creator, World = blueprint.World, SavedAt = blueprint.SavedAt, Radius = blueprint.Radius, Entries = blueprint.Entries.Select((ZoneBlueprintEntry entry) => new ZoneBlueprintEntry { Prefab = entry.Prefab, LocalPos = entry.LocalPos.ToArray(), LocalRot = entry.LocalRot.ToArray(), Scale = entry.Scale.ToArray(), Text = entry.Text }).ToList(), TerrainContacts = blueprint.TerrainContacts.Select((ZoneBlueprintTerrainContact contact) => new ZoneBlueprintTerrainContact { LocalX = contact.LocalX, LocalY = contact.LocalY, LocalZ = contact.LocalZ }).ToList() }; } private static string ValidateBlueprintFile(ZoneBlueprintFile blueprint) { if (blueprint.Entries.Count == 0) { return HomesteadLocalization.Text("hs_blueprint_no_entries"); } if ((Object)(object)ZNetScene.instance == (Object)null) { return HomesteadLocalization.Text("hs_common_world_not_ready"); } int num = 0; foreach (ZoneBlueprintEntry entry in blueprint.Entries) { if (IsLoadableBlueprintEntry(entry, out var missingPrefab)) { num++; } if (missingPrefab) { LogMissingPrefabOnce(blueprint.Name, entry.Prefab); } } if (num <= 0) { return HomesteadLocalization.Format("hs_blueprint_no_valid_entries", blueprint.Name); } return ""; } private static string GetUniqueBlueprintName(string preferredName) { string text = SanitizePathSegment(string.IsNullOrWhiteSpace(preferredName) ? "store_blueprint" : preferredName.Trim()); string text2 = text; int num = 2; while (File.Exists(GetBlueprintPath(text2))) { text2 = $"{text}_{num++}"; } return text2; } private static string GetUniquePlanGhostBlueprintName(string preferredName) { string text = SanitizePathSegment(string.IsNullOrWhiteSpace(preferredName) ? "plan_ghost" : preferredName.Trim()); string text2 = text; int num = 2; while (File.Exists(GetPlanGhostBlueprintPath(text2))) { text2 = $"{text}_{num++}"; } return text2; } private static void EnsureWorldReady() { if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || ZDOMan.instance == null || (Object)(object)ZoneSystem.instance == (Object)null) { throw new InvalidOperationException("World is not ready."); } } private static string GetBlueprintPath(string name) { return Path.Combine(GetWorldBlueprintDirectory(), SanitizePathSegment(name) + ".blueprint"); } private static string GetPlanGhostBlueprintPath(string name) { return Path.Combine(GetPlanGhostBlueprintDirectory(), SanitizePathSegment(name) + ".blueprint"); } internal static string GetBlueprintIconPath(string name) { return Path.Combine(GetWorldBlueprintDirectory(), SanitizePathSegment(name) + ".png"); } private static string GetWorldBlueprintDirectory() { return HomesteadPlugin.BlueprintStorageFullPath; } private static string GetPlanGhostBlueprintDirectory() { return HomesteadPlugin.PlanGhostStorageFullPath; } private static void CleanupPlanGhostFilesIfDue() { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (_nextPlanGhostCleanupAt <= 0f) { _nextPlanGhostCleanupAt = realtimeSinceStartup + 600f; } else if (!(realtimeSinceStartup < _nextPlanGhostCleanupAt)) { _nextPlanGhostCleanupAt = realtimeSinceStartup + 21600f; try { CleanupPlanGhostFiles(); } catch (Exception ex) { _nextPlanGhostCleanupAt = Time.realtimeSinceStartup + 60f; _logger.LogWarning((object)("Homestead plan ghost cleanup failed: " + ex.Message)); } } } private static void CleanupPlanGhostFiles() { if (!ZoneBlueprintChestZdoRegistry.IsReady) { _nextPlanGhostCleanupAt = Time.realtimeSinceStartup + 60f; return; } string planGhostBlueprintDirectory = GetPlanGhostBlueprintDirectory(); if (!Directory.Exists(planGhostBlueprintDirectory)) { return; } HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (ZDO item in ZoneBlueprintChestZdoRegistry.EnumerateChestZdos()) { if (item.GetPrefab() == ZoneBlueprintPlanChestPrefab.PrefabHash) { string @string = item.GetString("hs_blueprint_name", ""); if (!string.IsNullOrWhiteSpace(@string)) { hashSet.Add(SanitizePathSegment(@string)); } } } int num = 0; string[] files = Directory.GetFiles(planGhostBlueprintDirectory, "*.blueprint", SearchOption.TopDirectoryOnly); foreach (string text in files) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); if (!string.IsNullOrWhiteSpace(fileNameWithoutExtension) && !hashSet.Contains(fileNameWithoutExtension)) { try { File.Delete(text); num++; } catch (Exception ex) { _logger.LogWarning((object)("Failed to delete orphan Homestead plan ghost blueprint '" + text + "': " + ex.Message)); } } } if (num > 0) { _logger.LogInfo((object)$"Homestead plan ghost cleanup deleted {num} orphan blueprint file(s)."); } } private static string GetWorldName() { ZNet instance = ZNet.instance; return ((instance != null) ? instance.GetWorldName() : null) ?? "unknown"; } private static string SanitizePathSegment(string value) { char[] invalidChars = Path.GetInvalidFileNameChars(); string text = new string(value.Select((char character) => (!invalidChars.Contains(character)) ? character : '_').ToArray()).Trim(); if (text.Length == 0) { throw new InvalidOperationException("Blueprint name resolves to an empty path segment."); } return text; } private static Vector3 ReadScale(ZDO zdo, GameObject prefab) { //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) return zdo.GetVec3(ZDOVars.s_scaleHash, prefab.transform.localScale); } private static string ReadBlueprintText(ZDO zdo, GameObject prefab) { if (prefab.GetComponent() == null) { return ""; } ZNetView val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(zdo) : null); TextReceiver val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); return (((val2 != null) ? val2.GetText() : zdo.GetString(ZDOVars.s_text, "")) ?? "").Replace(";", "").Replace("\0", ""); } private static float[] ToArray(Vector3 value) { //IL_0008: 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) //IL_0024: Unknown result type (might be due to invalid IL or missing references) return new float[3] { Round(value.x), Round(value.y), Round(value.z) }; } private static float[] ToArray(Quaternion value) { //IL_0008: 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) //IL_0024: 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) return new float[4] { Round(value.x), Round(value.y), Round(value.z), Round(value.w) }; } private static Vector3 FromVector(float[] value) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) return new Vector3(value[0], value[1], value[2]); } private static Quaternion FromQuaternion(float[] value) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new Quaternion(value[0], value[1], value[2], value[3]); } private static float Round(float value) { return Mathf.Round(value * 1000f) / 1000f; } private static float SampleGroundY(float x, float z, float fallbackY) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return fallbackY; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(x, fallbackY, z); Vector3 val2 = default(Vector3); Biome val3 = default(Biome); BiomeArea val4 = default(BiomeArea); Heightmap val5 = default(Heightmap); ZoneSystem.instance.GetGroundData(ref val, ref val2, ref val3, ref val4, ref val5); return val.y; } } internal static class ZoneBlueprintFileFormat { private enum BlueprintSection { Pieces, SnapPoints, Terrain } public const string BlueprintExtension = ".blueprint"; public const string IconExtension = ".png"; private const string DefaultCreator = "Homestead"; private const string DefaultCategory = "Blueprints"; private const string DefaultPieceCategory = "Building"; private const string HeaderName = "#Name:"; private const string HeaderCreator = "#Creator:"; private const string HeaderDescription = "#Description:"; private const string HeaderCategory = "#Category:"; private const string HeaderHomesteadVersion = "#HomesteadVersion:"; private const string HeaderHomesteadWorld = "#HomesteadWorld:"; private const string HeaderHomesteadSavedAt = "#HomesteadSavedAt:"; private const string HeaderHomesteadRadius = "#HomesteadRadius:"; private const string HeaderHomesteadTerrainContact = "#HomesteadTerrainContact:"; private const string HeaderSnapPoints = "#SnapPoints"; private const string HeaderTerrain = "#Terrain"; private const string HeaderHeight = "#Height:"; private const string HeaderPaint = "#Paint"; private const string HeaderPieces = "#Pieces"; public static ZoneBlueprintFile ReadFile(string path) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path); return Deserialize(File.ReadAllText(path), fileNameWithoutExtension); } public static void WriteFile(string path, ZoneBlueprintFile blueprint) { File.WriteAllText(path, Serialize(blueprint)); } public static string Serialize(ZoneBlueprintFile blueprint) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("#Name:").AppendLine(SanitizeHeaderValue(blueprint.Name)); stringBuilder.Append("#Creator:").AppendLine(SanitizeHeaderValue(string.IsNullOrWhiteSpace(blueprint.Creator) ? "Homestead" : blueprint.Creator)); stringBuilder.Append("#Description:").AppendLine(); stringBuilder.Append("#Category:").AppendLine("Blueprints"); stringBuilder.Append("#HomesteadVersion:").AppendLine(blueprint.Version.ToString(CultureInfo.InvariantCulture)); stringBuilder.Append("#HomesteadWorld:").AppendLine(SanitizeHeaderValue(blueprint.World)); stringBuilder.Append("#HomesteadSavedAt:").AppendLine(SanitizeHeaderValue(blueprint.SavedAt)); stringBuilder.Append("#HomesteadRadius:").AppendLine(FormatFloat(blueprint.Radius)); foreach (ZoneBlueprintTerrainContact terrainContact in blueprint.TerrainContacts) { stringBuilder.Append("#HomesteadTerrainContact:").Append(FormatFloat(terrainContact.LocalX)).Append(';') .Append(FormatFloat(terrainContact.LocalY)) .Append(';') .AppendLine(FormatFloat(terrainContact.LocalZ)); } stringBuilder.AppendLine("#Pieces"); foreach (ZoneBlueprintEntry entry in blueprint.Entries) { stringBuilder.Append(SanitizePieceField(entry.Prefab)).Append(';').Append("Building") .Append(';') .Append(FormatFloat(ReadArray(entry.LocalPos, 0))) .Append(';') .Append(FormatFloat(ReadArray(entry.LocalPos, 1))) .Append(';') .Append(FormatFloat(ReadArray(entry.LocalPos, 2))) .Append(';') .Append(FormatFloat(ReadArray(entry.LocalRot, 0))) .Append(';') .Append(FormatFloat(ReadArray(entry.LocalRot, 1))) .Append(';') .Append(FormatFloat(ReadArray(entry.LocalRot, 2))) .Append(';') .Append(FormatFloat(ReadArray(entry.LocalRot, 3, 1f))) .Append(';') .Append(EncodeJsonString(SanitizeAdditionalInfo(entry.Text))) .Append(';') .Append(FormatFloat(ReadArray(entry.Scale, 0, 1f))) .Append(';') .Append(FormatFloat(ReadArray(entry.Scale, 1, 1f))) .Append(';') .AppendLine(FormatFloat(ReadArray(entry.Scale, 2, 1f))); } return stringBuilder.ToString(); } public static ZoneBlueprintFile Deserialize(string text, string fallbackName = "") { ZoneBlueprintFile zoneBlueprintFile = new ZoneBlueprintFile { Name = (fallbackName ?? "") }; BlueprintSection blueprintSection = BlueprintSection.Pieces; using StringReader stringReader = new StringReader(text ?? ""); string text2; while ((text2 = stringReader.ReadLine()) != null) { string text3 = text2.Trim(); if (text3.Length == 0) { continue; } string value2; string value3; string value4; string value5; string value6; string value8; ZoneBlueprintEntry entry; if (TryReadHeader(text3, "#Name:", out string value)) { zoneBlueprintFile.Name = (string.IsNullOrWhiteSpace(value) ? zoneBlueprintFile.Name : value.Trim()); } else if (TryReadHeader(text3, "#Creator:", out value2)) { zoneBlueprintFile.Creator = value2.Trim(); } else if (TryReadHeader(text3, "#HomesteadVersion:", out value3)) { if (int.TryParse(value3.Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { zoneBlueprintFile.Version = result; } } else if (TryReadHeader(text3, "#HomesteadWorld:", out value4)) { zoneBlueprintFile.World = value4.Trim(); } else if (TryReadHeader(text3, "#HomesteadSavedAt:", out value5)) { zoneBlueprintFile.SavedAt = value5.Trim(); } else if (TryReadHeader(text3, "#HomesteadRadius:", out value6)) { if (TryParseFloat(value6, out var value7)) { zoneBlueprintFile.Radius = value7; } } else if (TryReadHeader(text3, "#HomesteadTerrainContact:", out value8)) { if (TryParseVector(value8, out var x, out var y, out var z)) { zoneBlueprintFile.TerrainContacts.Add(new ZoneBlueprintTerrainContact { LocalX = x, LocalY = y, LocalZ = z }); } } else if (StartsWithHeader(text3, "#SnapPoints")) { blueprintSection = BlueprintSection.SnapPoints; } else if (StartsWithHeader(text3, "#Terrain") || StartsWithHeader(text3, "#Height:") || StartsWithHeader(text3, "#Paint")) { blueprintSection = BlueprintSection.Terrain; } else if (StartsWithHeader(text3, "#Pieces")) { blueprintSection = BlueprintSection.Pieces; } else if (!text3.StartsWith("#", StringComparison.Ordinal) && blueprintSection == BlueprintSection.Pieces && TryParsePiece(text3, out entry) && entry != null) { zoneBlueprintFile.Entries.Add(entry); } } if (string.IsNullOrWhiteSpace(zoneBlueprintFile.Name)) { zoneBlueprintFile.Name = fallbackName ?? ""; } return zoneBlueprintFile; } private static bool TryParsePiece(string line, out ZoneBlueprintEntry? entry) { entry = null; string[] array = line.Split(new char[1] { ';' }); if (array.Length < 9) { return false; } string text = array[0].Trim(); if (string.IsNullOrWhiteSpace(text) || !TryParseFloat(array[2], out var value) || !TryParseFloat(array[3], out var value2) || !TryParseFloat(array[4], out var value3) || !TryParseFloat(array[5], out var value4) || !TryParseFloat(array[6], out var value5) || !TryParseFloat(array[7], out var value6) || !TryParseFloat(array[8], out var value7)) { return false; } float value8 = 1f; float value9 = 1f; float value10 = 1f; if (array.Length > 12) { TryParseFloat(array[10], out value8, 1f); TryParseFloat(array[11], out value9, 1f); TryParseFloat(array[12], out value10, 1f); } entry = new ZoneBlueprintEntry { Prefab = text, LocalPos = new float[3] { value, value2, value3 }, LocalRot = new float[4] { value4, value5, value6, value7 }, Scale = new float[3] { value8, value9, value10 }, Text = ((array.Length > 9) ? DecodeAdditionalInfo(array[9]) : "") }; return true; } private static bool TryReadHeader(string line, string header, out string value) { value = ""; if (!line.StartsWith(header, StringComparison.OrdinalIgnoreCase)) { return false; } value = line.Substring(header.Length); return true; } private static bool StartsWithHeader(string line, string header) { return line.StartsWith(header, StringComparison.OrdinalIgnoreCase); } private static bool TryParseVector(string text, out float x, out float y, out float z) { x = 0f; y = 0f; z = 0f; string[] array = (text ?? "").Split(new char[1] { ';' }); if (array.Length >= 3 && TryParseFloat(array[0], out x) && TryParseFloat(array[1], out y)) { return TryParseFloat(array[2], out z); } return false; } private static bool TryParseFloat(string text, out float value, float defaultValue = 0f) { text = (text ?? "").Trim().Replace(',', '.'); if (string.IsNullOrEmpty(text)) { value = defaultValue; return true; } if (!float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out value) || float.IsNaN(value) || float.IsInfinity(value)) { value = defaultValue; return false; } return true; } private static string FormatFloat(float value) { if (float.IsNaN(value) || float.IsInfinity(value)) { value = 0f; } return value.ToString("0.###", CultureInfo.InvariantCulture); } private static float ReadArray(float[]? values, int index, float fallback = 0f) { if (values == null || index < 0 || index >= values.Length) { return fallback; } return values[index]; } private static string SanitizeHeaderValue(string value) { return (value ?? "").Replace('\r', ' ').Replace('\n', ' ').Trim(); } private static string SanitizePieceField(string value) { return SanitizeHeaderValue(value).Replace(";", ""); } private static string SanitizeAdditionalInfo(string value) { return (value ?? "").Replace(";", "").Replace("\0", ""); } private static string DecodeAdditionalInfo(string value) { value = (value ?? "").Trim(); if (value.Length == 0 || string.Equals(value, "null", StringComparison.OrdinalIgnoreCase) || value == "\"\"") { return ""; } return SanitizeAdditionalInfo((value.Length >= 2 && value[0] == '"' && value[value.Length - 1] == '"') ? DecodeJsonString(value) : value); } private static string EncodeJsonString(string value) { if (value == null) { value = ""; } StringBuilder stringBuilder = new StringBuilder(value.Length + 2); stringBuilder.Append('"'); string text = value; foreach (char c in text) { switch (c) { case '"': stringBuilder.Append("\\\""); continue; case '\\': stringBuilder.Append("\\\\"); continue; case '\b': stringBuilder.Append("\\b"); continue; case '\f': stringBuilder.Append("\\f"); continue; case '\n': stringBuilder.Append("\\n"); continue; case '\r': stringBuilder.Append("\\r"); continue; case '\t': stringBuilder.Append("\\t"); continue; } if (c < ' ') { StringBuilder stringBuilder2 = stringBuilder.Append("\\u"); int num = c; stringBuilder2.Append(num.ToString("x4", CultureInfo.InvariantCulture)); } else { stringBuilder.Append(c); } } stringBuilder.Append('"'); return stringBuilder.ToString(); } private static string DecodeJsonString(string value) { StringBuilder stringBuilder = new StringBuilder(value.Length); for (int i = 1; i < value.Length - 1; i++) { char c = value[i]; if (c != '\\' || i + 1 >= value.Length - 1) { stringBuilder.Append(c); continue; } char c2 = value[++i]; switch (c2) { case '"': case '/': case '\\': stringBuilder.Append(c2); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'n': stringBuilder.Append('\n'); break; case 'r': stringBuilder.Append('\r'); break; case 't': stringBuilder.Append('\t'); break; case 'u': { if (i + 4 < value.Length && int.TryParse(value.Substring(i + 1, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result)) { stringBuilder.Append((char)result); i += 4; } break; } default: stringBuilder.Append(c2); break; } } return stringBuilder.ToString(); } } internal static class ZoneBlueprintHammerTable { private static readonly List TempPieceTables = new List(); public static bool LooksLike(PieceTable table) { if (((Object)table).name.ToLowerInvariant().Contains("hammer")) { return true; } return table.m_pieces.Any((GameObject piece) => Object.op_Implicit((Object)(object)piece) && Utils.GetPrefabName(piece).Equals("piece_repair", StringComparison.OrdinalIgnoreCase)); } public static void SanitizeLocalPlayerTables(bool removeBlueprintPieces) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if ((Object)(object)localPlayer.m_buildPieces != (Object)null && LooksLike(localPlayer.m_buildPieces)) { Sanitize(localPlayer.m_buildPieces, removeBlueprintPieces); } TempPieceTables.Clear(); Inventory inventory = ((Humanoid)localPlayer).m_inventory; if (inventory != null) { inventory.GetAllPieceTables(TempPieceTables); } foreach (PieceTable tempPieceTable in TempPieceTables) { if ((Object)(object)tempPieceTable != (Object)null && LooksLike(tempPieceTable)) { Sanitize(tempPieceTable, removeBlueprintPieces); } } TempPieceTables.Clear(); } public static void Sanitize(PieceTable table, bool removeBlueprintPieces) { if ((Object)(object)table == (Object)null) { return; } table.m_pieces.RemoveAll((GameObject pieceObject) => ShouldRemovePieceObject(pieceObject, removeBlueprintPieces)); foreach (List availablePiece in table.m_availablePieces) { availablePiece.RemoveAll((Piece piece) => ShouldRemoveAvailablePiece(piece, removeBlueprintPieces)); } } public static bool EnsurePiece(PieceTable table, Piece piece, PieceCategory homesteadCategory, string homesteadLabel) { //IL_0029: 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_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null || !Object.op_Implicit((Object)(object)piece) || !Object.op_Implicit((Object)(object)((Component)piece).gameObject)) { return false; } bool flag = false; if (!table.m_categories.Contains(piece.m_category)) { table.m_categories.Add(piece.m_category); flag = true; } flag |= EnsureCategoryLabels(table, homesteadCategory, homesteadLabel); if (!table.m_pieces.Contains(((Component)piece).gameObject)) { table.m_pieces.Add(((Component)piece).gameObject); flag = true; } return flag; } public static bool EnsureCategoryLabels(PieceTable table, PieceCategory homesteadCategory, string homesteadLabel) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_005c: Unknown result type (might be due to invalid IL or missing references) bool flag = false; while (table.m_categoryLabels.Count < table.m_categories.Count) { int count = table.m_categoryLabels.Count; PieceCategory val = table.m_categories[count]; table.m_categoryLabels.Add((val == homesteadCategory) ? homesteadLabel : ((object)(PieceCategory)(ref val)).ToString()); flag = true; } int num = table.m_categories.IndexOf(homesteadCategory); if (num >= 0 && num < table.m_categoryLabels.Count) { if (!string.Equals(table.m_categoryLabels[num], homesteadLabel, StringComparison.Ordinal)) { table.m_categoryLabels[num] = homesteadLabel; flag = true; } flag |= MoveHomesteadCategoryToEnd(table, num, homesteadLabel); } return flag; } public static void EnsureAvailableCategorySlots(PieceTable table) { //IL_001c: 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) //IL_0023: 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_002b: Expected I4, but got Unknown int num = table.m_categories.Count; foreach (PieceCategory category in table.m_categories) { num = Mathf.Max(num, category + 1); } while (table.m_availablePieces.Count < num) { table.m_availablePieces.Add(new List()); } if (table.m_selectedPiece.Length < num) { Array.Resize(ref table.m_selectedPiece, num); } if (table.m_lastSelectedPiece.Length < num) { Array.Resize(ref table.m_lastSelectedPiece, num); } } public static void EnsurePieceVisible(PieceTable table, Piece piece, PieceCategory homesteadCategory, string homesteadLabel) { //IL_0007: 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) //IL_0047: Expected I4, but got Unknown //IL_0016: 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) if (table.m_categories.IndexOf(piece.m_category) < 0) { if (EnsurePiece(table, piece, homesteadCategory, homesteadLabel)) { EnsureAvailableCategorySlots(table); } if (table.m_categories.IndexOf(piece.m_category) < 0) { return; } } EnsureAvailableCategorySlots(table); int num = (int)piece.m_category; if (num >= 0 && num < table.m_availablePieces.Count) { List list = table.m_availablePieces[num]; if (!list.Contains(piece)) { list.Add(piece); } } } public static void RefreshVisibleSelection(Player player, PieceCategory homesteadCategory, string homesteadLabel) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Hud instance = Hud.instance; if (!((Object)(object)instance == (Object)null) && instance.m_buildHud.activeSelf) { PieceTable buildPieces = player.m_buildPieces; if ((Object)(object)buildPieces != (Object)null && LooksLike(buildPieces)) { EnsureCategoryLabels(buildPieces, homesteadCategory, homesteadLabel); } instance.m_lastPieceCategory = (PieceCategory)8; instance.UpdateBuild(player, true); } } private static bool ShouldRemovePieceObject(GameObject? pieceObject, bool removeBlueprintPieces) { if ((Object)(object)pieceObject == (Object)null || !Object.op_Implicit((Object)(object)pieceObject)) { return true; } Piece component; try { component = pieceObject.GetComponent(); } catch { return true; } return ShouldRemoveAvailablePiece(component, removeBlueprintPieces); } private static bool ShouldRemoveAvailablePiece(Piece? piece, bool removeBlueprintPieces) { if ((Object)(object)piece == (Object)null || !Object.op_Implicit((Object)(object)piece) || (Object)(object)((Component)piece).gameObject == (Object)null || !Object.op_Implicit((Object)(object)((Component)piece).gameObject)) { return true; } if (removeBlueprintPieces) { ZoneBlueprintSaveToolMarker component = ((Component)piece).GetComponent(); if (component != null) { return component.Kind == ZoneBlueprintToolKind.Blueprint; } return false; } return false; } private static bool MoveHomesteadCategoryToEnd(PieceTable table, int homesteadIndex, string homesteadLabel) { //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_0037: Unknown result type (might be due to invalid IL or missing references) int num = table.m_categories.Count - 1; if (homesteadIndex < 0 || homesteadIndex >= num) { return false; } PieceCategory item = table.m_categories[homesteadIndex]; table.m_categories.RemoveAt(homesteadIndex); table.m_categories.Add(item); if (homesteadIndex < table.m_categoryLabels.Count) { string item2 = table.m_categoryLabels[homesteadIndex]; table.m_categoryLabels.RemoveAt(homesteadIndex); table.m_categoryLabels.Add(item2); } int num2 = table.m_categories.Count - 1; if (num2 >= 0 && num2 < table.m_categoryLabels.Count) { table.m_categoryLabels[num2] = homesteadLabel; } return true; } } internal static class ZoneDvergrCirclet { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDbAwakePatch { private static void Postfix() { PatchObjectDbItem(); } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private static class ItemDropAwakePatch { private static void Postfix(ItemDrop __instance) { PatchItemData(__instance.m_itemData, initializeDurability: true); } } [HarmonyPatch(typeof(ItemDrop), "Start")] private static class ItemDropStartPatch { private static void Postfix(ItemDrop __instance) { PatchItemData(__instance.m_itemData, initializeDurability: true); } } [HarmonyPatch(typeof(Inventory), "Load")] private static class InventoryLoadPatch { private static void Postfix(Inventory __instance) { PatchInventoryItems(__instance); } } [HarmonyPatch(typeof(Inventory), "Changed")] private static class InventoryChangedPatch { private static void Postfix(Inventory __instance) { PatchInventoryItems(__instance); } } [HarmonyPatch(typeof(VisEquipment), "AttachItem")] private static class VisEquipmentAttachItemPatch { private static void Postfix(VisEquipment __instance, GameObject __result, int itemHash) { if (Active && Object.op_Implicit((Object)(object)__result) && itemHash == PrefabHash) { ItemData val = TryGetVisualHelmetItem(__instance); ZNetView nview; if (val != null) { PatchItemData(val, initializeDurability: true); (__result.GetComponent() ?? __result.AddComponent()).Initialize(val); } else if (TryGetRemoteCircletNview(__instance, out nview) && (Object)(object)nview != (Object)null) { (__result.GetComponent() ?? __result.AddComponent()).InitializeRemote(nview); } } } } [HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")] private static class VisEquipmentUpdateEquipmentVisualsPatch { private static void Postfix(VisEquipment __instance) { if (ShouldSyncRemoteVisuals() && Object.op_Implicit((Object)(object)__instance) && __instance.m_isPlayer && !IsLocalVisEquipment(__instance) && (Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent().RefreshNow(); } } } [HarmonyPatch(typeof(Humanoid), "DrainEquipedItemDurability")] private static class HumanoidDrainEquipedItemDurabilityPatch { private static bool Prefix(ItemData item) { if (Active) { return !IsDvergrCircletItem(item); } return true; } } [HarmonyPatch(typeof(Humanoid), "UpdateEquipment")] private static class HumanoidUpdateEquipmentPatch { private static void Postfix(Humanoid __instance, float dt) { if (!Active) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer || !TryGetEquippedDvergrCirclet(val, out ItemData item) || item == null) { return; } CircletState circletState = LoadState(item); if (PatchItemData(item, initializeDurability: true) && circletState.LightOn && !(item.m_durability <= 0f) && IsCircletLightOn(val, item)) { float durability = item.m_durability; item.m_durability = Mathf.Max(0f, item.m_durability - GetDurabilityDrainPerSecond(item) * dt); if (Mathf.Abs(durability - item.m_durability) > 0.001f) { PublishLocalCircletState(val, item, circletState); } if (durability > 0f && item.m_durability <= 0f) { ((Character)val).Message((MessageType)1, HomesteadLocalization.Text("hs_dvergr_depleted"), 0, item.GetIcon()); ((Humanoid)val).GetInventory().Changed(); } } } } [HarmonyPatch(typeof(Player), "DamageArmorDurability")] private static class PlayerDamageArmorDurabilityPatch { private static void Prefix(Player __instance, ref float __state) { __state = float.NaN; if (TryGetEquippedDvergrCirclet(__instance, out ItemData item) && item != null && Active && PatchItemData(item, initializeDurability: true)) { __state = item.m_durability; } } private static void Postfix(Player __instance, float __state) { if (!float.IsNaN(__state) && TryGetEquippedDvergrCirclet(__instance, out ItemData item) && item != null && IsDvergrCircletItem(item)) { item.m_durability = Mathf.Clamp(__state, 0f, item.GetMaxDurability()); } } } [HarmonyPatch(typeof(InventoryGui), "CanRepair")] private static class InventoryGuiCanRepairPatch { private static bool Prefix(ItemData item, ref bool __result) { if (!Active || !IsDvergrCircletItem(item)) { return true; } PatchItemData(item, initializeDurability: true); Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !item.m_shared.m_canBeReparied) { __result = false; return false; } if (localPlayer.NoCostCheat()) { __result = true; return false; } CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation(); __result = MatchesRepairStation(currentCraftingStation); return false; } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int) })] private static class ItemDataGetTooltipPatch { [HarmonyPriority(200)] private static void Postfix(ItemData item, bool crafting, ref string __result) { if (!crafting && Active && PatchItemData(item, initializeDurability: true)) { __result += BuildTooltip(item); } } } private sealed class CircletState { internal bool LightOn = true; internal bool HasFuel = true; internal float IntensityMultiplier = 1f; internal float RangeMultiplier = 1f; } private sealed class ZoneDvergrCircletVisual : MonoBehaviour { private readonly List _lights = new List(); private float[] _baseIntensities = Array.Empty(); private float[] _baseRanges = Array.Empty(); private bool[] _baseEnabled = Array.Empty(); private ItemData? _item; private ZNetView? _remoteStateView; private bool _remoteCulled; internal bool IsFor(ItemData? item) { if ((Object)(object)_remoteStateView == (Object)null && _item == item) { return _lights.Count > 0; } return false; } internal bool IsRemoteFor(ZNetView nview) { if ((Object)(object)_remoteStateView == (Object)(object)nview) { return _lights.Count > 0; } return false; } internal void Initialize(ItemData? item) { _item = item; _remoteStateView = null; _remoteCulled = false; CaptureLights(); Apply(); } internal void InitializeRemote(ZNetView nview) { _item = null; _remoteStateView = nview; _remoteCulled = false; CaptureLights(); Apply(); } internal void SetRemoteCulled(bool culled) { if (!((Object)(object)_remoteStateView == (Object)null) && _remoteCulled != culled) { _remoteCulled = culled; Apply(); } } private void CaptureLights() { _lights.Clear(); ((Component)this).gameObject.GetComponentsInChildren(true, _lights); _baseIntensities = new float[_lights.Count]; _baseRanges = new float[_lights.Count]; _baseEnabled = new bool[_lights.Count]; for (int i = 0; i < _lights.Count; i++) { Light val = _lights[i]; _baseIntensities[i] = (Object.op_Implicit((Object)(object)val) ? val.intensity : 0f); _baseRanges[i] = (Object.op_Implicit((Object)(object)val) ? val.range : 0f); _baseEnabled[i] = Object.op_Implicit((Object)(object)val) && ((Behaviour)val).enabled; } } internal void ApplyNow() { Apply(); } private void LateUpdate() { Apply(); } private void Apply() { CircletState circletState = (((Object)(object)_remoteStateView != (Object)null) ? LoadRemoteState(_remoteStateView) : LoadState(_item)); bool flag = Active && !_remoteCulled && circletState.LightOn && circletState.HasFuel; float intensityMultiplier = circletState.IntensityMultiplier; float rangeMultiplier = circletState.RangeMultiplier; for (int i = 0; i < _lights.Count; i++) { Light val = _lights[i]; if (Object.op_Implicit((Object)(object)val)) { val.intensity = _baseIntensities[i] * intensityMultiplier; val.range = _baseRanges[i] * rangeMultiplier; ((Behaviour)val).enabled = flag && _baseEnabled[i]; } } } } private sealed class ZoneDvergrCircletRemoteVisual : MonoBehaviour { private const float RefreshInterval = 0.25f; private VisEquipment? _visEquipment; private GameObject? _customRoot; private float _nextRefreshTime; private void Awake() { _visEquipment = ((Component)this).GetComponent(); } private void LateUpdate() { if (Time.time >= _nextRefreshTime) { Refresh(force: false); } } private void OnDestroy() { DestroyCustomRoot(); } internal void RefreshNow() { Refresh(force: true); } private void Refresh(bool force) { if (!force && Time.time < _nextRefreshTime) { return; } _nextRefreshTime = Time.time + 0.25f; VisEquipment val = (((Object)(object)_visEquipment != (Object)null) ? _visEquipment : (_visEquipment = ((Component)this).GetComponent())); if (!ShouldSyncRemoteVisuals() || !Object.op_Implicit((Object)(object)val) || !val.m_isPlayer || IsLocalVisEquipment(val) || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { DestroyCustomRoot(); return; } ZNetView nview = val.m_nview; ZDO zDO = nview.GetZDO(); if (zDO == null || zDO.GetInt(RemoteItemKey, 0) != PrefabHash) { CullRemoteVisualComponent(val.m_helmetItemInstance, nview); DestroyCustomRoot(); return; } if (val.m_currentHelmetItemHash == PrefabHash && Object.op_Implicit((Object)(object)val.m_helmetItemInstance)) { DestroyCustomRoot(); EnsureRemoteVisualComponent(val.m_helmetItemInstance, nview, culled: false); return; } CullRemoteVisualComponent(val.m_helmetItemInstance, nview); if (!Object.op_Implicit((Object)(object)val.m_helmet)) { DestroyCustomRoot(); return; } if (!Object.op_Implicit((Object)(object)_customRoot)) { try { _customRoot = val.AttachItem(PrefabHash, 0, val.m_helmet, false, false); if (Object.op_Implicit((Object)(object)_customRoot)) { ((Object)_customRoot).name = "HomesteadDvergrCircletRemoteVisual"; ((Object)_customRoot).hideFlags = (HideFlags)52; } } catch (Exception ex) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogWarning((object)("Failed to attach remote Dvergr circlet visual; remote light sync skipped for this refresh. " + ex.GetType().Name + ": " + ex.Message)); } DestroyCustomRoot(); return; } } if (Object.op_Implicit((Object)(object)_customRoot)) { EnsureRemoteVisualComponent(_customRoot, nview, culled: false); } } private void DestroyCustomRoot() { if (Object.op_Implicit((Object)(object)_customRoot)) { Object.Destroy((Object)(object)_customRoot); } _customRoot = null; } } private const string PrefabName = "HelmetDverger"; private const string CircletExtendedGuid = "shudnal.CircletExtended"; private const string InitKey = "sighsorry.Homestead.dvergr_circlet_initialized"; private const string StateKey = "sighsorry.Homestead.dvergr_circlet_state"; private static readonly int RemoteItemKey = StringExtensionMethods.GetStableHashCode("sighsorry.Homestead.dvergr_circlet_item"); private static readonly int RemoteStateKey = StringExtensionMethods.GetStableHashCode("sighsorry.Homestead.dvergr_circlet_remote_state"); private static readonly int RemoteStateHashKey = StringExtensionMethods.GetStableHashCode("sighsorry.Homestead.dvergr_circlet_remote_state_hash"); private static readonly int PrefabHash = StringExtensionMethods.GetStableHashCode("HelmetDverger"); private static readonly List TempLights = new List(); private static readonly List TempVisualRoots = new List(); private static ManualLogSource? _logger; private static bool _loggedCircletExtendedSkip; private static bool? _circletExtendedLoaded; private static GameObject? _fallbackLightObject; private static Light? _fallbackLight; private static ItemData? _fallbackLightItem; private static GameObject? _fallbackVisualRoot; private static ItemData? _fallbackVisualItem; private static readonly Dictionary RepairStationDisplayNameCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static bool Active { get { if (!DvergrCircletConfig.ExtensionEnabled) { return false; } if (!IsCircletExtendedLoaded()) { return true; } if (!_loggedCircletExtendedSkip) { _loggedCircletExtendedSkip = true; ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)"Circlet Extended is installed, so Homestead Dvergr circlet handling is disabled to avoid conflicts."); } } return false; } } internal static void Initialize(ManualLogSource logger) { _logger = logger; } internal static void ResetForWorldSession() { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { PublishLocalCircletState(localPlayer, null, null); } CleanupFallbackVisuals(); ResetRemoteVisualsForWorldSession(); TempLights.Clear(); TempVisualRoots.Clear(); RepairStationDisplayNameCache.Clear(); _loggedCircletExtendedSkip = false; _circletExtendedLoaded = null; AzuExtendedPlayerInventoryCompat.ResetForWorldSession(); InventorySlotsCompat.ResetForWorldSession(); } internal static void Update() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) bool active = Active; bool flag = ShouldBlockInput(); Player localPlayer = Player.m_localPlayer; ItemData item; ItemData val = ((Object.op_Implicit((Object)(object)localPlayer) && TryGetEquippedDvergrCirclet(localPlayer, out item)) ? item : null); if (!active) { if (Object.op_Implicit((Object)(object)localPlayer)) { PublishLocalCircletState(localPlayer, null, null); } CleanupFallbackVisuals(); return; } if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead()) { if (Object.op_Implicit((Object)(object)localPlayer)) { PublishLocalCircletState(localPlayer, null, null); } CleanupFallbackVisuals(); return; } if (!PatchItemData(val, initializeDurability: true)) { PublishLocalCircletState(localPlayer, null, null); CleanupFallbackVisuals(); return; } ItemData item2 = val; CircletState circletState = LoadState(item2); EnsureLocalCircletVisual(localPlayer, item2, circletState); PublishLocalCircletState(localPlayer, item2, circletState); if (!flag) { if (IsShortcutDownLenient(DvergrCircletConfig.ToggleLightHotkey)) { circletState.LightOn = !circletState.LightOn; SaveState(item2, circletState); ((Humanoid)localPlayer).GetInventory().Changed(); EnsureLocalCircletVisual(localPlayer, item2, circletState); PublishLocalCircletState(localPlayer, item2, circletState); ShowStateHud(circletState); } else if (TryAdjustHotkey((KeyCode)273, circletState, 1f, 0f) || TryAdjustHotkey((KeyCode)274, circletState, -1f, 0f) || TryAdjustHotkey((KeyCode)275, circletState, 0f, 1f) || TryAdjustHotkey((KeyCode)276, circletState, 0f, -1f)) { SaveState(item2, circletState); ((Humanoid)localPlayer).GetInventory().Changed(); EnsureLocalCircletVisual(localPlayer, item2, circletState); PublishLocalCircletState(localPlayer, item2, circletState); ShowStateHud(circletState); } } } private static bool IsCircletExtendedLoaded() { if (_circletExtendedLoaded.HasValue) { return _circletExtendedLoaded.Value; } _circletExtendedLoaded = Chainloader.PluginInfos.ContainsKey("shudnal.CircletExtended"); return _circletExtendedLoaded.Value; } private static bool TryAdjustHotkey(KeyCode arrowKey, CircletState state, float intensityDelta, float rangeDelta) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (!Input.GetKeyDown(arrowKey) || !IsAdjustmentModifierHeld()) { return false; } float perItemAdjustmentStep = DvergrCircletConfig.PerItemAdjustmentStep; if (Mathf.Abs(intensityDelta) > 0.001f) { state.IntensityMultiplier = ClampAndRoundIntensityMultiplier(state.IntensityMultiplier + intensityDelta * perItemAdjustmentStep); } if (Mathf.Abs(rangeDelta) > 0.001f) { state.RangeMultiplier = ClampAndRoundRangeMultiplier(state.RangeMultiplier + rangeDelta * perItemAdjustmentStep); } return true; } private static bool IsAdjustmentModifierHeld() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0013: 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) KeyboardShortcut adjustmentModifierKey = DvergrCircletConfig.AdjustmentModifierKey; if ((int)((KeyboardShortcut)(ref adjustmentModifierKey)).MainKey == 0) { return true; } if (!IsShortcutModifierHeld(((KeyboardShortcut)(ref adjustmentModifierKey)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref adjustmentModifierKey)).Modifiers) { if (!IsShortcutModifierHeld(modifier)) { return false; } } return true; } private static bool IsShortcutDownLenient(KeyboardShortcut shortcut) { //IL_0002: 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_0029: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!IsShortcutModifierHeld(modifier)) { return false; } } return true; } private static bool IsShortcutModifierHeld(KeyCode key) { //IL_0000: 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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected I4, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0) { switch (key - 303) { case 0: case 1: return Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); case 2: case 3: return Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305); case 4: case 5: return Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); default: return Input.GetKey(key); } } return true; } private static bool ShouldBlockInput() { if (!Hud.IsPieceSelectionVisible() && !Console.IsVisible() && !HomesteadInputBlockers.IsTextInputVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible()) { return Minimap.IsOpen(); } return true; } private static bool PatchItemData(ItemData? item, bool initializeDurability) { if (!Active || item == null || item.m_shared == null || !IsDvergrCircletItem(item)) { return false; } PatchSharedData(item.m_shared); float maxDurability = item.GetMaxDurability(); if (initializeDurability && !item.m_customData.ContainsKey("sighsorry.Homestead.dvergr_circlet_initialized")) { item.m_durability = maxDurability; item.m_customData["sighsorry.Homestead.dvergr_circlet_initialized"] = "1"; } else { item.m_durability = Mathf.Clamp(item.m_durability, 0f, maxDurability); } return true; } private static void PatchSharedData(SharedData shared) { shared.m_useDurability = true; shared.m_destroyBroken = false; shared.m_canBeReparied = true; shared.m_maxDurability = 100f; shared.m_durabilityPerLevel = 0f; shared.m_durabilityDrain = 0f; shared.m_useDurabilityDrain = 0f; } private static void PatchObjectDbItem() { if (Active && !((Object)(object)ObjectDB.instance == (Object)null)) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("HelmetDverger"); if (Object.op_Implicit((Object)(object)itemPrefab)) { PatchItemData(itemPrefab.GetComponent()?.m_itemData, initializeDurability: false); } } } private static void PatchInventoryItems(Inventory? inventory) { if (!Active || inventory == null) { return; } foreach (ItemData allItem in inventory.GetAllItems()) { PatchItemData(allItem, initializeDurability: true); } } private static float GetDurabilityDrainPerSecond() { return 100f / DvergrCircletConfig.FuelSeconds; } private static float GetDurabilityDrainPerSecond(ItemData item) { CircletState circletState = LoadState(item); return GetDurabilityDrainPerSecond() * circletState.IntensityMultiplier * circletState.RangeMultiplier; } private static bool MatchesRepairStation(CraftingStation? station) { if (!Object.op_Implicit((Object)(object)station)) { return false; } string text = NormalizeStationName(DvergrCircletConfig.RepairStation); if (text.Length == 0) { return true; } if (!(NormalizeStationName(station.m_name) == text) && !(NormalizeStationName(((Object)((Component)station).gameObject).name) == text)) { return NormalizeStationName(Utils.GetPrefabName(((Object)((Component)station).gameObject).name)) == text; } return true; } private static string NormalizeStationName(string value) { string text = (value ?? string.Empty).Trim(); if (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - 7).Trim(); } text = text.ToLowerInvariant(); if (text.StartsWith("$piece_", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(7); } else if (text.StartsWith("piece_", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(6); } return text.Replace(" ", "").Replace("_", ""); } private static void ShowStateHud(CircletState state) { ZoneAreaToolStatusHud.ShowDvergrCirclet(state.LightOn, state.IntensityMultiplier, state.RangeMultiplier); } private static string BuildTooltip(ItemData item) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) CircletState circletState = LoadState(item); string text = (circletState.LightOn ? "$hud_on" : "$hud_off"); return "\n\n" + HomesteadLocalization.Text("hs_dvergr_title") + "\n" + HomesteadLocalization.Format("hs_dvergr_tooltip_light", text, FormatShortcut(DvergrCircletConfig.ToggleLightHotkey)) + "\n" + HomesteadLocalization.Format("hs_dvergr_tooltip_intensity", circletState.IntensityMultiplier * 100f, FormatAdjustmentShortcutPair("↑ ↓")) + "\n" + HomesteadLocalization.Format("hs_dvergr_tooltip_range", circletState.RangeMultiplier * 100f, FormatAdjustmentShortcutPair("← →")) + "\n" + HomesteadLocalization.Format("hs_dvergr_tooltip_repair_station", GetRepairStationDisplayName()); } private static string GetRepairStationDisplayName() { string text = DvergrCircletConfig.RepairStation; if (string.IsNullOrWhiteSpace(text)) { text = "forge"; } if (RepairStationDisplayNameCache.TryGetValue(text, out string value)) { return value; } string text2 = ResolveRepairStationDisplayName(text); RepairStationDisplayNameCache[text] = text2; return text2; } private static string ResolveRepairStationDisplayName(string configured) { string text = configured.Trim(); GameObject val = FindCraftingStationPrefab(text); if ((Object)(object)val != (Object)null) { Piece component = val.GetComponent(); if ((Object)(object)component != (Object)null && !string.IsNullOrWhiteSpace(component.m_name)) { Localization instance = Localization.instance; string text2 = ((instance != null) ? instance.Localize(component.m_name) : null) ?? ""; if (!string.IsNullOrWhiteSpace(text2) && !string.Equals(text2, component.m_name, StringComparison.Ordinal)) { return text2; } string text3 = StripLocalizationToken(component.m_name); if (!string.IsNullOrWhiteSpace(text3)) { return text3; } } } if (text.StartsWith("$", StringComparison.Ordinal)) { Localization instance2 = Localization.instance; string text4 = ((instance2 != null) ? instance2.Localize(text) : null) ?? ""; if (!string.IsNullOrWhiteSpace(text4) && !string.Equals(text4, text, StringComparison.Ordinal)) { return text4; } string text5 = StripLocalizationToken(text); if (!string.IsNullOrWhiteSpace(text5)) { return text5; } } return text; } private static GameObject? FindCraftingStationPrefab(string configured) { string text = NormalizeStationName(configured); if (text.Length == 0) { return null; } GameObject[] array = new GameObject[4]; ZNetScene instance = ZNetScene.instance; array[0] = ((instance != null) ? instance.GetPrefab(configured) : null); ZNetScene instance2 = ZNetScene.instance; array[1] = ((instance2 != null) ? instance2.GetPrefab(Utils.GetPrefabName(configured)) : null); array[2] = PrefabManager.Instance.GetPrefab(configured); array[3] = PrefabManager.Instance.GetPrefab(Utils.GetPrefabName(configured)); GameObject[] array2 = (GameObject[])(object)array; foreach (GameObject val in array2) { if (IsMatchingCraftingStation(val, text)) { return val; } } if ((Object)(object)ZNetScene.instance != (Object)null) { foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if (IsMatchingCraftingStation(prefab, text)) { return prefab; } } } return null; } private static bool IsMatchingCraftingStation(GameObject? prefab, string wanted) { if (!Object.op_Implicit((Object)(object)prefab) || (Object)(object)prefab.GetComponent() == (Object)null) { return false; } Piece component = prefab.GetComponent(); if (!(NormalizeStationName(((Object)prefab).name) == wanted) && !(NormalizeStationName(Utils.GetPrefabName(((Object)prefab).name)) == wanted)) { if ((Object)(object)component != (Object)null) { return NormalizeStationName(component.m_name) == wanted; } return false; } return true; } private static string StripLocalizationToken(string value) { string text = (value ?? string.Empty).Trim(); if (text.StartsWith("$piece_", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(7); } else if (text.StartsWith("$item_", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(6); } else if (text.StartsWith("$", StringComparison.Ordinal)) { text = text.Substring(1); } text = text.Replace("_", " ").Trim(); if (text.Length != 0) { return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(text); } return value ?? string.Empty; } private static string FormatShortcut(KeyboardShortcut shortcut) { string text = ((object)(KeyboardShortcut)(ref shortcut)).ToString(); if (!string.IsNullOrWhiteSpace(text)) { return text.Replace(" + ", "+"); } return "Unbound"; } private static string FormatAdjustmentShortcutPair(string arrows) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0011: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut adjustmentModifierKey = DvergrCircletConfig.AdjustmentModifierKey; if ((int)((KeyboardShortcut)(ref adjustmentModifierKey)).MainKey == 0) { return arrows; } return FormatShortcut(adjustmentModifierKey) + " + " + arrows; } internal static bool IsDvergrCircletItem(ItemData? item) { if (item == null) { return false; } string text = (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : string.Empty); if (text.Equals("HelmetDverger", StringComparison.OrdinalIgnoreCase) || text.StartsWith("HelmetDverger", StringComparison.OrdinalIgnoreCase)) { return true; } string text2 = item.m_shared?.m_name ?? string.Empty; if (text2.IndexOf("helmet_dverger", StringComparison.OrdinalIgnoreCase) < 0) { if (text2.IndexOf("dverger", StringComparison.OrdinalIgnoreCase) >= 0) { if (text2.IndexOf("helmet", StringComparison.OrdinalIgnoreCase) < 0) { return text2.IndexOf("circlet", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } return false; } return true; } internal static bool TryGetEquippedDvergrCirclet(Player player, out ItemData? item) { item = null; if (!Object.op_Implicit((Object)(object)player)) { return false; } if (IsDvergrCircletItem(((Humanoid)player).m_helmetItem)) { item = ((Humanoid)player).m_helmetItem; return true; } if (InventorySlotsCompat.TryGetCustomEquippedItem(player, IsDvergrCircletItem, out item)) { return true; } return AzuExtendedPlayerInventoryCompat.TryGetCustomEquippedItem(player, IsDvergrCircletItem, out item); } private static ItemData? TryGetVisualHelmetItem(VisEquipment visEquipment) { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && (Object)(object)((Humanoid)localPlayer).m_visEquipment == (Object)(object)visEquipment && TryGetEquippedDvergrCirclet(localPlayer, out ItemData item)) { return item; } Player componentInParent = ((Component)visEquipment).GetComponentInParent(); if (Object.op_Implicit((Object)(object)componentInParent) && TryGetEquippedDvergrCirclet(componentInParent, out ItemData item2)) { return item2; } return null; } private static bool IsCircletLightOn(Player player, ItemData item) { TempLights.Clear(); CollectCircletLights(player, item, TempLights); foreach (Light tempLight in TempLights) { if (Object.op_Implicit((Object)(object)tempLight) && ((Behaviour)tempLight).enabled && ((Component)tempLight).gameObject.activeInHierarchy) { return true; } } return false; } internal static bool TryAppendFallbackLight(List output) { int count = output.Count; if ((Object)(object)_fallbackVisualRoot != (Object)null && Object.op_Implicit((Object)(object)_fallbackVisualRoot) && _fallbackVisualRoot.activeInHierarchy) { _fallbackVisualRoot.GetComponentsInChildren(true, output); } if ((Object)(object)_fallbackLight == (Object)null || !Object.op_Implicit((Object)(object)_fallbackLight) || !((Behaviour)_fallbackLight).enabled || !((Component)_fallbackLight).gameObject.activeInHierarchy) { return output.Count > count; } output.Add(_fallbackLight); return output.Count > count; } private static void CollectCircletLights(Player player, ItemData item, List output) { VisEquipment visEquipment = ((Humanoid)player).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment)) { CleanupFallbackVisuals(); return; } if (item == ((Humanoid)player).m_helmetItem && Object.op_Implicit((Object)(object)visEquipment.m_helmetItemInstance)) { visEquipment.m_helmetItemInstance.GetComponentsInChildren(true, output); } if (AzuExtendedPlayerInventoryCompat.TryGetCustomEquipVisualRoots(visEquipment, item, TempVisualRoots)) { foreach (GameObject tempVisualRoot in TempVisualRoots) { if (Object.op_Implicit((Object)(object)tempVisualRoot)) { tempVisualRoot.GetComponentsInChildren(true, output); } } } if (InventorySlotsCompat.TryGetCustomEquipmentVisualRoots(visEquipment, item, TempVisualRoots)) { foreach (GameObject tempVisualRoot2 in TempVisualRoots) { if (Object.op_Implicit((Object)(object)tempVisualRoot2)) { tempVisualRoot2.GetComponentsInChildren(true, output); } } } TryAppendFallbackLight(output); } private static void EnsureLocalCircletVisual(Player player, ItemData item, CircletState state) { VisEquipment visEquipment = ((Humanoid)player).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment)) { return; } int num = 0; if (item == ((Humanoid)player).m_helmetItem && Object.op_Implicit((Object)(object)visEquipment.m_helmetItemInstance)) { EnsureVisualComponent(visEquipment.m_helmetItemInstance, item); num++; } if (AzuExtendedPlayerInventoryCompat.TryGetCustomEquipVisualRoots(visEquipment, item, TempVisualRoots)) { foreach (GameObject tempVisualRoot in TempVisualRoots) { if (Object.op_Implicit((Object)(object)tempVisualRoot)) { EnsureVisualComponent(tempVisualRoot, item); num++; } } } if (InventorySlotsCompat.TryGetCustomEquipmentVisualRoots(visEquipment, item, TempVisualRoots)) { foreach (GameObject tempVisualRoot2 in TempVisualRoots) { if (Object.op_Implicit((Object)(object)tempVisualRoot2)) { EnsureVisualComponent(tempVisualRoot2, item); num++; } } } TempLights.Clear(); CollectCircletLights(player, item, TempLights); bool flag = TempLights.Any((Light light) => Object.op_Implicit((Object)(object)light) && (Object)(object)light != (Object)(object)_fallbackLight); if (num == 0 || !flag) { if (EnsureFallbackVisual(player, item)) { TempLights.Clear(); CollectCircletLights(player, item, TempLights); if (TempLights.Any((Light light) => Object.op_Implicit((Object)(object)light) && (Object)(object)light != (Object)(object)_fallbackLight)) { DisableFallbackLight(); return; } } UpdateFallbackLight(player, item, state); } else { DestroyFallbackVisual(); DisableFallbackLight(); } } private static void EnsureVisualComponent(GameObject root, ItemData item) { ZoneDvergrCircletVisual zoneDvergrCircletVisual = root.GetComponent() ?? root.AddComponent(); if (!zoneDvergrCircletVisual.IsFor(item)) { zoneDvergrCircletVisual.Initialize(item); } zoneDvergrCircletVisual.ApplyNow(); } private static void UpdateFallbackLight(Player player, ItemData item, CircletState state) { //IL_004d: 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_005d: 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) //IL_0068: 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_0077: 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_00ba: Unknown result type (might be due to invalid IL or missing references) EnsureFallbackLight(); if (!((Object)(object)_fallbackLight == (Object)null) && !((Object)(object)_fallbackLightObject == (Object)null)) { _fallbackLightItem = item; Transform val = ((Component)player).transform; if (TryGetHelmetTransform(player, out Transform helmetTransform) && (Object)(object)helmetTransform != (Object)null) { val = helmetTransform; } _fallbackLightObject.transform.position = val.position + val.up * 0.05f + val.forward * 0.28f; _fallbackLightObject.transform.rotation = val.rotation; _fallbackLight.type = (LightType)2; _fallbackLight.color = new Color(1f, 0.82f, 0.58f, 1f); _fallbackLight.intensity = 1.25f * state.IntensityMultiplier; _fallbackLight.range = 14f * state.RangeMultiplier; _fallbackLight.shadows = (LightShadows)2; ((Behaviour)_fallbackLight).enabled = Active && state.LightOn && item.m_durability > 0f; _fallbackLightObject.SetActive(((Behaviour)_fallbackLight).enabled); } } private static void EnsureFallbackLight() { //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) //IL_004a: Expected O, but got Unknown if (!((Object)(object)_fallbackLightObject != (Object)null) || !Object.op_Implicit((Object)(object)_fallbackLightObject) || !((Object)(object)_fallbackLight != (Object)null) || !Object.op_Implicit((Object)(object)_fallbackLight)) { _fallbackLightObject = new GameObject("HomesteadDvergrCircletFallbackLight") { hideFlags = (HideFlags)61 }; _fallbackLight = _fallbackLightObject.AddComponent(); _fallbackLightObject.SetActive(false); } } private static void DisableFallbackLight() { _fallbackLightItem = null; if ((Object)(object)_fallbackLight != (Object)null && Object.op_Implicit((Object)(object)_fallbackLight)) { ((Behaviour)_fallbackLight).enabled = false; } if ((Object)(object)_fallbackLightObject != (Object)null && Object.op_Implicit((Object)(object)_fallbackLightObject)) { _fallbackLightObject.SetActive(false); } } private static bool EnsureFallbackVisual(Player player, ItemData item) { if (!TryGetHelmetTransform(player, out Transform helmetTransform) || (Object)(object)helmetTransform == (Object)null) { return false; } if ((Object)(object)_fallbackVisualRoot != (Object)null && Object.op_Implicit((Object)(object)_fallbackVisualRoot) && _fallbackVisualItem == item) { _fallbackVisualRoot.SetActive(true); EnsureVisualComponent(_fallbackVisualRoot, item); return true; } DestroyFallbackVisual(); try { GameObject val = ((Humanoid)player).m_visEquipment.AttachItem(PrefabHash, 0, helmetTransform, false, false); if (!Object.op_Implicit((Object)(object)val)) { return false; } ((Object)val).name = "HomesteadDvergrCircletFallbackVisual"; ((Object)val).hideFlags = (HideFlags)52; _fallbackVisualRoot = val; _fallbackVisualItem = item; EnsureVisualComponent(val, item); return true; } catch (Exception ex) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogWarning((object)("Failed to attach fallback Dvergr circlet visual to helmet joint; using point light fallback. " + ex.GetType().Name + ": " + ex.Message)); } DestroyFallbackVisual(); return false; } } private static bool TryGetHelmetTransform(Player player, out Transform? helmetTransform) { helmetTransform = null; VisEquipment visEquipment = ((Humanoid)player).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !Object.op_Implicit((Object)(object)visEquipment.m_helmet)) { return false; } helmetTransform = visEquipment.m_helmet; return true; } private static void CleanupFallbackVisuals() { DestroyFallbackVisual(); DisableFallbackLight(); } private static void DestroyFallbackVisual() { _fallbackVisualItem = null; if ((Object)(object)_fallbackVisualRoot != (Object)null && Object.op_Implicit((Object)(object)_fallbackVisualRoot)) { Object.Destroy((Object)(object)_fallbackVisualRoot); } _fallbackVisualRoot = null; } private static void PublishLocalCircletState(Player player, ItemData? item, CircletState? state) { if (!Object.op_Implicit((Object)(object)player) || (Object)(object)((Character)player).m_nview == (Object)null || !((Character)player).m_nview.IsValid() || !((Character)player).m_nview.IsOwner()) { return; } ZDO zDO = ((Character)player).m_nview.GetZDO(); if (zDO != null) { if (!Active || item == null || !IsDvergrCircletItem(item)) { SetRemoteCircletZdo(zDO, 0, ""); return; } string serializedState = SerializeState(state ?? LoadState(item), item.m_durability > 0f, includeFuel: true); SetRemoteCircletZdo(zDO, PrefabHash, serializedState); } } private static void SetRemoteCircletZdo(ZDO zdo, int itemHash, string serializedState) { int num = ((!string.IsNullOrEmpty(serializedState)) ? StringExtensionMethods.GetStableHashCode(serializedState) : 0); if (zdo.GetInt(RemoteItemKey, 0) != itemHash) { zdo.Set(RemoteItemKey, itemHash, false); } if (zdo.GetString(RemoteStateKey, "") != serializedState) { zdo.Set(RemoteStateKey, serializedState); } if (zdo.GetInt(RemoteStateHashKey, 0) != num) { zdo.Set(RemoteStateHashKey, num, false); } } private static bool ShouldSyncRemoteVisuals() { return Active; } private static bool IsLocalVisEquipment(VisEquipment visEquipment) { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { return (Object)(object)((Humanoid)localPlayer).m_visEquipment == (Object)(object)visEquipment; } return false; } private static void EnsureRemoteVisualComponent(GameObject root, ZNetView nview, bool culled) { ZoneDvergrCircletVisual zoneDvergrCircletVisual = root.GetComponent() ?? root.AddComponent(); if (!zoneDvergrCircletVisual.IsRemoteFor(nview)) { zoneDvergrCircletVisual.InitializeRemote(nview); } zoneDvergrCircletVisual.SetRemoteCulled(culled); zoneDvergrCircletVisual.ApplyNow(); } private static bool TryGetRemoteCircletNview(VisEquipment visEquipment, out ZNetView? nview) { nview = null; if (!ShouldSyncRemoteVisuals() || !Object.op_Implicit((Object)(object)visEquipment) || !visEquipment.m_isPlayer || IsLocalVisEquipment(visEquipment) || (Object)(object)visEquipment.m_nview == (Object)null || !visEquipment.m_nview.IsValid()) { return false; } ZDO zDO = visEquipment.m_nview.GetZDO(); if (zDO == null || zDO.GetInt(RemoteItemKey, 0) != PrefabHash) { return false; } nview = visEquipment.m_nview; return true; } private static void CullRemoteVisualComponent(GameObject? root, ZNetView? nview) { if (Object.op_Implicit((Object)(object)root) && !((Object)(object)nview == (Object)null)) { ZoneDvergrCircletVisual component = root.GetComponent(); if ((Object)(object)component != (Object)null && component.IsRemoteFor(nview)) { component.SetRemoteCulled(culled: true); } } } private static CircletState LoadState(ItemData? item) { if (item == null || !item.m_customData.TryGetValue("sighsorry.Homestead.dvergr_circlet_state", out var value)) { return new CircletState(); } CircletState circletState = LoadStateFromString(value); circletState.HasFuel = item.m_durability > 0f; return circletState; } private static CircletState LoadRemoteState(ZNetView? nview) { if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return new CircletState { HasFuel = false }; } ZDO zDO = nview.GetZDO(); if (zDO == null || zDO.GetInt(RemoteItemKey, 0) != PrefabHash) { return new CircletState { HasFuel = false }; } return LoadStateFromString(zDO.GetString(RemoteStateKey, "")); } private static CircletState LoadStateFromString(string? serialized) { CircletState circletState = new CircletState(); if (serialized == null) { return circletState; } if (string.IsNullOrWhiteSpace(serialized)) { return circletState; } string[] array = serialized.Split(new char[1] { ';' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { '=' }, 2); if (array2.Length == 2) { string text = array2[0].Trim(); string text2 = array2[1].Trim(); float result; float result2; if (text.Equals("on", StringComparison.OrdinalIgnoreCase)) { circletState.LightOn = text2 == "1" || text2.Equals("true", StringComparison.OrdinalIgnoreCase); } else if (text.Equals("intensity", StringComparison.OrdinalIgnoreCase) && float.TryParse(text2, NumberStyles.Float, CultureInfo.InvariantCulture, out result)) { circletState.IntensityMultiplier = ClampAndRoundIntensityMultiplier(result); } else if (text.Equals("range", StringComparison.OrdinalIgnoreCase) && float.TryParse(text2, NumberStyles.Float, CultureInfo.InvariantCulture, out result2)) { circletState.RangeMultiplier = ClampAndRoundRangeMultiplier(result2); } else if ((text.Equals("fuel", StringComparison.OrdinalIgnoreCase) || text.Equals("active", StringComparison.OrdinalIgnoreCase)) && (text2 == "0" || text2.Equals("false", StringComparison.OrdinalIgnoreCase))) { circletState.HasFuel = false; } } } return circletState; } private static void SaveState(ItemData item, CircletState state) { state.IntensityMultiplier = ClampAndRoundIntensityMultiplier(state.IntensityMultiplier); state.RangeMultiplier = ClampAndRoundRangeMultiplier(state.RangeMultiplier); item.m_customData["sighsorry.Homestead.dvergr_circlet_state"] = SerializeState(state, hasFuel: true, includeFuel: false); } private static string SerializeState(CircletState state, bool hasFuel, bool includeFuel) { state.IntensityMultiplier = ClampAndRoundIntensityMultiplier(state.IntensityMultiplier); state.RangeMultiplier = ClampAndRoundRangeMultiplier(state.RangeMultiplier); string text = string.Format("on={0};intensity={1};range={2}", state.LightOn ? 1 : 0, state.IntensityMultiplier.ToString("0.##", CultureInfo.InvariantCulture), state.RangeMultiplier.ToString("0.##", CultureInfo.InvariantCulture)); if (includeFuel) { text += $";fuel={(hasFuel ? 1 : 0)}"; } return text; } private static float ClampAndRoundIntensityMultiplier(float value) { return ClampAndRoundMultiplier(value, DvergrCircletConfig.PerItemMaxIntensityMultiplier); } private static float ClampAndRoundRangeMultiplier(float value) { return ClampAndRoundMultiplier(value, DvergrCircletConfig.PerItemMaxRangeMultiplier); } private static float ClampAndRoundMultiplier(float value, float maxMultiplier) { float perItemAdjustmentStep = DvergrCircletConfig.PerItemAdjustmentStep; return Mathf.Clamp((perItemAdjustmentStep > 0f) ? (Mathf.Round(value / perItemAdjustmentStep) * perItemAdjustmentStep) : value, 1f, maxMultiplier); } private static void ResetRemoteVisualsForWorldSession() { ZoneDvergrCircletRemoteVisual[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (ZoneDvergrCircletRemoteVisual zoneDvergrCircletRemoteVisual in array) { if (Object.op_Implicit((Object)(object)zoneDvergrCircletRemoteVisual)) { Object.Destroy((Object)(object)zoneDvergrCircletRemoteVisual); } } ZoneDvergrCircletVisual[] array2 = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (ZoneDvergrCircletVisual zoneDvergrCircletVisual in array2) { if (Object.op_Implicit((Object)(object)zoneDvergrCircletVisual)) { Object.Destroy((Object)(object)zoneDvergrCircletVisual); } } } } internal sealed class ZoneBlueprintFile { public int Version { get; set; } = 1; public string Name { get; set; } = ""; public string Creator { get; set; } = ""; public string World { get; set; } = ""; public string SavedAt { get; set; } = ""; public float Radius { get; set; } public List Entries { get; set; } = new List(); public List TerrainContacts { get; set; } = new List(); } internal sealed class ZoneBlueprintEntry { public string Prefab { get; set; } = ""; public float[] LocalPos { get; set; } = new float[3]; public float[] LocalRot { get; set; } = new float[4]; public float[] Scale { get; set; } = new float[3]; public string Text { get; set; } = ""; } internal sealed class ZoneBlueprintTerrainContact { public float LocalX { get; set; } public float LocalY { get; set; } public float LocalZ { get; set; } } internal sealed class ZoneBlueprintRequirement { public string ItemName { get; set; } = ""; public string PrefabName { get; set; } = ""; public string DisplayName { get; set; } = ""; public int Amount { get; set; } } internal sealed class ZoneBlueprintCraftingStationRequirement { public string StationName { get; set; } = ""; public string PrefabName { get; set; } = ""; public string DisplayName { get; set; } = ""; } internal sealed class ZoneBlueprintStoreCatalog { public int Version { get; set; } = 1; public List Listings { get; set; } = new List(); public List Offers { get; set; } = new List(); public List Notifications { get; set; } = new List(); public List Balances { get; set; } = new List(); } internal sealed class ZoneBlueprintStoreListing { public string ListingId { get; set; } = ""; public string Name { get; set; } = ""; public string SellerName { get; set; } = ""; public long SellerPlayerId { get; set; } public string SellerPlatformId { get; set; } = ""; public string CreatedAt { get; set; } = ""; public string ExpiresAt { get; set; } = ""; public List PriceItems { get; set; } = new List(); public int EntryCount { get; set; } public int PurchaseCount { get; set; } public string BlueprintFile { get; set; } = ""; public string IconPngBase64 { get; set; } = ""; public bool Active { get; set; } = true; } internal sealed class ZoneBlueprintStoreBalance { public long SellerPlayerId { get; set; } public string SellerPlatformId { get; set; } = ""; public string SellerName { get; set; } = ""; public int Coins { get; set; } public List Materials { get; set; } = new List(); } internal sealed class ZoneBlueprintStoreOffer { public string OfferId { get; set; } = ""; public string ListingId { get; set; } = ""; public string BuyerName { get; set; } = ""; public long BuyerPlayerId { get; set; } public string BuyerPlatformId { get; set; } = ""; public string CreatedAt { get; set; } = ""; public string UpdatedAt { get; set; } = ""; public string Status { get; set; } = "Pending"; public List PriceItems { get; set; } = new List(); } internal static class ZoneBlueprintStoreOfferStatus { public const string Pending = "Pending"; public const string Accepted = "Accepted"; public const string Declined = "Declined"; public const string Deleted = "Deleted"; } internal sealed class ZoneBlueprintStoreNotification { public string NotificationId { get; set; } = ""; public string Type { get; set; } = ""; public string RecipientPlatformId { get; set; } = ""; public long RecipientPlayerId { get; set; } public string RecipientName { get; set; } = ""; public string ActorName { get; set; } = ""; public string ListingId { get; set; } = ""; public string ListingName { get; set; } = ""; public string OfferId { get; set; } = ""; public string Message { get; set; } = ""; public string CreatedAt { get; set; } = ""; public bool Read { get; set; } public List ReadByPlatformIds { get; set; } = new List(); public List ReadByPlayerIds { get; set; } = new List(); } internal static class ZoneBlueprintStoreNotificationType { public const string NewListing = "NewListing"; public const string OfferReceived = "OfferReceived"; public const string OfferAccepted = "OfferAccepted"; public const string OfferDeclined = "OfferDeclined"; public const string BlueprintPurchased = "BlueprintPurchased"; } internal sealed class ZoneBlueprintStoreListingSummaryDto { public string ListingId { get; set; } = ""; public string Name { get; set; } = ""; public string SellerName { get; set; } = ""; public List PriceItems { get; set; } = new List(); public int PurchaseCount { get; set; } public int OfferCount { get; set; } public bool CanDelist { get; set; } public bool CanManage { get; set; } } internal sealed class ZoneBlueprintStoreListingIconDto { public string ListingId { get; set; } = ""; public string IconPngBase64 { get; set; } = ""; } internal sealed class ZoneBlueprintStoreOfferDto { public string OfferId { get; set; } = ""; public string ListingId { get; set; } = ""; public string BuyerName { get; set; } = ""; public List PriceItems { get; set; } = new List(); public string PriceText { get; set; } = ""; public string Status { get; set; } = ""; public bool CanAccept { get; set; } public bool CanDecline { get; set; } public bool CanDelete { get; set; } public bool CanBuy { get; set; } } internal sealed class ZoneBlueprintStoreNotificationDto { public string NotificationId { get; set; } = ""; public string Type { get; set; } = ""; public string ActorName { get; set; } = ""; public string ListingId { get; set; } = ""; public string ListingName { get; set; } = ""; public string OfferId { get; set; } = ""; public string Message { get; set; } = ""; public string CreatedAt { get; set; } = ""; public bool Read { get; set; } } internal sealed class ZoneBlueprintStorePriceItem { public string ItemName { get; set; } = ""; public string PrefabName { get; set; } = ""; public string DisplayName { get; set; } = ""; public int Amount { get; set; } } internal static class ZoneBlueprintStoreRpcType { public const string Error = "error"; public const string List = "list"; public const string PriceChest = "price_chest"; public const string Publish = "publish"; public const string Preview = "preview"; public const string PreviewRestore = "preview_restore"; public const string Buy = "buy"; public const string ConfirmPurchase = "confirm"; public const string ConfirmListing = "confirm_listing"; public const string Delist = "delist"; public const string EditPrice = "edit_price"; public const string CreateOffer = "create_offer"; public const string ListOffers = "list_offers"; public const string DecideOffer = "decide_offer"; public const string DeleteOffer = "delete_offer"; public const string Notify = "notify"; public const string GetNotifications = "get_notifications"; public const string RecentNotifications = "recent_notifications"; public const string ReadNotifications = "read_notifications"; public const string SyncHidden = "sync_hidden"; public const string Withdraw = "withdraw"; public const string PurchaseComplete = "purchase_complete"; public const string WithdrawComplete = "withdraw_complete"; } internal sealed class ZoneBlueprintStoreRpcEnvelope : IZoneBlueprintRpcEnvelope { public string Type { get; set; } = ""; public string PayloadYaml { get; set; } = ""; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); } internal sealed class ZoneBlueprintStoreTransformPayload { public float[] Pos { get; set; } = new float[3]; public float[] Rot { get; set; } = new float[4]; } internal sealed class ZoneBlueprintStoreListRequest { public int RequestId { get; set; } public int Offset { get; set; } public int Limit { get; set; } public bool ShowHidden { get; set; } public bool IncludeNotifications { get; set; } public bool IconsOnly { get; set; } public List IconListingIds { get; set; } = new List(); public int FirstIconCount { get; set; } = 6; } internal sealed class ZoneBlueprintStoreListResponse { public bool Success { get; set; } public string Message { get; set; } = ""; public int RequestId { get; set; } public int TotalListings { get; set; } public int Offset { get; set; } public int Limit { get; set; } public int HiddenListings { get; set; } public bool HasMore { get; set; } public bool HasWithdrawableBalance { get; set; } public bool IconsOnly { get; set; } public List Listings { get; set; } = new List(); public List Icons { get; set; } = new List(); public List Notifications { get; set; } = new List(); } internal sealed class ZoneBlueprintStoreSyncHiddenRequest { public List HiddenListingIds { get; set; } = new List(); } internal interface IZoneBlueprintPayloadCarrier { string BlueprintEncoding { get; set; } byte[] BlueprintPayload { get; set; } } internal interface IZoneBlueprintRpcEnvelope { string Type { get; set; } string PayloadYaml { get; set; } byte[] BlueprintPayload { get; set; } } internal sealed class ZoneBlueprintStorePriceChestRequest : IZoneBlueprintPayloadCarrier { public string Name { get; set; } = ""; public string BlueprintEncoding { get; set; } = "gzip"; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); public string IconPngBase64 { get; set; } = ""; public ZoneBlueprintStoreTransformPayload? Target { get; set; } public ZoneBlueprintStoreTransformPayload? PreviewAnchor { get; set; } } internal sealed class ZoneBlueprintStorePriceChestResponse { public bool Success { get; set; } public string Message { get; set; } = ""; public string ListingId { get; set; } = ""; public string Name { get; set; } = ""; public ZoneBlueprintStoreTransformPayload? Chest { get; set; } } internal sealed class ZoneBlueprintStorePublishRequest : IZoneBlueprintPayloadCarrier { public string Name { get; set; } = ""; public List PriceItems { get; set; } = new List(); public string BlueprintEncoding { get; set; } = "gzip"; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); public string IconPngBase64 { get; set; } = ""; } internal sealed class ZoneBlueprintStoreStatusResponse { public bool Success { get; set; } public string Message { get; set; } = ""; public string ListingId { get; set; } = ""; public bool RemoveListing { get; set; } public ZoneBlueprintStoreListingSummaryDto? Listing { get; set; } } internal sealed class ZoneBlueprintStorePreviewRequest { public string ListingId { get; set; } = ""; public string OfferId { get; set; } = ""; } internal sealed class ZoneBlueprintStorePreviewResponse : IZoneBlueprintPayloadCarrier { public bool Success { get; set; } public string Message { get; set; } = ""; public string ListingId { get; set; } = ""; public string OfferId { get; set; } = ""; public string Name { get; set; } = ""; public string BlueprintEncoding { get; set; } = "gzip"; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); } internal sealed class ZoneBlueprintStorePreviewRestoreRequest { public string Mode { get; set; } = ""; public string ListingId { get; set; } = ""; public string Name { get; set; } = ""; public string BlueprintFile { get; set; } = ""; } internal sealed class ZoneBlueprintStorePreviewRestoreResponse : IZoneBlueprintPayloadCarrier { public bool Success { get; set; } public string Message { get; set; } = ""; public string Mode { get; set; } = ""; public string ListingId { get; set; } = ""; public string Name { get; set; } = ""; public string BlueprintFile { get; set; } = ""; public string BlueprintEncoding { get; set; } = "gzip"; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); } internal sealed class ZoneBlueprintStoreBuyRequest { public string ListingId { get; set; } = ""; public string OfferId { get; set; } = ""; public ZoneBlueprintStoreTransformPayload? Target { get; set; } public ZoneBlueprintStoreTransformPayload? PreviewAnchor { get; set; } } internal sealed class ZoneBlueprintStoreBuyResponse { public bool Success { get; set; } public string Message { get; set; } = ""; public string ListingId { get; set; } = ""; public string OfferId { get; set; } = ""; public string Name { get; set; } = ""; public ZoneBlueprintStoreTransformPayload? Chest { get; set; } } internal sealed class ZoneBlueprintStoreConfirmPurchaseRequest { public string ListingId { get; set; } = ""; public string OfferId { get; set; } = ""; } internal sealed class ZoneBlueprintStoreConfirmListingRequest { public string ListingId { get; set; } = ""; public List PriceItems { get; set; } = new List(); } internal sealed class ZoneBlueprintStoreConfirmListingResponse { public bool Success { get; set; } public string Message { get; set; } = ""; public string ListingId { get; set; } = ""; } internal sealed class ZoneBlueprintStoreDelistRequest { public string ListingId { get; set; } = ""; } internal sealed class ZoneBlueprintStoreEditPriceRequest { public string ListingId { get; set; } = ""; public List PriceItems { get; set; } = new List(); } internal sealed class ZoneBlueprintStoreCreateOfferRequest { public string ListingId { get; set; } = ""; public List PriceItems { get; set; } = new List(); } internal sealed class ZoneBlueprintStoreListOffersRequest { public string ListingId { get; set; } = ""; } internal sealed class ZoneBlueprintStoreListOffersResponse { public bool Success { get; set; } public string Message { get; set; } = ""; public string ListingId { get; set; } = ""; public string ListingName { get; set; } = ""; public bool CanManage { get; set; } public List Offers { get; set; } = new List(); } internal sealed class ZoneBlueprintStoreDecideOfferRequest { public string ListingId { get; set; } = ""; public string OfferId { get; set; } = ""; public string Decision { get; set; } = ""; } internal sealed class ZoneBlueprintStoreDeleteOfferRequest { public string ListingId { get; set; } = ""; public string OfferId { get; set; } = ""; } internal sealed class ZoneBlueprintStoreNotificationResponse { public List Notifications { get; set; } = new List(); } internal sealed class ZoneBlueprintStoreGetNotificationsRequest { } internal sealed class ZoneBlueprintStoreRecentNotificationsRequest { public int Limit { get; set; } = 32; } internal sealed class ZoneBlueprintStoreReadNotificationsRequest { public List NotificationIds { get; set; } = new List(); } internal sealed class ZoneBlueprintStorePurchaseCompleteResponse : IZoneBlueprintPayloadCarrier { public bool Success { get; set; } public string Message { get; set; } = ""; public string ListingId { get; set; } = ""; public string OfferId { get; set; } = ""; public string Name { get; set; } = ""; public string BlueprintEncoding { get; set; } = "gzip"; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); } internal sealed class ZoneBlueprintStoreWithdrawRequest { public ZoneBlueprintStoreTransformPayload? Target { get; set; } } internal sealed class ZoneBlueprintStoreWithdrawResponse { public bool Success { get; set; } public string Message { get; set; } = ""; public List Chests { get; set; } = new List(); } internal static class ZoneBlueprintPlanRpcType { public const string Place = "place"; public const string Preview = "preview"; } internal sealed class ZoneBlueprintPlanRpcEnvelope : IZoneBlueprintRpcEnvelope { public string Type { get; set; } = ""; public string PayloadYaml { get; set; } = ""; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); } internal sealed class ZoneBlueprintPlanPlaceRequest : IZoneBlueprintPayloadCarrier { public string Name { get; set; } = ""; public string BlueprintEncoding { get; set; } = "gzip"; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); public ZoneBlueprintStoreTransformPayload? Anchor { get; set; } public ZoneBlueprintStoreTransformPayload? Chest { get; set; } } internal sealed class ZoneBlueprintPlanPlaceResponse : IZoneBlueprintPayloadCarrier { public bool Success { get; set; } public string Message { get; set; } = ""; public string RequestedName { get; set; } = ""; public string BlueprintName { get; set; } = ""; public ZoneBlueprintStoreTransformPayload? Chest { get; set; } public string BlueprintEncoding { get; set; } = "gzip"; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); } internal sealed class ZoneBlueprintPlanPreviewRequest { public string Name { get; set; } = ""; } internal sealed class ZoneBlueprintPlanPreviewResponse : IZoneBlueprintPayloadCarrier { public bool Success { get; set; } public string Message { get; set; } = ""; public string Name { get; set; } = ""; public string BlueprintEncoding { get; set; } = "gzip"; [YamlIgnore] public byte[] BlueprintPayload { get; set; } = Array.Empty(); } internal sealed class ZoneBlueprintGhostOwner { private sealed class ZoneBlueprintGhostMaterialSet : MonoBehaviour { private readonly List _materials = new List(); private readonly List _renderers = new List(); private Material? _primary; private bool _captured; public Material Apply(Color color) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) CaptureOriginalMaterials(); Clear(); foreach (RendererSnapshot renderer2 in _renderers) { Renderer renderer = renderer2.Renderer; if ((Object)(object)renderer == (Object)null) { continue; } Material[] materials = renderer2.Materials; Material[] array = (Material[])(object)new Material[materials.Length]; for (int i = 0; i < materials.Length; i++) { Material val = (array[i] = CreateGhostMaterial(materials[i], color)); _materials.Add(val); if (_primary == null) { _primary = val; } } renderer.sharedMaterials = array; renderer.shadowCastingMode = (ShadowCastingMode)0; renderer.receiveShadows = false; } if (_primary == null) { _primary = CreateGhostMaterial(null, color); } if (!_materials.Contains(_primary)) { _materials.Add(_primary); } return _primary; } public void UpdateColor(Color color) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) foreach (Material material in _materials) { if ((Object)(object)material != (Object)null) { material.color = color; } } } private void OnDestroy() { Clear(); } private void Clear() { foreach (Material material in _materials) { if ((Object)(object)material != (Object)null) { Object.Destroy((Object)(object)material); } } _materials.Clear(); _primary = null; } private void CaptureOriginalMaterials() { if (!_captured) { Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { _renderers.Add(new RendererSnapshot(val, val.sharedMaterials)); } _captured = true; } } } private readonly struct RendererSnapshot { public Renderer Renderer { get; } public Material[] Materials { get; } public RendererSnapshot(Renderer renderer, Material[] materials) { Renderer = renderer; Materials = materials; } } public GameObject? Root { get; private set; } public Material? Material { get; private set; } public bool HasRoot { get { if ((Object)(object)Root != (Object)null) { return Object.op_Implicit((Object)(object)Root); } return false; } } public GameObject CreateBlueprint(ZoneBlueprintFile blueprint, string objectName, Vector3 position, Quaternion rotation, Transform? parent = null) { //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) Destroy(); Root = ZoneBlueprintVisuals.CreateBlueprintVisualRoot(blueprint, objectName); SetTransform(position, rotation); if ((Object)(object)parent != (Object)null) { Root.transform.SetParent(parent, true); } return Root; } public GameObject CreateEmpty(string objectName) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown Destroy(); Root = new GameObject(objectName); return Root; } public void Adopt(GameObject root, Material? material) { Destroy(); Root = root; Material = material; } public void SetTransform(Vector3 position, Quaternion rotation) { //IL_0014: 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) if (HasRoot) { Root.transform.position = position; Root.transform.rotation = rotation; } } public Material ApplyMaterial(Color color) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) Material = ApplyMaterial(Root, color, Material); return Material; } public Material ApplyMaterial(GameObject target, Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Material = ApplyMaterial(target, color, Material); return Material; } public void UpdateMaterialColor(Color color) { //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) UpdateMaterialColor(Root, color); if ((Object)(object)Material != (Object)null) { Material.color = color; } } public void Destroy() { if ((Object)(object)Root != (Object)null && Object.op_Implicit((Object)(object)Root)) { Object.Destroy((Object)(object)Root); } if ((Object)(object)Material != (Object)null) { Object.Destroy((Object)(object)Material); } Root = null; Material = null; } public static Material ApplyMaterial(GameObject? root, Color color, Material? material = null) { //IL_0036: 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) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { if (material == null) { material = CreateGhostMaterial(null, color); } material.color = color; return material; } ZoneBlueprintGhostMaterialSet zoneBlueprintGhostMaterialSet = root.GetComponent(); if ((Object)(object)zoneBlueprintGhostMaterialSet == (Object)null) { zoneBlueprintGhostMaterialSet = root.AddComponent(); } return zoneBlueprintGhostMaterialSet.Apply(color); } public static void UpdateMaterialColor(GameObject? root, Color color) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)root == (Object)null)) { ZoneBlueprintGhostMaterialSet[] componentsInChildren = root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].UpdateColor(color); } } } private static Material CreateGhostMaterial(Material? source, Color color) { //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) //IL_006d: 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_0075: Expected O, but got Unknown Material val = new Material(Shader.Find("Standard") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Transparent") ?? Shader.Find("Unlit/Texture") ?? Shader.Find("Unlit/Color")) { name = (((Object)(object)source != (Object)null) ? ("HomesteadGhost_" + ((Object)source).name) : "HomesteadGhost"), color = color }; Texture val2 = GetTexture(source, "_MainTex") ?? GetTexture(source, "_BaseMap") ?? GetTexture(source, "_MainTexture") ?? GetTexture(source, "_DiffuseTex"); if ((Object)(object)val2 != (Object)null && val.HasProperty("_MainTex")) { val.SetTexture("_MainTex", val2); CopyTextureTransform(source, val, "_MainTex"); } Texture texture = GetTexture(source, "_BumpMap"); if ((Object)(object)texture != (Object)null && val.HasProperty("_BumpMap")) { val.SetTexture("_BumpMap", texture); val.EnableKeyword("_NORMALMAP"); } ConfigureTransparency(val); return val; } private static Texture? GetTexture(Material? source, string property) { if (!((Object)(object)source != (Object)null) || !source.HasProperty(property)) { return null; } return source.GetTexture(property); } private static void CopyTextureTransform(Material? source, Material target, string property) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && source.HasProperty(property) && target.HasProperty(property)) { target.SetTextureScale(property, source.GetTextureScale(property)); target.SetTextureOffset(property, source.GetTextureOffset(property)); } } private static void ConfigureTransparency(Material material) { if (material.HasProperty("_Mode")) { material.SetFloat("_Mode", 3f); } if (material.HasProperty("_SrcBlend")) { material.SetInt("_SrcBlend", 5); } if (material.HasProperty("_DstBlend")) { material.SetInt("_DstBlend", 10); } if (material.HasProperty("_ZWrite")) { material.SetInt("_ZWrite", 0); } material.DisableKeyword("_ALPHATEST_ON"); material.EnableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; } } internal static class ZoneBlueprintNetworkPayload { private readonly struct QueuedWork { public string Label { get; } public ManualLogSource Logger { get; } public long Sender { get; } public int EstimatedBytes { get; } public Action Execute { get; } public QueuedWork(string label, ManualLogSource logger, long sender, int estimatedBytes, Action execute) { Label = label; Logger = logger; Sender = sender; EstimatedBytes = estimatedBytes; Execute = execute; } } public readonly struct RawEnvelopePayload { public byte[] CompressedEnvelope { get; } public byte[] BlueprintPayload { get; } public int MaxOutputBytes { get; } public RawEnvelopePayload(byte[] compressedEnvelope, byte[] blueprintPayload, int maxOutputBytes) { CompressedEnvelope = compressedEnvelope ?? Array.Empty(); BlueprintPayload = blueprintPayload ?? Array.Empty(); MaxOutputBytes = Math.Max(1, maxOutputBytes); } } private readonly struct IngressWindow { public float StartedAt { get; } public int Count { get; } public IngressWindow(float startedAt, int count) { StartedAt = startedAt; Count = count; } } public const string GzipEncoding = "gzip"; private const int MaxEnvelopeOverheadBytes = 524288; private const int MaxCompressedEnvelopeBytes = 8388608; private const int MaxQueuedWorkItems = 32; private const int MaxQueuedWorkItemsPerSender = 4; private const int MaxIngressRequestsPerSender = 12; private const float IngressWindowSeconds = 2f; private const float IngressCleanupSeconds = 60f; private static readonly Queue WorkQueue = new Queue(); private static readonly Dictionary IngressBySender = new Dictionary(); private static int _queuedBytes; private static float _nextIngressCleanup; public static int MaxUploadEnvelopeBytes => Math.Max(1048576, BlueprintConfig.NetworkSettings.MaxIconBytes + 524288); private static int MaxGeneralEnvelopeBytes => Math.Max(16777216, MaxUploadEnvelopeBytes); private static int MaxCompressedBlueprintPayloadBytes => Math.Max(1048576, BlueprintConfig.NetworkSettings.MaxUploadBytes); private static int MaxGeneralBlueprintBytes => Math.Max(16777216, BlueprintConfig.NetworkSettings.MaxUploadBytes); private static int MaxQueuedPayloadBytes => Math.Max(4194304, BlueprintConfig.NetworkSettings.MaxUploadBytes * 4); public static void Update() { if (WorkQueue.Count == 0) { return; } QueuedWork queuedWork = WorkQueue.Dequeue(); _queuedBytes = Math.Max(0, _queuedBytes - queuedWork.EstimatedBytes); try { queuedWork.Execute(); } catch (Exception arg) { ManualLogSource logger = queuedWork.Logger; if (logger != null) { logger.LogError((object)$"{queuedWork.Label} failed: {arg}"); } } } public static void ResetForWorldSession() { WorkQueue.Clear(); _queuedBytes = 0; IngressBySender.Clear(); _nextIngressCleanup = 0f; } public static bool TryEnqueue(string label, ManualLogSource logger, long sender, int estimatedBytes, Action execute, out string reason) { reason = ""; estimatedBytes = Math.Max(1, estimatedBytes); if (WorkQueue.Count >= 32) { reason = HomesteadLocalization.Format("hs_blueprint_rpc_queue_busy", WorkQueue.Count, 32); return false; } if (sender != 0L && WorkQueue.Count((QueuedWork item) => item.Sender == sender) >= 4) { reason = HomesteadLocalization.Format("hs_blueprint_rpc_queue_busy_player", 4); return false; } int maxQueuedPayloadBytes = MaxQueuedPayloadBytes; if (_queuedBytes + estimatedBytes > maxQueuedPayloadBytes) { reason = HomesteadLocalization.Format("hs_blueprint_rpc_queue_full", FormatBytes(_queuedBytes), FormatBytes(maxQueuedPayloadBytes)); return false; } WorkQueue.Enqueue(new QueuedWork(label, logger, sender, estimatedBytes, execute)); _queuedBytes += estimatedBytes; return true; } public static bool TryReserveIngress(long sender, out string reason) { reason = ""; if (sender == 0L) { return true; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup >= _nextIngressCleanup) { _nextIngressCleanup = realtimeSinceStartup + 60f; List list = null; foreach (KeyValuePair item in IngressBySender) { if (!(realtimeSinceStartup - item.Value.StartedAt <= 60f)) { if (list == null) { list = new List(); } list.Add(item.Key); } } if (list != null) { foreach (long item2 in list) { IngressBySender.Remove(item2); } } } if (!IngressBySender.TryGetValue(sender, out var value) || realtimeSinceStartup - value.StartedAt >= 2f) { IngressBySender[sender] = new IngressWindow(realtimeSinceStartup, 1); return true; } if (value.Count >= 12) { reason = HomesteadLocalization.Format("hs_blueprint_rpc_ingress_busy_player", 12, 2f); return false; } IngressBySender[sender] = new IngressWindow(value.StartedAt, value.Count + 1); return true; } public static void WriteEnvelope(ZPackage package, string yaml, byte[]? blueprintPayload = null) { package.Write(CompressUtf8(yaml)); bool flag = blueprintPayload != null && blueprintPayload.Length > 0; package.Write(flag); if (flag) { package.Write(blueprintPayload); } } public static string ReadEnvelope(ZPackage package) { byte[] blueprintPayload; return ReadEnvelope(package, out blueprintPayload, MaxGeneralEnvelopeBytes); } public static string ReadEnvelope(ZPackage package, int maxOutputBytes) { byte[] blueprintPayload; return ReadEnvelope(package, out blueprintPayload, maxOutputBytes); } public static string ReadEnvelope(ZPackage package, out byte[] blueprintPayload) { return ReadEnvelope(package, out blueprintPayload, MaxGeneralEnvelopeBytes); } public static string ReadEnvelope(ZPackage package, out byte[] blueprintPayload, int maxOutputBytes) { return ReadEnvelope(ReadRawEnvelope(package, maxOutputBytes), out blueprintPayload); } public static RawEnvelopePayload ReadRawEnvelope(ZPackage package, int maxOutputBytes) { byte[] array = package.ReadByteArray().ToArray(); if (array.Length > 8388608) { throw new InvalidDataException(HomesteadLocalization.Format("hs_rpc_payload_too_large_compressed", FormatBytes(array.Length))); } byte[] array2 = Array.Empty(); if (package.ReadBool()) { array2 = package.ReadByteArray().ToArray(); if (array2.Length > MaxCompressedBlueprintPayloadBytes) { throw new InvalidDataException(HomesteadLocalization.Format("hs_blueprint_payload_too_large_throw", FormatBytes(array2.Length))); } } return new RawEnvelopePayload(array, array2, maxOutputBytes); } public static string ReadEnvelope(RawEnvelopePayload raw, out byte[] blueprintPayload) { blueprintPayload = raw.BlueprintPayload; return DecompressUtf8(raw.CompressedEnvelope, raw.MaxOutputBytes); } public static bool TryCreateBlueprintPayload(string blueprintText, bool enforceUploadLimit, out byte[] payload, out string reason) { payload = Array.Empty(); if (enforceUploadLimit && !TryValidateBlueprintTextSize(blueprintText, out reason)) { return false; } payload = CompressUtf8(blueprintText ?? ""); if (payload.Length > MaxCompressedBlueprintPayloadBytes) { reason = HomesteadLocalization.Format("hs_blueprint_payload_too_large_compressed", FormatBytes(payload.Length), FormatBytes(MaxCompressedBlueprintPayloadBytes)); payload = Array.Empty(); return false; } reason = ""; return true; } public static int EstimateQueuedBytes(string envelopeYaml, byte[] blueprintPayload) { long num = Encoding.UTF8.GetByteCount(envelopeYaml ?? "") + ((blueprintPayload != null) ? blueprintPayload.Length : 0); if (num < int.MaxValue) { return Math.Max(1, (int)num); } return int.MaxValue; } public static int EstimateQueuedBytes(RawEnvelopePayload raw) { long num = Math.Min(raw.MaxOutputBytes, Math.Max((long)raw.CompressedEnvelope.Length + 65536L, (long)raw.CompressedEnvelope.Length * 8L)) + raw.BlueprintPayload.Length; if (num < int.MaxValue) { return Math.Max(1, (int)num); } return int.MaxValue; } public static TEnvelope CreateEnvelope(string type, TPayload payload) where TEnvelope : IZoneBlueprintRpcEnvelope, new() { TEnvelope val = new TEnvelope { Type = type, PayloadYaml = HomesteadYaml.Serialize(payload) }; TEnvelope result = val; if ((object)payload is IZoneBlueprintPayloadCarrier zoneBlueprintPayloadCarrier && zoneBlueprintPayloadCarrier.BlueprintPayload.Length != 0) { ref TEnvelope reference = ref result; val = default(TEnvelope); if (val == null) { val = reference; reference = ref val; } reference.BlueprintPayload = zoneBlueprintPayloadCarrier.BlueprintPayload; } return result; } public static TPayload ReadPayload(TEnvelope envelope) where TEnvelope : IZoneBlueprintRpcEnvelope { TPayload val = HomesteadYaml.Deserialize(envelope.PayloadYaml); if ((object)val is IZoneBlueprintPayloadCarrier zoneBlueprintPayloadCarrier && envelope.BlueprintPayload.Length != 0) { zoneBlueprintPayloadCarrier.BlueprintPayload = envelope.BlueprintPayload; } return val; } public static bool TryDeserializeBlueprintUpload(byte[] payload, string encoding, out ZoneBlueprintFile blueprint, out string reason) { blueprint = null; if (!TryDecodeBlueprintPayloadToText(payload, encoding, BlueprintConfig.NetworkSettings.MaxUploadBytes, out string blueprintText, out reason)) { return false; } try { blueprint = ZoneBlueprintFileFormat.Deserialize(blueprintText); } catch (Exception ex) { reason = HomesteadLocalization.Format("hs_blueprint_payload_invalid", ex.Message); return false; } return true; } public static bool TryDeserializeBlueprintPayload(byte[] payload, string encoding, out ZoneBlueprintFile blueprint, out string reason) { blueprint = null; if (!TryDecodeBlueprintPayloadToText(payload, encoding, MaxGeneralBlueprintBytes, out string blueprintText, out reason)) { return false; } try { blueprint = ZoneBlueprintFileFormat.Deserialize(blueprintText); } catch (Exception ex) { reason = HomesteadLocalization.Format("hs_blueprint_payload_invalid", ex.Message); return false; } return true; } public static bool TryDecodeBlueprintPayloadToText(byte[] payload, string encoding, out string blueprintText, out string reason) { return TryDecodeBlueprintPayloadToText(payload, encoding, MaxGeneralBlueprintBytes, out blueprintText, out reason); } public static bool TryDecodeBlueprintPayloadToText(byte[] payload, string encoding, int maxOutputBytes, out string blueprintText, out string reason) { blueprintText = ""; reason = ""; if (payload == null || payload.Length == 0) { reason = HomesteadLocalization.Text("hs_blueprint_payload_missing"); return false; } if (payload.Length > MaxCompressedBlueprintPayloadBytes) { reason = HomesteadLocalization.Format("hs_blueprint_payload_too_large_compressed", FormatBytes(payload.Length), FormatBytes(MaxCompressedBlueprintPayloadBytes)); return false; } if (!string.Equals(encoding, "gzip", StringComparison.OrdinalIgnoreCase)) { reason = HomesteadLocalization.Format("hs_blueprint_payload_encoding_unsupported", encoding); return false; } try { blueprintText = DecompressUtf8(payload, maxOutputBytes); return true; } catch (Exception ex) { reason = HomesteadLocalization.Format("hs_blueprint_payload_invalid", ex.Message); return false; } } public static bool TryCreatePreviewText(ZoneBlueprintFile source, out string previewText, out string reason) { previewText = ""; ZoneBlueprintFile blueprint = ZoneBlueprintStorePreviewPayload.CreatePreviewBlueprint(source); previewText = ZoneBlueprintFileFormat.Serialize(blueprint); int byteCount = Encoding.UTF8.GetByteCount(previewText); int maxUploadBytes = BlueprintConfig.NetworkSettings.MaxUploadBytes; if (byteCount > maxUploadBytes) { reason = HomesteadLocalization.Format("hs_blueprint_preview_payload_too_large", FormatBytes(byteCount), FormatBytes(maxUploadBytes)); previewText = ""; return false; } reason = ""; return true; } public static bool TryCreatePreviewPayload(ZoneBlueprintFile source, out byte[] payload, out string reason) { payload = Array.Empty(); if (!TryCreatePreviewText(source, out string previewText, out reason)) { return false; } return TryCreateBlueprintPayload(previewText, enforceUploadLimit: false, out payload, out reason); } public static bool TryValidateIconBase64(string payload, out string reason) { reason = ""; if (string.IsNullOrWhiteSpace(payload)) { return true; } int maxIconBytes = BlueprintConfig.NetworkSettings.MaxIconBytes; if (maxIconBytes <= 0) { reason = HomesteadLocalization.Text("hs_store_icon_upload_disabled"); return false; } int num = EstimateBase64Bytes(payload); if (num > maxIconBytes) { reason = HomesteadLocalization.Format("hs_store_icon_too_large", FormatBytes(num), FormatBytes(maxIconBytes)); return false; } try { byte[] array = Convert.FromBase64String(payload); if (array.Length > maxIconBytes) { reason = HomesteadLocalization.Format("hs_store_icon_too_large", FormatBytes(array.Length), FormatBytes(maxIconBytes)); return false; } } catch (Exception ex) { reason = HomesteadLocalization.Format("hs_store_icon_payload_invalid", ex.Message); return false; } return true; } public static bool ShouldSendIconBase64(string payload) { if (!string.IsNullOrWhiteSpace(payload)) { if (BlueprintConfig.NetworkSettings.MaxIconBytes > 0) { return EstimateBase64Bytes(payload) <= BlueprintConfig.NetworkSettings.MaxIconBytes; } return false; } return true; } public static bool TryValidateBlueprintTextSize(string blueprintText, out string reason) { reason = ""; int byteCount = Encoding.UTF8.GetByteCount(blueprintText ?? ""); int maxUploadBytes = BlueprintConfig.NetworkSettings.MaxUploadBytes; if (byteCount > maxUploadBytes) { reason = HomesteadLocalization.Format("hs_blueprint_upload_too_large", FormatBytes(byteCount), FormatBytes(maxUploadBytes)); return false; } return true; } public static string FormatBytes(int bytes) { if (bytes >= 1048576) { return $"{(float)bytes / 1024f / 1024f:0.##} MB"; } return $"{Mathf.CeilToInt((float)bytes / 1024f)} KB"; } private static byte[] CompressUtf8(string value) { byte[] bytes = Encoding.UTF8.GetBytes(value ?? ""); using MemoryStream memoryStream = new MemoryStream(); using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Compress)) { gZipStream.Write(bytes, 0, bytes.Length); } return memoryStream.ToArray(); } private static string DecompressUtf8(byte[] compressed, int maxOutputBytes) { using MemoryStream stream = new MemoryStream(compressed); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[16384]; int count; while ((count = gZipStream.Read(array, 0, array.Length)) > 0) { memoryStream.Write(array, 0, count); if (memoryStream.Length > maxOutputBytes) { throw new InvalidDataException(HomesteadLocalization.Format("hs_rpc_payload_too_large_uncompressed", FormatBytes((int)memoryStream.Length))); } } return Encoding.UTF8.GetString(memoryStream.ToArray()); } private static int EstimateBase64Bytes(string payload) { string text = payload.Trim(); int num = 0; if (text.EndsWith("==", StringComparison.Ordinal)) { num = 2; } else if (text.EndsWith("=", StringComparison.Ordinal)) { num = 1; } return Math.Max(0, text.Length * 3 / 4 - num); } } internal static class ZoneBlueprintRpcTransport { public static void SendToServer(string rpcName, TEnvelope envelope) where TEnvelope : IZoneBlueprintRpcEnvelope { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), rpcName, new object[1] { WritePackage(envelope) }); } } public static void SendResponse(long target, string rpcName, TEnvelope envelope) where TEnvelope : IZoneBlueprintRpcEnvelope { ZRoutedRpc.instance.InvokeRoutedRPC(target, rpcName, new object[1] { WritePackage(envelope) }); } public static void HandleServerRequest(long sender, ZPackage package, ManualLogSource logger, string queueName, Func createError, Func execute, Action sendResponse) where TEnvelope : IZoneBlueprintRpcEnvelope { Func execute2 = execute; ManualLogSource logger2 = logger; string queueName2 = queueName; Func createError2 = createError; Action sendResponse2 = sendResponse; if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } if (!ZoneBlueprintNetworkPayload.TryReserveIngress(sender, out string reason)) { sendResponse2(sender, createError2(reason)); return; } ZoneBlueprintNetworkPayload.RawEnvelopePayload rawPayload; try { rawPayload = ZoneBlueprintNetworkPayload.ReadRawEnvelope(package, ZoneBlueprintNetworkPayload.MaxUploadEnvelopeBytes); } catch (Exception ex) { logger2.LogError((object)$"{queueName2} failed: {ex}"); sendResponse2(sender, createError2(ex.Message)); return; } int estimatedBytes = ZoneBlueprintNetworkPayload.EstimateQueuedBytes(rawPayload); if (!ZoneBlueprintNetworkPayload.TryEnqueue(queueName2, logger2, sender, estimatedBytes, delegate { TEnvelope arg; try { arg = execute2(ReadQueuedEnvelope(rawPayload), sender); } catch (Exception ex2) { logger2.LogError((object)$"{queueName2} failed: {ex2}"); arg = createError2(ex2.Message); } sendResponse2(sender, arg); }, out string reason2)) { sendResponse2(sender, createError2(reason2)); } } public static void HandleClientResponse(ZPackage package, ManualLogSource logger, string description, Action handleResponse) where TEnvelope : IZoneBlueprintRpcEnvelope { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { return; } try { handleResponse(ReadEnvelope(package)); } catch (Exception ex) { logger.LogWarning((object)("Failed to read " + description + " response: " + ex.Message)); } } public static TEnvelope CreateEnvelope(string type, TPayload payload) where TEnvelope : IZoneBlueprintRpcEnvelope, new() { return ZoneBlueprintNetworkPayload.CreateEnvelope(type, payload); } public static TPayload ReadPayload(TEnvelope envelope) where TEnvelope : IZoneBlueprintRpcEnvelope { return ZoneBlueprintNetworkPayload.ReadPayload(envelope); } private static ZPackage WritePackage(TEnvelope envelope) where TEnvelope : IZoneBlueprintRpcEnvelope { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_001f: Expected O, but got Unknown ZPackage val = new ZPackage(); ZoneBlueprintNetworkPayload.WriteEnvelope(val, HomesteadYaml.Serialize(envelope), envelope.BlueprintPayload); return val; } private static TEnvelope ReadQueuedEnvelope(ZoneBlueprintNetworkPayload.RawEnvelopePayload rawPayload) where TEnvelope : IZoneBlueprintRpcEnvelope { byte[] blueprintPayload; TEnvelope result = HomesteadYaml.Deserialize(ZoneBlueprintNetworkPayload.ReadEnvelope(rawPayload, out blueprintPayload)); result.BlueprintPayload = blueprintPayload; return result; } private static TEnvelope ReadEnvelope(ZPackage package) where TEnvelope : IZoneBlueprintRpcEnvelope { byte[] blueprintPayload; TEnvelope result = HomesteadYaml.Deserialize(ZoneBlueprintNetworkPayload.ReadEnvelope(package, out blueprintPayload)); result.BlueprintPayload = blueprintPayload; return result; } } internal static class ZoneBlueprintPlanRpc { private const string RequestRpcName = "sighsorry.Homestead_BlueprintPlanRequest"; private const string ResponseRpcName = "sighsorry.Homestead_BlueprintPlanResponse"; private const float MaxRequestedChestDistanceFromAnchor = 512f; private static ManualLogSource _logger = null; private static bool _initialized; private static readonly ZoneRpcRegistrar RpcRegistrar = new ZoneRpcRegistrar(); private static readonly Dictionary PreviewCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly HashSet PendingPreviewRequests = new HashSet(StringComparer.OrdinalIgnoreCase); public static void Initialize(ManualLogSource logger) { if (!_initialized) { _initialized = true; _logger = logger; RegisterRpcs(); } } public static void Update() { RegisterRpcs(); } public static void ResetForWorldSession() { PreviewCache.Clear(); PendingPreviewRequests.Clear(); } public static void RequestPlace(string name, ZoneBlueprintFile blueprint, Vector3 anchor, Quaternion anchorRotation, Vector3 chestPosition, Quaternion chestRotation) { //IL_00f0: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_0067: 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_0075: Unknown result type (might be due to invalid IL or missing references) byte[] payload; string reason; if ((Object)(object)ZNet.instance == (Object)null) { Message(HomesteadLocalization.Text("hs_common_world_not_ready"), (MessageType)2); } else if (!ZoneBlueprintNetworkPayload.TryCreateBlueprintPayload(ZoneBlueprintFileFormat.Serialize(blueprint), enforceUploadLimit: true, out payload, out reason)) { Message(reason, (MessageType)2); } else if (ZNet.instance.IsServer()) { HandleResponse(ExecutePlace(new ZoneBlueprintPlanPlaceRequest { Name = name, BlueprintEncoding = "gzip", BlueprintPayload = payload, Anchor = ZoneTransformPayload.From(anchor, anchorRotation), Chest = ZoneTransformPayload.From(chestPosition, chestRotation) }, 0L, ((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetPlayerID() : 0, ((Object)(object)Player.m_localPlayer != (Object)null) ? HomesteadPlayerIdentity.ResolveLocalPlatformId(Player.m_localPlayer.GetPlayerID()) : "")); } else { SendRequest("place", new ZoneBlueprintPlanPlaceRequest { Name = name, BlueprintEncoding = "gzip", BlueprintPayload = payload, Anchor = ZoneTransformPayload.From(anchor, anchorRotation), Chest = ZoneTransformPayload.From(chestPosition, chestRotation) }); } } public static void RequestPreview(string name) { if (!string.IsNullOrWhiteSpace(name) && !PreviewCache.ContainsKey(name) && !PendingPreviewRequests.Contains(name) && !((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer()) { PendingPreviewRequests.Add(name); SendRequest("preview", new ZoneBlueprintPlanPreviewRequest { Name = name }); } } public static bool TryGetCachedPreview(string name, out ZoneBlueprintFile blueprint) { return PreviewCache.TryGetValue(name, out blueprint); } public static bool IsPreviewPending(string name) { if (!string.IsNullOrWhiteSpace(name)) { return PendingPreviewRequests.Contains(name); } return false; } private static void CachePreview(string name, ZoneBlueprintFile blueprint) { if (!string.IsNullOrWhiteSpace(name) && blueprint != null) { blueprint.Name = name; PreviewCache[name] = blueprint; PendingPreviewRequests.Remove(name); } } private static void RegisterRpcs() { RpcRegistrar.EnsureRegistered(delegate(ZRoutedRpc routedRpc) { routedRpc.Register("sighsorry.Homestead_BlueprintPlanRequest", (Action)RPC_HandleRequest); routedRpc.Register("sighsorry.Homestead_BlueprintPlanResponse", (Action)RPC_HandleResponse); }); } private static void SendRequest(string type, TPayload payload) { RegisterRpcs(); if (ZRoutedRpc.instance != null) { ZoneBlueprintPlanRpcEnvelope envelope = CreateEnvelope(type, payload); ZoneBlueprintRpcTransport.SendToServer("sighsorry.Homestead_BlueprintPlanRequest", envelope); } } private static void RPC_HandleRequest(long sender, ZPackage package) { ZoneBlueprintRpcTransport.HandleServerRequest(sender, package, _logger, "Blueprint plan RPC", CreateError, ExecuteRequest, SendResponse); } private static void RPC_HandleResponse(long sender, ZPackage package) { ZoneBlueprintRpcTransport.HandleClientResponse(package, _logger, "blueprint plan", HandleResponse); } private static ZoneBlueprintPlanRpcEnvelope ExecuteRequest(ZoneBlueprintPlanRpcEnvelope request, long sender) { if (request.Type == "preview") { return ExecutePreview(ReadPayload(request)); } if (!TryResolveRequester(sender, out long playerId, out string reason)) { return CreateEnvelope(request.Type, new ZoneBlueprintPlanPlaceResponse { Success = false, Message = reason }); } if (request.Type == "place") { return ExecutePlace(ReadPayload(request), sender, playerId, HomesteadPlayerIdentity.ResolvePlatformId(null, sender, playerId)); } return CreateEnvelope(request.Type, new ZoneBlueprintPlanPlaceResponse { Success = false, Message = HomesteadLocalization.Format("hs_blueprint_plan_unknown_action", request.Type) }); } private static ZoneBlueprintPlanRpcEnvelope ExecutePlace(ZoneBlueprintPlanPlaceRequest request, long sender, long playerId, string ownerPlatformId) { //IL_0034: 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_0044: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) ZoneBlueprintPlanPlaceRequest request2 = request; if (!ZoneTransformPayload.TryRead(request2.Anchor, out var position, out var rotation) || !ZoneTransformPayload.TryRead(request2.Chest, out var position2, out var rotation2) || !ZoneTransformPayload.IsFinite(position) || !ZoneTransformPayload.IsFinite(rotation) || !ZoneTransformPayload.IsFinite(rotation2)) { return CreateEnvelope("place", Fail(HomesteadLocalization.Text("hs_blueprint_place_payload_missing_transform"))); } if (!ZoneBlueprintNetworkPayload.TryDeserializeBlueprintUpload(request2.BlueprintPayload, request2.BlueprintEncoding, out ZoneBlueprintFile blueprint, out string reason)) { return CreateEnvelope("place", Fail(reason)); } string savedName; HomesteadCommandResult homesteadCommandResult = ZoneBlueprintCommands.SaveUploadedBlueprintForPlan(request2.Name, blueprint, playerId, out savedName); if (!homesteadCommandResult.Success) { return CreateEnvelope("place", Fail(homesteadCommandResult.Message)); } try { ZoneBlueprintFile blueprint2 = ZoneBlueprintCommands.LoadBlueprintForPlan(savedName); if (ZoneBlueprintCommands.CreateLoadPlanForBlueprint(blueprint2, position, rotation).Entries.Count == 0) { return CreateEnvelope("place", Fail(HomesteadLocalization.Format("hs_blueprint_no_valid_entries", savedName))); } if (!ZoneBlueprintNetworkPayload.TryCreateBlueprintPayload(ZoneBlueprintFileFormat.Serialize(blueprint2), enforceUploadLimit: false, out byte[] payload, out string reason2)) { return CreateEnvelope("place", Fail(reason2)); } Vector3 val = ResolvePlanChestPosition(blueprint2, position, rotation, position2, rotation2); ownerPlatformId = (string.IsNullOrWhiteSpace(ownerPlatformId) ? HomesteadPlayerIdentity.ResolvePlatformId(null, sender, playerId) : ownerPlatformId); HomesteadCommandResult homesteadCommandResult2 = ZoneBlueprintPlanChestPrefab.PlacePlanChest(savedName, playerId, ownerPlatformId, position, rotation, val, rotation2, sender); return CreateEnvelope("place", new ZoneBlueprintPlanPlaceResponse { Success = homesteadCommandResult2.Success, Message = ((homesteadCommandResult2.Success && !string.Equals(savedName, request2.Name, StringComparison.OrdinalIgnoreCase)) ? HomesteadLocalization.Format("hs_blueprint_server_saved_as_existing", homesteadCommandResult2.Message, savedName) : homesteadCommandResult2.Message), RequestedName = request2.Name, BlueprintName = savedName, Chest = (homesteadCommandResult2.Success ? ZoneTransformPayload.From(val, rotation2) : null), BlueprintEncoding = "gzip", BlueprintPayload = (homesteadCommandResult2.Success ? payload : Array.Empty()) }); } catch (Exception ex) { return CreateEnvelope("place", Fail(ex.Message)); } ZoneBlueprintPlanPlaceResponse Fail(string message) { return new ZoneBlueprintPlanPlaceResponse { Success = false, Message = message, RequestedName = request2.Name }; } } private static ZoneBlueprintPlanRpcEnvelope ExecutePreview(ZoneBlueprintPlanPreviewRequest request) { try { if (!ZoneBlueprintNetworkPayload.TryCreateBlueprintPayload(ZoneBlueprintCommands.SerializePreviewBlueprintForPlan(request.Name), enforceUploadLimit: false, out byte[] payload, out string reason)) { throw new InvalidOperationException(reason); } return CreateEnvelope("preview", new ZoneBlueprintPlanPreviewResponse { Success = true, Name = request.Name, BlueprintEncoding = "gzip", BlueprintPayload = payload }); } catch (Exception ex) { return CreateEnvelope("preview", new ZoneBlueprintPlanPreviewResponse { Success = false, Name = request.Name, Message = ex.Message }); } } private static void SendResponse(long target, ZoneBlueprintPlanRpcEnvelope response) { ZoneBlueprintRpcTransport.SendResponse(target, "sighsorry.Homestead_BlueprintPlanResponse", response); } private static void HandleResponse(ZoneBlueprintPlanRpcEnvelope response) { if (response.Type == "preview") { ZoneBlueprintPlanPreviewResponse zoneBlueprintPlanPreviewResponse = ReadPayload(response); PendingPreviewRequests.Remove(zoneBlueprintPlanPreviewResponse.Name); if (!zoneBlueprintPlanPreviewResponse.Success) { return; } try { if (ZoneBlueprintNetworkPayload.TryDeserializeBlueprintPayload(zoneBlueprintPlanPreviewResponse.BlueprintPayload, zoneBlueprintPlanPreviewResponse.BlueprintEncoding, out ZoneBlueprintFile blueprint, out string reason)) { CachePreview(zoneBlueprintPlanPreviewResponse.Name, blueprint); } else { _logger.LogWarning((object)("Failed to cache server blueprint preview '" + zoneBlueprintPlanPreviewResponse.Name + "': " + reason)); } return; } catch (Exception ex) { _logger.LogWarning((object)("Failed to cache server blueprint preview '" + zoneBlueprintPlanPreviewResponse.Name + "': " + ex.Message)); return; } } ZoneBlueprintPlanPlaceResponse zoneBlueprintPlanPlaceResponse = ReadPayload(response); if (zoneBlueprintPlanPlaceResponse.Success) { TryPlayPlanChestPlaceVfx(zoneBlueprintPlanPlaceResponse.Chest); } if (zoneBlueprintPlanPlaceResponse.Success && !string.IsNullOrWhiteSpace(zoneBlueprintPlanPlaceResponse.BlueprintName) && zoneBlueprintPlanPlaceResponse.BlueprintPayload.Length != 0) { try { if (ZoneBlueprintNetworkPayload.TryDecodeBlueprintPayloadToText(zoneBlueprintPlanPlaceResponse.BlueprintPayload, zoneBlueprintPlanPlaceResponse.BlueprintEncoding, out string blueprintText, out string reason2)) { ZoneBlueprintFile blueprint2 = ZoneBlueprintFileFormat.Deserialize(blueprintText, zoneBlueprintPlanPlaceResponse.BlueprintName); CachePreview(zoneBlueprintPlanPlaceResponse.BlueprintName, blueprint2); ZoneBlueprintCommands.EnsureLocalPlanBlueprintCopy(zoneBlueprintPlanPlaceResponse.BlueprintName, blueprintText); } else { _logger.LogWarning((object)("Failed to decode server blueprint copy '" + zoneBlueprintPlanPlaceResponse.BlueprintName + "': " + reason2)); } } catch (Exception ex2) { _logger.LogWarning((object)("Failed to save server blueprint copy '" + zoneBlueprintPlanPlaceResponse.BlueprintName + "' locally: " + ex2.Message)); } } if (!string.IsNullOrWhiteSpace(zoneBlueprintPlanPlaceResponse.Message)) { Message(zoneBlueprintPlanPlaceResponse.Message, (MessageType)(zoneBlueprintPlanPlaceResponse.Success ? 1 : 2)); } } private static void TryPlayPlanChestPlaceVfx(ZoneBlueprintStoreTransformPayload? chest) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if ((!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()) && ZoneTransformPayload.TryRead(chest, out var position, out var rotation) && ZoneTransformPayload.IsFinite(position) && ZoneTransformPayload.IsFinite(rotation)) { ZoneBlueprintPlanChestPrefab.PlayPlaceEffect(position, rotation); } } private static bool TryResolveRequester(long sender, out long playerId, out string reason) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) playerId = 0L; reason = ""; if ((Object)(object)ZNet.instance == (Object)null || ZDOMan.instance == null) { reason = HomesteadLocalization.Text("hs_common_world_not_ready"); return false; } ZNetPeer peer = ZNet.instance.GetPeer(sender); if (peer == null || !peer.IsReady()) { reason = HomesteadLocalization.Text("hs_common_player_not_ready"); return false; } if (((ZDOID)(ref peer.m_characterID)).IsNone()) { reason = HomesteadLocalization.Text("hs_store_character_missing"); return false; } ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); if (zDO == null) { reason = HomesteadLocalization.Text("hs_store_character_missing"); return false; } playerId = zDO.GetLong(ZDOVars.s_playerID, 0L); if (playerId == 0L) { reason = HomesteadLocalization.Text("hs_dismantle_playerid_missing"); return false; } return true; } private static ZoneBlueprintPlanRpcEnvelope CreateEnvelope(string type, TPayload payload) { return ZoneBlueprintRpcTransport.CreateEnvelope(type, payload); } private static TPayload ReadPayload(ZoneBlueprintPlanRpcEnvelope envelope) { return ZoneBlueprintRpcTransport.ReadPayload(envelope); } private static ZoneBlueprintPlanRpcEnvelope CreateError(string message) { return CreateEnvelope("place", new ZoneBlueprintPlanPlaceResponse { Success = false, Message = message }); } private static Vector3 ResolvePlanChestPosition(ZoneBlueprintFile blueprint, Vector3 anchor, Quaternion anchorRotation, Vector3 requestedChestPosition, Quaternion chestRotation) { //IL_0000: 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_0026: 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_0029: 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) //IL_0017: 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) if (!ZoneTransformPayload.IsFinite(requestedChestPosition) || ((Vector3)(ref requestedChestPosition)).sqrMagnitude < 0.0001f || !IsWithinHorizontalDistance(anchor, requestedChestPosition, 512f)) { return ZoneBlueprintCommands.GetPlanChestPosition(blueprint, anchor, anchorRotation, chestRotation); } return requestedChestPosition; } private static bool IsWithinHorizontalDistance(Vector3 origin, Vector3 target, float maxDistance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = target.x - origin.x; float num2 = target.z - origin.z; return num * num + num2 * num2 <= maxDistance * maxDistance; } private static void Message(string message, MessageType type) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)message); } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message(type, message, 0, (Sprite)null); } } } internal sealed class ZoneBlueprintPlacementTool : MonoBehaviour { private const float MaxPlacementDistance = 128f; private static ManualLogSource? _logger; private static ZoneBlueprintPlacementTool? _instance; private string _blueprintName = ""; private ZoneBlueprintFile? _blueprint; private GameObject? _previewRoot; private GameObject? _chestPreviewRoot; private bool _active; private int _suppressInputFrames; private Vector3 _anchor; private Quaternion _anchorRotation = Quaternion.identity; private Quaternion _chestRotation = Quaternion.identity; private float _placementYaw; private float _heightOffset; private Vector3 _horizontalOffset; public static bool IsActive => _instance?._active ?? false; public static void Initialize(ManualLogSource logger) { _logger = logger; EnsureInstance(); } public static void Activate(Player player, string blueprintName) { EnsureInstance(); _instance?.ActivateInternal(player, blueprintName); } public static void Deactivate() { _instance?.DeactivateInternal(); } private static void EnsureInstance() { //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 if (!((Object)(object)_instance != (Object)null) || !Object.op_Implicit((Object)(object)_instance)) { GameObject val = new GameObject("HomesteadBlueprintPlacementTool"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void ActivateInternal(Player player, string blueprintName) { //IL_0040: 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_0056: 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 (_active && string.Equals(_blueprintName, blueprintName, StringComparison.OrdinalIgnoreCase)) { return; } ClearPreview(); _active = true; _blueprintName = blueprintName; _suppressInputFrames = 2; _placementYaw = 0f; _chestRotation = GetAimYawRotation(player); _heightOffset = 0f; _horizontalOffset = Vector3.zero; if (!ZoneBlueprintCommands.TryLoadBlueprint(blueprintName, out ZoneBlueprintFile blueprint)) { Message(player, HomesteadLocalization.Format("hs_blueprint_load_failed_plain", blueprintName)); DeactivateInternal(); return; } _blueprint = blueprint; _previewRoot = ZoneBlueprintVisuals.CreateBlueprintVisualRoot(blueprint, "HomesteadBlueprintPreview_" + blueprintName); _previewRoot.transform.SetParent(((Component)this).transform, false); _chestPreviewRoot = ZoneBlueprintPlanChestPrefab.CreatePreview(); GameObject? chestPreviewRoot = _chestPreviewRoot; if (chestPreviewRoot != null) { chestPreviewRoot.transform.SetParent(((Component)this).transform, false); } } private void DeactivateInternal() { //IL_0025: 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) _active = false; _blueprintName = ""; _blueprint = null; _heightOffset = 0f; _horizontalOffset = Vector3.zero; ZoneAreaToolStatusHud.Hide(); ClearPreview(); } private void Update() { //IL_004f: 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_005b: 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_0062: 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_006e: 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_00ee: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //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_0106: Unknown result type (might be due to invalid IL or missing references) if (!_active) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !ZonePlacementInput.IsHoldingBuildTool(localPlayer)) { DeactivateInternal(); return; } if (!TryGetAimPoint(localPlayer, out var point)) { SetPreviewVisible(visible: false); ZoneAreaToolStatusHud.Hide(); return; } _anchorRotation = Quaternion.Euler(0f, _placementYaw, 0f); _anchor = GetAdjustedAnchor(point, _anchorRotation); _chestRotation = GetAimYawRotation(localPlayer); if (ShouldBlockInput()) { UpdatePreviewTransform(); UpdateStatusHud(); return; } if (_suppressInputFrames > 0) { _suppressInputFrames--; UpdatePreviewTransform(); UpdateStatusHud(); return; } if (Input.GetKeyDown((KeyCode)27)) { ResetOffsets(); } ZonePlacementInput.ApplyYawScroll(ref _placementYaw); ZonePlacementInput.ApplyOffset(ref _horizontalOffset, ref _heightOffset); _anchorRotation = Quaternion.Euler(0f, _placementYaw, 0f); _anchor = GetAdjustedAnchor(point, _anchorRotation); UpdatePreviewTransform(); UpdateStatusHud(); if (Input.GetMouseButtonDown(0)) { Place(localPlayer); } } private void UpdateStatusHud() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) ZoneAreaToolStatusHud.ShowBlueprint("Blueprint Placement", _placementYaw, _horizontalOffset, _heightOffset); } private void OnDestroy() { ClearPreview(); if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } private void Place(Player player) { //IL_001e: 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: Unknown result type (might be due to invalid IL or missing references) if (_blueprint != null && !string.IsNullOrWhiteSpace(_blueprintName)) { HomesteadCommandResult homesteadCommandResult = ZoneBlueprintCommands.PlaceBlueprintPlanAt(_blueprintName, player, _anchor, _anchorRotation, _chestRotation); Message(player, homesteadCommandResult.Message, (MessageType)(homesteadCommandResult.Success ? 1 : 2)); } } private void UpdatePreviewTransform() { //IL_0027: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_previewRoot == (Object)null) { return; } _previewRoot.SetActive(true); _previewRoot.transform.position = _anchor; _previewRoot.transform.rotation = _anchorRotation; if (_blueprint == null) { return; } if ((Object)(object)_chestPreviewRoot == (Object)null) { _chestPreviewRoot = ZoneBlueprintPlanChestPrefab.CreatePreview(); GameObject? chestPreviewRoot = _chestPreviewRoot; if (chestPreviewRoot != null) { chestPreviewRoot.transform.SetParent(((Component)this).transform, false); } } if ((Object)(object)_chestPreviewRoot != (Object)null) { _chestPreviewRoot.SetActive(true); _chestPreviewRoot.transform.position = ZoneBlueprintCommands.GetPlanChestPosition(_blueprint, _anchor, _anchorRotation, _chestRotation); _chestPreviewRoot.transform.rotation = _chestRotation; } } private void SetPreviewVisible(bool visible) { if ((Object)(object)_previewRoot != (Object)null) { _previewRoot.SetActive(visible); } if ((Object)(object)_chestPreviewRoot != (Object)null) { _chestPreviewRoot.SetActive(visible); } } private void ClearPreview() { if ((Object)(object)_previewRoot != (Object)null) { Object.Destroy((Object)(object)_previewRoot); _previewRoot = null; } if ((Object)(object)_chestPreviewRoot != (Object)null) { Object.Destroy((Object)(object)_chestPreviewRoot); _chestPreviewRoot = null; } } private static bool TryGetAimPoint(Player player, out Vector3 point) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0095: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) Camera mainCamera = Utils.GetMainCamera(); RaycastHit val = default(RaycastHit); if ((Object)(object)mainCamera != (Object)null && Physics.Raycast(mainCamera.ScreenPointToRay(new Vector3((float)Screen.width * 0.5f, (float)Screen.height * 0.5f)), ref val, 128f, -5, (QueryTriggerInteraction)1)) { point = ((RaycastHit)(ref val)).point; point.y = SampleGroundY(point.x, point.z, point.y); return true; } point = ((Component)player).transform.position + ((Component)player).transform.forward * 8f; point.y = SampleGroundY(point.x, point.z, ((Component)player).transform.position.y); return true; } private Vector3 GetAdjustedAnchor(Vector3 aimPoint, Quaternion rotation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return aimPoint + ZonePlacementOffset.ToWorldOffset(rotation, _horizontalOffset, _heightOffset); } private void ResetOffsets() { //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) _heightOffset = 0f; _horizontalOffset = Vector3.zero; } private static float SampleGroundY(float x, float z, float fallbackY) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return fallbackY; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(x, fallbackY, z); Vector3 val2 = default(Vector3); Biome val3 = default(Biome); BiomeArea val4 = default(BiomeArea); Heightmap val5 = default(Heightmap); ZoneSystem.instance.GetGroundData(ref val, ref val2, ref val3, ref val4, ref val5); return val.y; } private static Quaternion GetYawRotation(Quaternion rotation) { //IL_0007: 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) return Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f); } private static Quaternion GetAimYawRotation(Player player) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_001a: 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) //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) Camera mainCamera = Utils.GetMainCamera(); if ((Object)(object)mainCamera != (Object)null) { Vector3 forward = ((Component)mainCamera).transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude > 0.0001f) { return Quaternion.LookRotation(((Vector3)(ref forward)).normalized, Vector3.up); } } return GetYawRotation(((Component)player).transform.rotation); } private static bool ShouldBlockInput() { return ZoneAreaToolShared.ShouldBlockInput(); } private static void Message(Player player, string message) { Message(player, message, (MessageType)1); } private static void Message(Player player, string message, MessageType type) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)message); } ((Character)player).Message(type, message, 0, (Sprite)null); } } internal static class ZoneBlueprintChestCommands { private enum BlueprintChestKind { Build, StorePrice, StorePurchase, StorePayout } private sealed class BlueprintChestCommandRequest { public bool DryRun { get; set; } } private sealed class BlueprintChestCommandResult { public bool Success { get; set; } public bool DryRun { get; set; } public int Total { get; set; } public int Deleted { get; set; } public int Build { get; set; } public int StorePrice { get; set; } public int StorePurchase { get; set; } public int StorePayout { get; set; } public int DraftFilesDeleted { get; set; } public string Message { get; set; } = ""; public static BlueprintChestCommandResult Fail(string message) { return new BlueprintChestCommandResult { Success = false, Message = message }; } } [CompilerGenerated] private static class <>O { public static ConsoleEvent <0>__HandleClearCommand; public static Action <1>__RPC_HandleRequest; public static Action <2>__RPC_HandleResult; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleOptionsFetcher <>9__6_0; public static Action <>9__7_0; public static Func <>9__8_0; public static Func <>9__12_0; internal List b__6_0() { return new List(1) { "dry" }; } internal void b__7_0(ZRoutedRpc routedRpc) { routedRpc.Register("sighsorry.Homestead_BlueprintChestCommandRequest", (Action)RPC_HandleRequest); routedRpc.Register("sighsorry.Homestead_BlueprintChestCommandResult", (Action)RPC_HandleResult); } internal bool b__8_0(string arg) { if (!arg.Equals("dry", StringComparison.OrdinalIgnoreCase)) { return arg.Equals("dry-run", StringComparison.OrdinalIgnoreCase); } return true; } internal bool b__12_0(ZDO zdo) { BlueprintChestKind kind; if (zdo != null && zdo.IsValid()) { return TryGetChestKind(zdo, out kind); } return false; } } private const string ClearCommand = "hs_clearchests"; private const string RequestRpcName = "sighsorry.Homestead_BlueprintChestCommandRequest"; private const string ResultRpcName = "sighsorry.Homestead_BlueprintChestCommandResult"; private static ManualLogSource _logger = null; private static bool _initialized; private static readonly ZoneRpcRegistrar RpcRegistrar = new ZoneRpcRegistrar(); public static void Initialize(ManualLogSource logger) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_005d: Expected O, but got Unknown if (_initialized) { return; } _initialized = true; _logger = logger; object obj = <>O.<0>__HandleClearCommand; if (obj == null) { ConsoleEvent val = HandleClearCommand; <>O.<0>__HandleClearCommand = val; obj = (object)val; } object obj2 = <>c.<>9__6_0; if (obj2 == null) { ConsoleOptionsFetcher val2 = () => new List(1) { "dry" }; <>c.<>9__6_0 = val2; obj2 = (object)val2; } new ConsoleCommand("hs_clearchests", "[dry] - Deletes all Homestead blueprint/build/store chests in the world.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, false, false, false); RegisterRpcs(); } internal static void RegisterRpcs() { RpcRegistrar.EnsureRegistered(delegate(ZRoutedRpc routedRpc) { routedRpc.Register("sighsorry.Homestead_BlueprintChestCommandRequest", (Action)RPC_HandleRequest); routedRpc.Register("sighsorry.Homestead_BlueprintChestCommandResult", (Action)RPC_HandleResult); }); } private static void HandleClearCommand(ConsoleEventArgs args) { EnsureCommandReady(); bool dryRun = args.Args.Skip(1).Any((string arg) => arg.Equals("dry", StringComparison.OrdinalIgnoreCase) || arg.Equals("dry-run", StringComparison.OrdinalIgnoreCase)); DispatchRequest(new BlueprintChestCommandRequest { DryRun = dryRun }, args.Context); } private static void DispatchRequest(BlueprintChestCommandRequest request, Terminal? context) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if (ZNet.instance.IsServer()) { ShowResult(Execute(request), context); return; } RegisterRpcs(); ZPackage val = new ZPackage(); val.Write(HomesteadYaml.Serialize(request)); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "sighsorry.Homestead_BlueprintChestCommandRequest", new object[1] { val }); if (context != null) { context.AddString("hs_clearchests request sent to server."); } } private static void RPC_HandleRequest(long sender, ZPackage package) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { BlueprintChestCommandResult value; try { value = (IsAuthorizedSender(sender) ? Execute(HomesteadYaml.Deserialize(package.ReadString())) : BlueprintChestCommandResult.Fail("Admin only.")); } catch (Exception ex) { _logger.LogError((object)$"Blueprint chest command RPC failed: {ex}"); value = BlueprintChestCommandResult.Fail(ex.Message); } ZPackage val = new ZPackage(); val.Write(HomesteadYaml.Serialize(value)); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "sighsorry.Homestead_BlueprintChestCommandResult", new object[1] { val }); } } private static void RPC_HandleResult(long sender, ZPackage package) { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { return; } try { ShowResult(HomesteadYaml.Deserialize(package.ReadString()), (Terminal?)(object)Console.instance); } catch (Exception arg) { _logger.LogError((object)$"Blueprint chest command result RPC failed: {arg}"); } } private static BlueprintChestCommandResult Execute(BlueprintChestCommandRequest request) { if (ZDOMan.instance == null) { return BlueprintChestCommandResult.Fail("World is not ready."); } BlueprintChestKind kind2; List list = ZDOMan.instance.m_objectsByID.Values.Where((ZDO zdo) => zdo != null && zdo.IsValid() && TryGetChestKind(zdo, out kind2)).ToList(); BlueprintChestCommandResult blueprintChestCommandResult = new BlueprintChestCommandResult { Success = true, DryRun = request.DryRun }; foreach (ZDO item in list) { if (!TryGetChestKind(item, out var kind)) { continue; } blueprintChestCommandResult.Total++; switch (kind) { case BlueprintChestKind.Build: blueprintChestCommandResult.Build++; break; case BlueprintChestKind.StorePrice: blueprintChestCommandResult.StorePrice++; if (!request.DryRun && TryCleanupOwnedDraft(item)) { blueprintChestCommandResult.DraftFilesDeleted++; } break; case BlueprintChestKind.StorePurchase: blueprintChestCommandResult.StorePurchase++; break; case BlueprintChestKind.StorePayout: blueprintChestCommandResult.StorePayout++; break; } if (!request.DryRun) { SavedZdoHelper.Destroy(item); blueprintChestCommandResult.Deleted++; } } if (!request.DryRun) { SavedZdoHelper.FlushDestroyed(); } blueprintChestCommandResult.Message = BuildMessage(blueprintChestCommandResult); return blueprintChestCommandResult; } private static bool TryGetChestKind(ZDO zdo, out BlueprintChestKind kind) { kind = BlueprintChestKind.Build; int prefab = zdo.GetPrefab(); if (prefab == ZoneBlueprintPlanChestPrefab.PrefabHash) { kind = BlueprintChestKind.Build; return true; } if (prefab == ZoneBlueprintStoreChestPrefab.PricePrefabHash) { kind = BlueprintChestKind.StorePrice; return true; } if (prefab == ZoneBlueprintStoreChestPrefab.PurchasePrefabHash) { kind = BlueprintChestKind.StorePurchase; return true; } if (prefab == ZoneBlueprintStoreChestPrefab.PayoutPrefabHash) { kind = BlueprintChestKind.StorePayout; return true; } return false; } private static bool TryCleanupOwnedDraft(ZDO zdo) { if (!string.Equals(zdo.GetString("hs_store_mode", ""), "price", StringComparison.Ordinal) || zdo.GetBool("hs_store_confirmed", false) || !zdo.GetBool("hs_store_draft_owned_by_chest", false)) { return false; } string @string = zdo.GetString("hs_store_blueprint_file", ""); ZoneBlueprintStoreDraftRepository.DeleteFile(@string); zdo.Set("hs_store_draft_owned_by_chest", false); ZoneBlueprintChestZdoRegistry.Refresh(zdo); return !string.IsNullOrWhiteSpace(@string); } private static string BuildMessage(BlueprintChestCommandResult result) { string text = (result.DryRun ? "Found" : "Deleted"); return $"{text} {result.Total} Homestead blueprint chest(s): build={result.Build}, price={result.StorePrice}, purchase={result.StorePurchase}, payout={result.StorePayout}, draft files deleted={result.DraftFilesDeleted}."; } private static void EnsureCommandReady() { if ((Object)(object)ZNet.instance == (Object)null) { throw new InvalidOperationException("World is not ready."); } if (!ZNet.instance.IsServer() && ZRoutedRpc.instance == null) { throw new InvalidOperationException("Server RPC is not ready."); } if ((!ZNet.instance.IsServer() || !((Object)(object)Player.m_localPlayer == (Object)null)) && !ZNet.instance.LocalPlayerIsAdminOrHost()) { throw new InvalidOperationException("Admin only."); } } private static bool IsAuthorizedSender(long sender) { ZNetPeer peer = ZNet.instance.GetPeer(sender); object obj; if (peer == null) { obj = null; } else { ZRpc rpc = peer.m_rpc; if (rpc == null) { obj = null; } else { ISocket socket = rpc.m_socket; obj = ((socket != null) ? socket.GetHostName() : null); } } if (obj == null) { obj = ""; } string text = (string)obj; if (text.Length > 0) { return ZNet.instance.IsAdmin(text); } return false; } private static void ShowResult(BlueprintChestCommandResult result, Terminal? terminal) { string message = result.Message; _logger.LogInfo((object)message); if (terminal != null) { terminal.AddString(message); } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)(result.Success ? 1 : 2), message, 0, (Sprite)null); } } } internal static class ZoneBlueprintChestInventoryScroll { [HarmonyPatch(typeof(InventoryGui), "Show")] private static class InventoryGuiShowPatch { private static void Postfix(InventoryGui __instance, Container container) { if ((Object)(object)__instance != (Object)null && (Object)(object)container != (Object)null) { __instance.m_firstContainerUpdate = true; } Request(container, ((Object)(object)__instance != (Object)null) ? __instance.m_containerGrid : null); } } private const int KeepTopFrames = 3; private static Container? _container; private static int _untilFrame; public static void TryKeepContainerGridAtTop(InventoryGrid? grid) { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)grid == (Object)null) && !((Object)(object)instance.m_containerGrid != (Object)(object)grid) && ShouldKeepAtTop(instance.m_currentContainer) && Time.frameCount <= _untilFrame && !((Object)(object)_container != (Object)(object)instance.m_currentContainer)) { ScrollToTop(grid); } } private static void Request(Container? container, InventoryGrid? grid) { if (ShouldKeepAtTop(container)) { _container = container; _untilFrame = Time.frameCount + 3; ScrollToTop(grid); } } private static bool ShouldKeepAtTop(Container? container) { if (!Object.op_Implicit((Object)(object)container)) { return false; } if (ZoneBlueprintPlanAnchor.TryGetAnchor(container, out ZoneBlueprintPlanAnchor _)) { return true; } if (ZoneBlueprintStoreChestPatchHelper.TryGetStoreChest(container, out ZoneBlueprintStoreChest chest)) { if (!chest.IsPurchaseChest()) { return chest.IsPayoutChest(); } return true; } return false; } private static void ScrollToTop(InventoryGrid? grid) { if (!((Object)(object)grid == (Object)null)) { grid.ResetView(); if ((Object)(object)grid.m_scrollbar != (Object)null) { grid.m_scrollbar.value = 1f; } } } } internal sealed class ZoneBlueprintPlanAnchor : MonoBehaviour { private sealed class RefundMaterial { public string ItemName { get; set; } = ""; public string PrefabName { get; set; } = ""; public int Amount { get; set; } } [HarmonyPatch(typeof(Player), "Update")] private static class PlayerUpdatePatch { private static void Postfix(Player __instance) { //IL_0032: 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 (Time.frameCount == _lastConfirmInputFrame || (Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !((Character)__instance).TakeInput() || ((Character)__instance).IsDead()) { return; } KeyboardShortcut chestConfirmHotkey = BlueprintConfig.ChestConfirmHotkey; if (!((KeyboardShortcut)(ref chestConfirmHotkey)).IsDown()) { return; } GameObject hoverObject = ((Humanoid)__instance).GetHoverObject(); if (!((Object)(object)hoverObject == (Object)null)) { ZoneBlueprintPlanAnchor componentInParent = hoverObject.GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null)) { _lastConfirmInputFrame = Time.frameCount; componentInParent.TryConfirm(__instance); } } } } [CompilerGenerated] private sealed class <>c__DisplayClass46_0 { public HomesteadCommandResult result; internal void b__0(HomesteadCommandResult value) { result = value; } } [CompilerGenerated] private sealed class d__46 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string name; public Player player; public Vector3 anchorPosition; public Quaternion anchorRotation; public Dictionary deposited; public ZoneBlueprintPlanAnchor <>4__this; private <>c__DisplayClass46_0 <>8__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__46(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0051: 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) int num = <>1__state; ZoneBlueprintPlanAnchor zoneBlueprintPlanAnchor = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass46_0(); <>8__1.result = HomesteadCommandResult.Fail(HomesteadLocalization.Text("hs_blueprint_confirmation_incomplete")); <>2__current = ZoneBlueprintCommands.FinalizeBlueprintPlanAsync(name, player, anchorPosition, anchorRotation, deposited, delegate(HomesteadCommandResult value) { <>8__1.result = value; }); <>1__state = 1; return true; case 1: <>1__state = -1; zoneBlueprintPlanAnchor._confirmInProgress = false; Message(player, <>8__1.result.Message, (MessageType)(<>8__1.result.Success ? 1 : 2)); if (!<>8__1.result.Success) { return false; } if ((Object)(object)zoneBlueprintPlanAnchor._nview == (Object)null || !zoneBlueprintPlanAnchor._nview.IsValid()) { return false; } zoneBlueprintPlanAnchor.PlayConfirmSfx(); zoneBlueprintPlanAnchor._nview.GetZDO().Set("hs_plan_confirmed", true); zoneBlueprintPlanAnchor.ClearDepositedMaterials(); zoneBlueprintPlanAnchor._nview.Destroy(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__103 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public List refundMaterials; public Vector3 dropPosition; public string source; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__103(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; DropRefundMaterials(refundMaterials, dropPosition, source); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal const string BlueprintNameKey = "hs_blueprint_name"; private const string AnchorXKey = "hs_anchor_x"; private const string AnchorYKey = "hs_anchor_y"; private const string AnchorZKey = "hs_anchor_z"; private const string AnchorRotXKey = "hs_anchor_rot_x"; private const string AnchorRotYKey = "hs_anchor_rot_y"; private const string AnchorRotZKey = "hs_anchor_rot_z"; private const string AnchorRotWKey = "hs_anchor_rot_w"; private const string ConfirmedKey = "hs_plan_confirmed"; private const string MaterialPrefix = "hs_plan_material_"; private const string RefundPayloadKey = "hs_plan_refund_payload"; private const int RefundPayloadVersion = 1; private const string ProgressSfxPrefab = "sfx_build_hammer_wood"; private const string ConfirmSfxPrefab = "vfx_StaminaUpgrade"; private const float CleanupCheckInterval = 30f; private const float FailedPlanReloadRetryInterval = 5f; private const float FailedPlanWarningInterval = 60f; private static int _lastConfirmInputFrame = -1; private ZNetView? _nview; private Container? _container; private WearNTear? _wearNTear; private ZoneBlueprintFile? _blueprint; private ZoneBlueprintCommands.BlueprintLoadPlan? _plan; private List _requirements = new List(); private List _stationRequirements = new List(); private string _loadedBlueprintName = ""; private readonly ZoneBlueprintGhostOwner _previewGhost = new ZoneBlueprintGhostOwner(); private readonly ZoneBlueprintGhostOwner _stationGhost = new ZoneBlueprintGhostOwner(); private bool _absorbing; private bool _refundStarted; private bool _confirmInProgress; private string _lastReadySignature = ""; private string _lastPreviewStyleSignature = ""; private string _failedBlueprintName = ""; private string _lastPlanLoadFailure = ""; private int _lastInventorySignatureHash; private bool _hasInventorySignature; private float _nextCleanupCheck; private float _nextFailedPlanReloadAt; private float _nextFailedPlanWarningAt; internal static void NoteConfirmInputFrame() { _lastConfirmInputFrame = Time.frameCount; } private void Awake() { _nview = ((Component)this).GetComponent(); _container = ((Component)this).GetComponent(); _wearNTear = ((Component)this).GetComponent(); if ((Object)(object)_wearNTear != (Object)null) { WearNTear? wearNTear = _wearNTear; wearNTear.m_onDestroyed = (Action)Delegate.Combine(wearNTear.m_onDestroyed, new Action(OnDestroyed)); } ZoneBlueprintChestZdoRegistry.Refresh(((Object)(object)_nview != (Object)null && _nview.IsValid()) ? _nview.GetZDO() : null); ((MonoBehaviour)this).InvokeRepeating("Tick", 0.5f, 0.5f); } private void OnDestroy() { ReleaseAzuCraftyBoxesContainer("PlanChest.OnDestroy"); TryRefundDepositedMaterials("Unity.OnDestroy"); ClearPreview(); } public void SetPlan(string blueprintName, Vector3 anchor, Quaternion anchorRotation) { //IL_0039: 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_005b: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_nview == (Object)null) && _nview.IsValid()) { ZDO zDO = _nview.GetZDO(); zDO.Set("hs_blueprint_name", blueprintName); zDO.Set("hs_anchor_x", anchor.x); zDO.Set("hs_anchor_y", anchor.y); zDO.Set("hs_anchor_z", anchor.z); zDO.Set("hs_anchor_rot_x", anchorRotation.x); zDO.Set("hs_anchor_rot_y", anchorRotation.y); zDO.Set("hs_anchor_rot_z", anchorRotation.z); zDO.Set("hs_anchor_rot_w", anchorRotation.w); zDO.Set("hs_plan_confirmed", false); ZoneBlueprintChestLifecycle.Initialize(zDO); ReloadPlan(force: true); RebuildPreview(); } } public string GetPlanHoverText() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) string blueprintName = GetBlueprintName(); if (!ReloadPlan()) { return HomesteadLocalization.MaybeLocalize(HomesteadLocalization.Text("hs_blueprint_chest_data_missing")); } int requiredTotal = GetRequiredTotal(); int depositedTotal = GetDepositedTotal(); bool flag = requiredTotal == 0 || depositedTotal >= requiredTotal; string text = HomesteadLocalization.Format("hs_blueprint_chest_header", blueprintName, depositedTotal, requiredTotal); text = text + HomesteadLocalization.Format("hs_hover_action", "$KEY_Use", HomesteadLocalization.Text("hs_blueprint_open_materials")) + "\n"; text = text + HomesteadLocalization.Format("hs_hover_action", FormatShortcut(BlueprintConfig.ChestConfirmHotkey), HomesteadLocalization.Text("hs_blueprint_confirm_build")) + "\n"; if (!flag) { text = text + "\n" + HomesteadLocalization.Text("hs_blueprint_missing") + "\n"; foreach (ZoneBlueprintRequirement item in GetMissingRequirements().Take(6)) { text += $" {item.Amount} {Localization.instance.Localize(item.DisplayName)}\n"; } } return Localization.instance.Localize(text); } public bool TryConfirm(Player player) { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return true; } _nview.ClaimOwnership(); Touch(); Tick(); long @long = _nview.GetZDO().GetLong(ZDOVars.s_creator, 0L); if (@long != 0L && player.GetPlayerID() != @long) { Message(player, HomesteadLocalization.Text("hs_blueprint_other_creator"), (MessageType)2); return true; } string blueprintName = GetBlueprintName(); if (!ReloadPlan()) { Message(player, HomesteadLocalization.Format("hs_blueprint_not_available", blueprintName), (MessageType)2); return true; } if (BlueprintConfig.AzuCraftyBoxesPullOnConfirm) { TryPullAvailableMaterials(player, "confirm", message: true); } Dictionary depositedMaterials = GetDepositedMaterials(); if (_confirmInProgress) { Message(player, HomesteadLocalization.Text("hs_blueprint_confirmation_in_progress"), (MessageType)2); return true; } if (!TryGetAnchorTransform(out var position, out var rotation)) { Message(player, HomesteadLocalization.Format("hs_blueprint_not_available", blueprintName), (MessageType)2); return true; } _confirmInProgress = true; ((MonoBehaviour)this).StartCoroutine(ConfirmAsync(player, blueprintName, position, rotation, depositedMaterials)); return true; } [IteratorStateMachine(typeof(d__46))] private IEnumerator ConfirmAsync(Player player, string name, Vector3 anchorPosition, Quaternion anchorRotation, Dictionary deposited) { //IL_001c: 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_0023: 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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__46(0) { <>4__this = this, player = player, name = name, anchorPosition = anchorPosition, anchorRotation = anchorRotation, deposited = deposited }; } private void Tick() { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid() && ReloadPlan()) { if (_nview.IsOwner()) { AbsorbContainerMaterials(); TouchWhenInventoryChanged(); CheckAutoCleanup(); } UpdatePreview(); } } public void Touch() { ZoneBlueprintChestLifecycle.Touch(_nview); } private void TouchWhenInventoryChanged() { int inventorySignatureHash = ZoneMaterialEscrow.GetInventorySignatureHash(_container?.m_inventory); if (!_hasInventorySignature) { _lastInventorySignatureHash = inventorySignatureHash; _hasInventorySignature = true; } else if (inventorySignatureHash != _lastInventorySignatureHash) { _lastInventorySignatureHash = inventorySignatureHash; Touch(); } } private void CheckAutoCleanup() { if (Time.time < _nextCleanupCheck) { return; } _nextCleanupCheck = Time.time + 30f; ZNetView? nview = _nview; if (ZoneBlueprintChestLifecycle.IsExpired((nview != null) ? nview.GetZDO() : null, BlueprintConfig.ChestTimeoutMinutes) && !HasRetainedMaterials()) { ZNetView? nview2 = _nview; if (nview2 != null) { nview2.Destroy(); } } } private bool HasRetainedMaterials() { Container? container = _container; int? obj; if (container == null) { obj = null; } else { Inventory inventory = container.m_inventory; obj = ((inventory != null) ? new int?(inventory.NrOfItems()) : null); } int? num = obj; if (num.GetValueOrDefault() > 0) { return true; } if (GetDepositedTotal() > 0) { return true; } return ReadRefundMaterials().Any((RefundMaterial material) => material.Amount > 0); } private bool ReloadPlan(bool force = false) { //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0097: Unknown result type (might be due to invalid IL or missing references) string blueprintName = GetBlueprintName(); if (string.IsNullOrWhiteSpace(blueprintName)) { return false; } if (!force && _plan != null && string.Equals(_loadedBlueprintName, blueprintName, StringComparison.OrdinalIgnoreCase)) { return true; } if (ShouldSkipFailedPlanReload(blueprintName, force)) { return false; } if (!TryGetAnchorTransform(out var position, out var rotation)) { _blueprint = null; _plan = null; _requirements = new List(); _stationRequirements = new List(); _loadedBlueprintName = ""; _lastReadySignature = ""; ClearPreview(); return false; } ZoneBlueprintFile blueprint; try { _blueprint = ZoneBlueprintCommands.LoadBlueprintForPlan(blueprintName); _plan = ZoneBlueprintCommands.CreateLoadPlanForBlueprint(blueprintName, position, rotation); _requirements = ZoneBlueprintCommands.CollectRequirements(_plan); _stationRequirements = ZoneBlueprintCommands.CollectCraftingStations(_plan); _loadedBlueprintName = blueprintName; _lastReadySignature = ""; ClearPlanLoadFailure(); return true; } catch (Exception ex2) when (ZoneBlueprintPlanRpc.TryGetCachedPreview(blueprintName, out blueprint)) { try { _blueprint = blueprint; _plan = ZoneBlueprintCommands.CreateLoadPlanForBlueprint(blueprint, position, rotation); _requirements = ZoneBlueprintCommands.CollectRequirements(_plan); _stationRequirements = ZoneBlueprintCommands.CollectCraftingStations(_plan); _loadedBlueprintName = blueprintName; _lastReadySignature = ""; ClearPlanLoadFailure(); return true; } catch (Exception ex) { RecordPlanLoadFailure(blueprintName, "Failed to load Homestead server blueprint preview '" + blueprintName + "': " + ex.Message + " (local: " + ex2.Message + ")", logWarning: true); } _blueprint = null; _plan = null; _requirements = new List(); _stationRequirements = new List(); _loadedBlueprintName = ""; _lastReadySignature = ""; ClearPreview(); return false; } catch (Exception ex3) { ZoneBlueprintPlanRpc.RequestPreview(blueprintName); RecordPlanLoadFailure(blueprintName, "Failed to load Homestead blueprint plan '" + blueprintName + "': " + ex3.Message, !ZoneBlueprintPlanRpc.IsPreviewPending(blueprintName)); _blueprint = null; _plan = null; _requirements = new List(); _stationRequirements = new List(); _loadedBlueprintName = ""; _lastReadySignature = ""; ClearPreview(); return false; } } private bool ShouldSkipFailedPlanReload(string name, bool force) { if (force || _plan != null || !string.Equals(_failedBlueprintName, name, StringComparison.OrdinalIgnoreCase)) { return false; } return Time.realtimeSinceStartup < _nextFailedPlanReloadAt; } private void RecordPlanLoadFailure(string name, string message, bool logWarning) { float realtimeSinceStartup = Time.realtimeSinceStartup; bool flag = !string.Equals(_lastPlanLoadFailure, message, StringComparison.Ordinal); _failedBlueprintName = name; _lastPlanLoadFailure = message; _nextFailedPlanReloadAt = realtimeSinceStartup + 5f; if (logWarning && (flag || !(realtimeSinceStartup < _nextFailedPlanWarningAt))) { HomesteadPlugin.HomesteadLogger.LogWarning((object)message); _nextFailedPlanWarningAt = realtimeSinceStartup + 60f; } } private void ClearPlanLoadFailure() { _failedBlueprintName = ""; _lastPlanLoadFailure = ""; _nextFailedPlanReloadAt = 0f; _nextFailedPlanWarningAt = 0f; } private void AbsorbContainerMaterials() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (_container?.m_inventory != null && !_absorbing && _container.m_inventory.GetAllItems().ToList().Count != 0) { string readyBefore = CaptureReadySignature(); _absorbing = true; ZoneMaterialEscrow.AbsorbResult absorbResult; try { absorbResult = CreateMaterialSession().AbsorbUnexpectedInventoryItems(_container.m_inventory, ((Component)this).transform.position, preferInventory: false); } finally { _absorbing = false; } if (absorbResult.Changed) { _container.Save(); _lastReadySignature = ""; Touch(); PlayProgressSfxIfReadyAdvanced(readyBefore, absorbResult.Accepted); } } } public bool TryAcceptMaterialFromInventory(Inventory sourceInventory, ItemData item, int requestedAmount, bool message) { string readyBefore = CaptureReadySignature(); int num = AcceptMaterialFromInventory(sourceInventory, item, requestedAmount); if (num > 0) { Container? container = _container; if (container != null) { container.Save(); } _lastReadySignature = ""; Touch(); PlayProgressSfxIfReadyAdvanced(readyBefore, num); if (message && (Object)(object)Player.m_localPlayer != (Object)null && num < requestedAmount) { ((Character)Player.m_localPlayer).Message((MessageType)2, HomesteadLocalization.Format("hs_blueprint_accepted_excess_inventory", num), 0, (Sprite)null); } return true; } if (message && (Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, HomesteadLocalization.Text("hs_blueprint_material_not_needed"), 0, (Sprite)null); } return false; } public bool TryAcceptAllFromPlayer(Player player) { Player player2 = player; if ((Object)(object)player2 == (Object)null) { return false; } Inventory inventory = ((Humanoid)player2).GetInventory(); string readyBefore = CaptureReadySignature(); int num = 0; num += CreateMaterialSession().AcceptAllNeeded(inventory, (ItemData item) => item.m_shared.m_questItem || ((Humanoid)player2).IsItemEquiped(item)); if (num > 0) { Container? container = _container; if (container != null) { container.Save(); } _lastReadySignature = ""; Touch(); PlayProgressSfxIfReadyAdvanced(readyBefore, num); ((Character)player2).Message((MessageType)2, HomesteadLocalization.Format("hs_blueprint_accepted_materials", num), 0, (Sprite)null); return true; } ((Character)player2).Message((MessageType)2, HomesteadLocalization.Text("hs_blueprint_no_matching_materials"), 0, (Sprite)null); return false; } public int TryPullAvailableMaterials(Player player, string trigger, bool message) { if ((Object)(object)player == (Object)null || (Object)(object)_nview == (Object)null || !_nview.IsValid() || !ReloadPlan()) { return 0; } string readyBefore = CaptureReadySignature(); int num = AcceptAllFromPlayerInventory(player); int num2 = 0; if ((trigger == "confirm" && BlueprintConfig.AzuCraftyBoxesPullOnConfirm) || (trigger == "open" && BlueprintConfig.AzuCraftyBoxesPullOnOpen)) { num2 = TryPullFromAzuCraftyBoxes(player, trigger, message: false, playProgressSfx: false); } int num3 = num + num2; if (num3 > 0) { Container? container = _container; if (container != null) { container.Save(); } _lastReadySignature = ""; Touch(); PlayProgressSfxIfReadyAdvanced(readyBefore, num3); if (message) { ((Character)player).Message((MessageType)1, HomesteadLocalization.Format("hs_blueprint_pulled_materials", num3, num, num2), 0, (Sprite)null); } } return num3; } public int TryPullFromAzuCraftyBoxes(Player player, string trigger, bool message, bool playProgressSfx = true) { if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || !ReloadPlan()) { return 0; } ZoneMaterialEscrow.Session session = CreateMaterialSession(); List missingRequirements = session.GetMissingRequirements(); if (missingRequirements.Count == 0) { return 0; } string readyBefore = (playProgressSfx ? CaptureReadySignature() : ""); int num = AzuCraftyBoxesCompat.PullMissingMaterials((Component)(object)this, missingRequirements, delegate(ZoneBlueprintRequirement requirement, int amount) { session.AcceptPulled(requirement, amount); }); if (num <= 0) { return 0; } Container? container = _container; if (container != null) { container.Save(); } _lastReadySignature = ""; Touch(); if (playProgressSfx) { PlayProgressSfxIfReadyAdvanced(readyBefore, num); } if (message) { ((Character)player).Message((MessageType)1, HomesteadLocalization.Format("hs_blueprint_pulled_from_containers", num), 0, (Sprite)null); } return num; } private int AcceptAllFromPlayerInventory(Player player) { Player player2 = player; Inventory inventory = ((Humanoid)player2).GetInventory(); return CreateMaterialSession().AcceptAllNeeded(inventory, (ItemData item) => item.m_shared.m_questItem || ((Humanoid)player2).IsItemEquiped(item)); } private int AcceptMaterialFromInventory(Inventory sourceInventory, ItemData item, int requestedAmount) { if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || sourceInventory == null || item == null || requestedAmount <= 0) { return 0; } return CreateMaterialSession().AcceptNeededOnly(sourceInventory, item, requestedAmount); } private void AcceptMaterialAmount(ZoneBlueprintRequirement requirement, int amount) { if (amount > 0) { SetDeposited(requirement.ItemName, GetDeposited(requirement.ItemName) + amount); AddRefundMaterial(requirement, amount); } } private void PlayConfirmSfx() { PlayLocalEffect("vfx_StaminaUpgrade", "confirm"); } private void PlayProgressSfxIfReadyAdvanced(string readyBefore, int acceptedAmount) { if (acceptedAmount > 0) { string b = CaptureReadySignature(); if (!string.Equals(readyBefore, b, StringComparison.Ordinal)) { PlayLocalEffect("sfx_build_hammer_wood", "progress"); } } } private string CaptureReadySignature() { if (_plan == null && !ReloadPlan()) { return ""; } GetReadyEntryIndices(out string signature); return signature; } private void PlayLocalEffect(string prefabName, string label) { //IL_0025: 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) if (!((Object)(object)Player.m_localPlayer == (Object)null)) { GameObject val = FindPrefab(prefabName); if (Object.op_Implicit((Object)(object)val)) { Object.Instantiate(val, ((Component)this).transform.position, Quaternion.identity); } } } private static void GiveOrDropItem(ItemData prototype, int amount, Vector3 dropPosition, bool preferInventory, GameObject? dropPrefab = null) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ZoneMaterialEscrow.GiveOrDropItem(prototype, amount, dropPosition, preferInventory, dropPrefab); } private void UpdatePreview() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) if ((Object)(object)Player.m_localPlayer == (Object)null || _blueprint == null || _plan == null) { return; } RefreshPendingMaterialStyle(); if (!TryGetAnchorTransform(out var position, out var rotation)) { ClearPreview(); return; } string signature; HashSet readyEntryIndices = GetReadyEntryIndices(out signature); if (_previewGhost.HasRoot && string.Equals(signature, _lastReadySignature, StringComparison.Ordinal)) { _previewGhost.SetTransform(position, rotation); } else { RebuildPreview(readyEntryIndices, signature, position, rotation); } } private void RebuildPreview(HashSet? readyEntries = null, string? readySignature = null, Vector3? anchorPosition = null, Quaternion? anchorRotation = null) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0056: 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) //IL_005e: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || _blueprint == null || _plan == null) { return; } Vector3 position = default(Vector3); Quaternion rotation = default(Quaternion); if ((!anchorPosition.HasValue || !anchorRotation.HasValue) && !TryGetAnchorTransform(out position, out rotation)) { ClearPreview(); return; } Vector3 valueOrDefault = anchorPosition.GetValueOrDefault(position); Quaternion valueOrDefault2 = anchorRotation.GetValueOrDefault(rotation); if (readyEntries == null) { readyEntries = GetReadyEntryIndices(out readySignature); } if (readySignature == null) { readySignature = ""; } ClearPreview(); GameObject val = _previewGhost.CreateBlueprint(_blueprint, "HomesteadPlanPreview_" + GetBlueprintName(), valueOrDefault, valueOrDefault2); for (int i = 0; i < val.transform.childCount; i++) { Transform child = val.transform.GetChild(i); if (!readyEntries.Contains(i)) { ApplyPendingMaterial(((Component)child).gameObject); } } RebuildStationPreview(); _lastReadySignature = readySignature; } private void ClearPreview() { _previewGhost.Destroy(); _stationGhost.Destroy(); } private void RebuildStationPreview() { //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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00d4: 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_00d7: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) _stationGhost.Destroy(); if (_blueprint == null || _stationRequirements.Count == 0) { return; } Vector3 position = ((Component)this).transform.position; Quaternion rotation = ((Component)this).transform.rotation; GameObject val = _stationGhost.CreateEmpty("HomesteadPlanStationPreview_" + GetBlueprintName()); float num = 2.75f; float num2 = 360f / (float)Mathf.Max(1, _stationRequirements.Count); for (int i = 0; i < _stationRequirements.Count; i++) { ZoneBlueprintCraftingStationRequirement zoneBlueprintCraftingStationRequirement = _stationRequirements[i]; GameObject val2 = FindPrefab(zoneBlueprintCraftingStationRequirement.PrefabName); if (Object.op_Implicit((Object)(object)val2)) { Vector3 val3 = Quaternion.Euler(0f, num2 * (float)i, 0f) * new Vector3(0f, 0f, 0f - num); Vector3 val4 = position + rotation * val3; val4.y = SampleGroundY(val4.x, val4.z, position.y); GameObject val5 = ZoneBlueprintVisuals.CreatePrefabVisualRoot(val2, "HomesteadStationGhost_" + zoneBlueprintCraftingStationRequirement.PrefabName); val5.transform.SetParent(val.transform, true); val5.transform.position = val4; val5.transform.rotation = rotation * Quaternion.Euler(0f, 180f + num2 * (float)i, 0f); _stationGhost.ApplyMaterial(val5, BlueprintConfig.PreviewGhostColor); } } } private static GameObject? FindPrefab(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { return null; } ZNetScene instance = ZNetScene.instance; object obj = ((instance != null) ? instance.GetPrefab(prefabName) : null); if (obj == null) { obj = PrefabManager.Instance.GetPrefab(prefabName); if (obj == null) { ObjectDB instance2 = ObjectDB.instance; if (instance2 == null) { return null; } obj = instance2.GetItemPrefab(prefabName); } } return (GameObject?)obj; } private static float SampleGroundY(float x, float z, float fallbackY) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return fallbackY; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(x, fallbackY, z); Vector3 val2 = default(Vector3); Biome val3 = default(Biome); BiomeArea val4 = default(BiomeArea); Heightmap val5 = default(Heightmap); ZoneSystem.instance.GetGroundData(ref val, ref val2, ref val3, ref val4, ref val5); return val.y; } private void ApplyPendingMaterial(GameObject root) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) _previewGhost.ApplyMaterial(root, BlueprintConfig.PreviewGhostColor); } private bool RefreshPendingMaterialStyle() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Color previewGhostColor = BlueprintConfig.PreviewGhostColor; string previewStyleSignature = GetPreviewStyleSignature(previewGhostColor); bool result = !string.Equals(previewStyleSignature, _lastPreviewStyleSignature, StringComparison.Ordinal); _lastPreviewStyleSignature = previewStyleSignature; _previewGhost.UpdateMaterialColor(previewGhostColor); _stationGhost.UpdateMaterialColor(previewGhostColor); return result; } private static string GetPreviewStyleSignature(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ColorUtility.ToHtmlStringRGBA(color); } private HashSet GetReadyEntryIndices(out string signature) { HashSet hashSet = new HashSet(); if (_plan == null) { signature = ""; return hashSet; } Dictionary budget = GetDepositedMaterials(); if (!TryGetAnchorTransform(out var anchor, out var _)) { signature = ""; return hashSet; } foreach (var item4 in (from item in _plan.Entries.Select((ZoneBlueprintCommands.BlueprintLoadEntry entry, int index) => (entry, index)) orderby item.entry.Position.y select item).ThenBy<(ZoneBlueprintCommands.BlueprintLoadEntry, int), float>(delegate((ZoneBlueprintCommands.BlueprintLoadEntry entry, int index) item) { //IL_0006: 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_0016: 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_001d: 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: Unknown result type (might be due to invalid IL or missing references) Vector3 val = item.entry.Position - anchor; return val.x * val.x + val.z * val.z; }).ThenBy<(ZoneBlueprintCommands.BlueprintLoadEntry, int), int>(((ZoneBlueprintCommands.BlueprintLoadEntry entry, int index) item) => item.index)) { ZoneBlueprintCommands.BlueprintLoadEntry item2 = item4.Item1; int item3 = item4.Item2; Dictionary entryRequirements = GetEntryRequirements(item2); if (entryRequirements.Any((KeyValuePair pair) => !budget.TryGetValue(pair.Key, out var value) || value < pair.Value)) { continue; } foreach (KeyValuePair item5 in entryRequirements) { budget[item5.Key] -= item5.Value; } hashSet.Add(item3); } signature = string.Join(",", hashSet.OrderBy((int index) => index)); return hashSet; } private static Dictionary GetEntryRequirements(ZoneBlueprintCommands.BlueprintLoadEntry entry) { Dictionary dictionary = new Dictionary(); Piece component = entry.Prefab.GetComponent(); if ((Object)(object)component == (Object)null) { return dictionary; } Requirement[] resources = component.m_resources; foreach (Requirement val in resources) { if (Object.op_Implicit((Object)(object)val.m_resItem) && val.m_amount > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; dictionary.TryGetValue(name, out var value); dictionary[name] = value + val.GetAmount(0); } } return dictionary; } private IEnumerable GetMissingRequirements() { return CreateMaterialSession().GetMissingRequirements(); } public List GetMissingRequirementList() { return GetMissingRequirements().ToList(); } public bool IsComplete() { return GetDepositedTotal() >= GetRequiredTotal(); } private int GetRequiredTotal() { return _requirements.Sum((ZoneBlueprintRequirement requirement) => requirement.Amount); } private int GetDepositedTotal() { return _requirements.Sum((ZoneBlueprintRequirement requirement) => Mathf.Min(requirement.Amount, GetDeposited(requirement.ItemName))); } private Dictionary GetDepositedMaterials() { Dictionary dictionary = new Dictionary(); foreach (ZoneBlueprintRequirement requirement in _requirements) { dictionary[requirement.ItemName] = GetDeposited(requirement.ItemName); } return dictionary; } private int GetDeposited(string itemName) { ZNetView? nview = _nview; if (((nview != null) ? nview.GetZDO() : null) == null) { return 0; } return _nview.GetZDO().GetInt("hs_plan_material_" + itemName, 0); } private ZoneMaterialEscrow.Session CreateMaterialSession() { return new ZoneMaterialEscrow.Session(_requirements, GetDeposited, AcceptMaterialAmount); } private void SetDeposited(string itemName, int amount) { ZNetView? nview = _nview; if (nview != null) { ZDO zDO = nview.GetZDO(); if (zDO != null) { zDO.Set("hs_plan_material_" + itemName, Mathf.Max(0, amount)); } } } private void ClearDepositedMaterials() { foreach (ZoneBlueprintRequirement requirement in _requirements) { SetDeposited(requirement.ItemName, 0); } ClearRefundMaterials(); } private void AddRefundMaterial(ZoneBlueprintRequirement requirement, int amount) { ZoneBlueprintRequirement requirement2 = requirement; if (amount > 0) { ZNetView? nview = _nview; if (((nview != null) ? nview.GetZDO() : null) != null) { List list = ReadRefundMaterials(); RefundMaterial refundMaterial = list.FirstOrDefault((RefundMaterial item) => item.ItemName == requirement2.ItemName); if (refundMaterial == null) { refundMaterial = new RefundMaterial { ItemName = requirement2.ItemName, PrefabName = requirement2.PrefabName }; list.Add(refundMaterial); } if (string.IsNullOrWhiteSpace(refundMaterial.PrefabName)) { refundMaterial.PrefabName = requirement2.PrefabName; } refundMaterial.Amount += amount; WriteRefundMaterials(list); LogRefundInfo($"Recorded refund material: {requirement2.ItemName} prefab={refundMaterial.PrefabName} added={amount} total={refundMaterial.Amount}."); return; } } string itemName = requirement2.ItemName; object arg = amount; ZNetView? nview2 = _nview; LogRefundDebug($"Skipped refund ledger add for '{itemName}'. amount={arg}, zdo={((nview2 != null) ? nview2.GetZDO() : null) != null}."); } private List ReadRefundMaterials() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown ZNetView? nview = _nview; ZDO val = ((nview != null) ? nview.GetZDO() : null); if (val == null) { LogRefundDebug("Read refund ledger skipped: no ZDO."); return new List(); } string @string = val.GetString("hs_plan_refund_payload", ""); if (string.IsNullOrWhiteSpace(@string)) { LogRefundDebug("Read refund ledger: empty payload."); return new List(); } try { ZPackage val2 = new ZPackage(@string); int num = val2.ReadInt(); if (num != 1) { LogRefundInfo($"Read refund ledger: unsupported version {num}."); return new List(); } int num2 = val2.ReadInt(); List list = new List(num2); for (int i = 0; i < num2; i++) { list.Add(new RefundMaterial { ItemName = val2.ReadString(), PrefabName = val2.ReadString(), Amount = val2.ReadInt() }); } LogRefundInfo($"Read refund ledger: {list.Count} material entries, total={list.Sum((RefundMaterial item) => item.Amount)}."); return list; } catch (Exception ex) { LogRefundInfo("Failed to read refund payload: " + ex.Message); return new List(); } } private void WriteRefundMaterials(IEnumerable materials) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown ZNetView? nview = _nview; ZDO val = ((nview != null) ? nview.GetZDO() : null); if (val == null) { LogRefundDebug("Write refund ledger skipped: no ZDO."); return; } List list = materials.Where((RefundMaterial item) => item.Amount > 0 && !string.IsNullOrWhiteSpace(item.ItemName)).OrderBy((RefundMaterial item) => item.ItemName, StringComparer.Ordinal).ToList(); if (list.Count == 0) { val.Set("hs_plan_refund_payload", ""); LogRefundDebug("Cleared refund ledger payload."); return; } ZPackage val2 = new ZPackage(); val2.Write(1); val2.Write(list.Count); foreach (RefundMaterial item in list) { val2.Write(item.ItemName); val2.Write(item.PrefabName); val2.Write(item.Amount); } val.Set("hs_plan_refund_payload", val2.GetBase64()); LogRefundDebug($"Wrote refund ledger: {list.Count} entries, total={list.Sum((RefundMaterial item) => item.Amount)}."); } private void ClearRefundMaterials() { ZNetView? nview = _nview; if (nview != null) { ZDO zDO = nview.GetZDO(); if (zDO != null) { zDO.Set("hs_plan_refund_payload", ""); } } LogRefundDebug("Refund ledger cleared."); } private string GetBlueprintName() { ZNetView? nview = _nview; if (((nview != null) ? nview.GetZDO() : null) == null) { return ""; } return _nview.GetZDO().GetString("hs_blueprint_name", ""); } private bool TryGetAnchorTransform(out Vector3 position, out Quaternion rotation) { //IL_0001: 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_0052: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00a1: Unknown result type (might be due to invalid IL or missing references) position = default(Vector3); rotation = default(Quaternion); ZNetView? nview = _nview; if (((nview != null) ? nview.GetZDO() : null) == null) { return false; } ZDO zDO = _nview.GetZDO(); position = new Vector3(ReadRequiredFloat(zDO, "hs_anchor_x"), ReadRequiredFloat(zDO, "hs_anchor_y"), ReadRequiredFloat(zDO, "hs_anchor_z")); rotation = new Quaternion(ReadRequiredFloat(zDO, "hs_anchor_rot_x"), ReadRequiredFloat(zDO, "hs_anchor_rot_y"), ReadRequiredFloat(zDO, "hs_anchor_rot_z"), ReadRequiredFloat(zDO, "hs_anchor_rot_w")); if (ZoneTransformPayload.IsFinite(position)) { return ZoneTransformPayload.IsFinite(rotation); } return false; } private static float ReadRequiredFloat(ZDO zdo, string key) { return zdo.GetFloat(key, float.NaN); } private void OnDestroyed() { ReleaseAzuCraftyBoxesContainer("PlanChest.WearNTear.m_onDestroyed"); TryRefundDepositedMaterials("WearNTear.m_onDestroyed"); } internal void HandleDestroyPrefix(string source) { ReleaseAzuCraftyBoxesContainer(source); TryRefundDepositedMaterials(source); } private void ReleaseAzuCraftyBoxesContainer(string source) { AzuCraftyBoxesCompat.RemoveContainer((Container?)(((Object)(object)_container != (Object)null && Object.op_Implicit((Object)(object)_container)) ? ((object)_container) : ((object)((Component)this).GetComponent())), source); } private void TryRefundDepositedMaterials(string source) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) if (_refundStarted || (Object)(object)_nview == (Object)null) { LogRefundDebug($"{source}: skipped refund. started={_refundStarted}, nview={(Object)(object)_nview != (Object)null}."); return; } ZDO zDO = _nview.GetZDO(); if (zDO == null || zDO.GetBool("hs_plan_confirmed", false)) { LogRefundDebug(string.Format("{0}: skipped refund. zdo={1}, confirmed={2}.", source, zDO != null, (zDO != null) ? new bool?(zDO.GetBool("hs_plan_confirmed", false)) : null)); return; } if (_nview.IsValid() && !_nview.IsOwner()) { LogRefundDebug($"{source}: skipped refund because this peer is not owner. valid={_nview.IsValid()}."); return; } _refundStarted = true; LogRefundInfo(string.Format("{0}: refund starting at {1}. valid={2}, owner={3}, payloadBytes={4}.", source, ((Component)this).transform.position, _nview.IsValid(), _nview.IsOwner(), zDO.GetString("hs_plan_refund_payload", "").Length)); try { RefundDepositedMaterials(source); } catch (Exception arg) { HomesteadPlugin.HomesteadLogger.LogWarning((object)$"Blueprint refund failed during {source}: {arg}"); } } private void RefundDepositedMaterials(string source) { //IL_0045: 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_0091: Unknown result type (might be due to invalid IL or missing references) List list = ReadRefundMaterials(); if (list.All((RefundMaterial material) => material.Amount <= 0)) { LogRefundInfo("Refund skipped: no deposited materials found."); return; } ClearDepositedMaterials(); Vector3 position = ((Component)this).transform.position; LogRefundInfo($"Queueing refund materials from {source}: entries={list.Count}, total={list.Sum((RefundMaterial material) => material.Amount)}."); ScheduleRefundDrop(list, position, source); } private static void ScheduleRefundDrop(List refundMaterials, Vector3 dropPosition, string source) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)HomesteadPlugin.Instance != (Object)null) { ((MonoBehaviour)HomesteadPlugin.Instance).StartCoroutine(DropRefundMaterialsDeferred(refundMaterials, dropPosition, source)); } else { DropRefundMaterials(refundMaterials, dropPosition, source); } } [IteratorStateMachine(typeof(d__103))] private static IEnumerator DropRefundMaterialsDeferred(List refundMaterials, Vector3 dropPosition, string source) { //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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__103(0) { refundMaterials = refundMaterials, dropPosition = dropPosition, source = source }; } private static void DropRefundMaterials(IEnumerable refundMaterials, Vector3 dropPosition, string source) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) LogRefundInfo("Dropping queued refund materials from " + source + "."); foreach (RefundMaterial refundMaterial in refundMaterials) { if (refundMaterial.Amount > 0) { GameObject val = FindPrefab(refundMaterial.PrefabName); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent() : null); if ((Object)(object)val2 == (Object)null) { HomesteadPlugin.HomesteadLogger.LogWarning((object)("Failed to refund Homestead blueprint material '" + refundMaterial.ItemName + "': prefab '" + refundMaterial.PrefabName + "' was not found.")); } else { LogRefundInfo($"Dropping refund material '{refundMaterial.ItemName}' prefab={refundMaterial.PrefabName} amount={refundMaterial.Amount}."); GiveOrDropItem(val2.m_itemData, refundMaterial.Amount, dropPosition, preferInventory: false, val); } } } } private static void LogRefundInfo(string message) { } private static void LogRefundDebug(string message) { } public void DrawRequirementOverlay(InventoryGrid grid) { if (!((Object)(object)grid == (Object)null) && ReloadPlan()) { ZoneMaterialEscrow.DrawRequirementOverlay(grid, GetMissingRequirementList(), "hs_blueprint_requirement_tooltip"); } } public static bool TryGetAnchor(Container? container, out ZoneBlueprintPlanAnchor anchor) { anchor = null; if (!Object.op_Implicit((Object)(object)container)) { return false; } anchor = ((Component)container).GetComponent(); if ((Object)(object)anchor != (Object)null) { return anchor.ReloadPlan(); } return false; } private static void Message(Player player, string message, MessageType type) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) HomesteadPlugin.HomesteadLogger.LogInfo((object)message); ((Character)player).Message(type, message, 0, (Sprite)null); } private static string FormatShortcut(KeyboardShortcut shortcut) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) string text = ConfigValueHelpers.FormatShortcut(shortcut); if (!string.Equals(text, "None", StringComparison.OrdinalIgnoreCase)) { return text; } return "Unbound"; } } internal static class ZoneBlueprintPlanChestPrefab { internal const string PrefabName = "piece_chest_wood_blueprint"; private const string BasePrefabName = "piece_chest_wood"; internal static readonly int PrefabHash = StringExtensionMethods.GetStableHashCode("piece_chest_wood_blueprint"); private static ManualLogSource? _logger; private static bool _initialized; private static bool _registered; public static void Initialize(ManualLogSource logger) { _logger = logger; if (!_initialized) { _initialized = true; PrefabManager.OnVanillaPrefabsAvailable += RegisterPrefab; RegisterPrefab(); } } public static HomesteadCommandResult PlacePlanChest(string blueprintName, Player player, Vector3 anchor, Quaternion anchorRotation, Vector3 chestPosition, Quaternion chestRotation) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) long playerID = player.GetPlayerID(); return PlacePlanChest(blueprintName, playerID, HomesteadPlayerIdentity.ResolveLocalPlatformId(playerID), anchor, anchorRotation, chestPosition, chestRotation, 0L); } public static HomesteadCommandResult PlacePlanChest(string blueprintName, long playerId, string ownerPlatformId, Vector3 anchor, Quaternion anchorRotation, Vector3 chestPosition, Quaternion chestRotation, long vfxExcludePeer = 0L) { //IL_0038: 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_0092: 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_00b5: 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) RegisterPrefab(); if (!ZoneBlueprintChestLifecycle.CanPlaceChests(ownerPlatformId, 1, out string reason)) { return HomesteadCommandResult.Fail(reason); } GameObject prefab = GetPrefab(); if (!Object.op_Implicit((Object)(object)prefab)) { return HomesteadCommandResult.Fail(HomesteadLocalization.Text("hs_blueprint_chest_prefab_not_ready")); } GameObject val = null; try { val = Object.Instantiate(prefab, chestPosition, chestRotation); Piece component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.SetCreator(playerId); } ZNetView component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null && component2.IsValid()) { ZoneBlueprintChestLifecycle.SetOwnerPlatformId(component2.GetZDO(), ownerPlatformId); } (val.GetComponent() ?? val.AddComponent()).SetPlan(blueprintName, anchor, anchorRotation); ZoneChestPlacement.PlayPlaceEffect(val); ZoneChestPlacement.SafeOnPlaced(val, _logger, "Blueprint chest"); ZoneBlueprintChestVfx.BroadcastPlace("plan", ZoneTransformPayload.From(chestPosition, chestRotation), vfxExcludePeer); ZoneLimitCompat.RebuildCounts(); return HomesteadCommandResult.Ok(HomesteadLocalization.Format("hs_blueprint_chest_placed", blueprintName)); } catch (Exception ex) { ZoneChestPlacement.DestroySpawned(val); return HomesteadCommandResult.Fail(HomesteadLocalization.Format("hs_blueprint_chest_place_failed", ex.Message)); } } public static GameObject? CreatePreview() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown RegisterPrefab(); GameObject prefab = GetPrefab(); if (!Object.op_Implicit((Object)(object)prefab)) { return null; } GameObject val = new GameObject("HomesteadBlueprintChestPreview"); if (ZoneBlueprintVisuals.CopyVisuals(prefab.transform, val.transform) == 0) { Object.Destroy((Object)(object)val); return null; } return val; } private static GameObject? GetPrefab() { GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_wood_blueprint"); if (prefab == null) { ZNetScene instance = ZNetScene.instance; if (instance == null) { return null; } prefab = instance.GetPrefab("piece_chest_wood_blueprint"); } return prefab; } internal static Sprite? GetIcon() { RegisterPrefab(); GameObject? prefab = GetPrefab(); if (prefab == null) { return null; } return prefab.GetComponent()?.m_icon; } public static bool PlayPlaceEffect(Vector3 position, Quaternion rotation) { //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) RegisterPrefab(); return ZoneChestPlacement.PlayPlaceEffect(GetPrefab(), position, rotation); } private static void RegisterPrefab() { if (_registered) { return; } if (Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab("piece_chest_wood_blueprint"))) { _registered = true; return; } if (!Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab("piece_chest_wood"))) { ZNetScene instance = ZNetScene.instance; if (!Object.op_Implicit((Object)(object)((instance != null) ? instance.GetPrefab("piece_chest_wood") : null))) { return; } } GameObject val = PrefabManager.Instance.CreateClonedPrefab("piece_chest_wood_blueprint", "piece_chest_wood"); if (Object.op_Implicit((Object)(object)val)) { ConfigurePrefab(val); PrefabManager.Instance.AddPrefab(val); PrefabManager.Instance.RegisterToZNetScene(val); _registered = true; ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)"Registered Homestead blueprint chest prefab."); } } } private static void ConfigurePrefab(GameObject prefab) { //IL_0038: 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_0048: Expected O, but got Unknown Container component = prefab.GetComponent(); if ((Object)(object)component != (Object)null) { component.m_name = HomesteadLocalization.Token("hs_blueprint_chest_name"); component.m_width = 8; component.m_height = 40; component.m_autoDestroyEmpty = false; component.m_privacy = (PrivacySetting)2; component.m_defaultItems = new DropTable(); } Piece component2 = prefab.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.m_name = HomesteadLocalization.Token("hs_blueprint_chest_name"); component2.m_description = HomesteadLocalization.Token("hs_blueprint_chest_desc"); component2.m_resources = Array.Empty(); } if ((Object)(object)prefab.GetComponent() == (Object)null) { prefab.AddComponent(); } } } internal static class ZoneBlueprintPreviewBuilder { private readonly struct VisualDescriptor { public string Name { get; } public Mesh Mesh { get; } public Material[] Materials { get; } public bool Skinned { get; } public Vector3 LocalPosition { get; } public Quaternion LocalRotation { get; } public Vector3 LocalScale { get; } public VisualDescriptor(string name, Mesh mesh, Material[] materials, bool skinned, Vector3 localPosition, Quaternion localRotation, Vector3 localScale) { //IL_001e: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) Name = name; Mesh = mesh; Materials = materials; Skinned = skinned; LocalPosition = localPosition; LocalRotation = localRotation; LocalScale = localScale; } } private static readonly Dictionary> VisualCache = new Dictionary>(StringComparer.OrdinalIgnoreCase); public static GameObject? CreateVisualPreview(GameObject prefab, Vector3 localPosition, Quaternion localRotation, Vector3 scale, int index, Transform parent) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_003c: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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) List visuals = GetVisuals(prefab); if (visuals.Count == 0) { return null; } GameObject val = new GameObject($"HomesteadBlueprintPreview_{index:D3}"); val.transform.SetParent(parent, false); val.transform.localPosition = localPosition; val.transform.localRotation = localRotation; val.transform.localScale = scale; foreach (VisualDescriptor item in visuals) { GameObject val2 = new GameObject(item.Name); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = item.LocalPosition; val2.transform.localRotation = item.LocalRotation; val2.transform.localScale = item.LocalScale; if (item.Skinned) { SkinnedMeshRenderer obj = val2.AddComponent(); obj.sharedMesh = item.Mesh; ((Renderer)obj).sharedMaterials = item.Materials; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; } else { MeshFilter val3 = val2.AddComponent(); MeshRenderer obj2 = val2.AddComponent(); val3.sharedMesh = item.Mesh; ((Renderer)obj2).sharedMaterials = item.Materials; ((Renderer)obj2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj2).receiveShadows = false; } } return val; } public static void ClearCache() { VisualCache.Clear(); } private static List GetVisuals(GameObject prefab) { string prefabName = Utils.GetPrefabName(prefab); if (VisualCache.TryGetValue(prefabName, out List value)) { return value; } List list = new List(); CollectVisuals(prefab.transform, prefab.transform, list); VisualCache[prefabName] = list; return list; } private static void CollectVisuals(Transform root, Transform source, List visuals) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown if (!((Component)source).gameObject.activeSelf) { return; } MeshFilter component = ((Component)source).GetComponent(); MeshRenderer component2 = ((Component)source).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null && (Object)(object)component2 != (Object)null && ((Renderer)component2).enabled) { visuals.Add(CreateDescriptor(root, source, component.sharedMesh, ((Renderer)component2).sharedMaterials, skinned: false)); } SkinnedMeshRenderer component3 = ((Component)source).GetComponent(); if ((Object)(object)component3 != (Object)null && (Object)(object)component3.sharedMesh != (Object)null && ((Renderer)component3).enabled) { visuals.Add(CreateDescriptor(root, source, component3.sharedMesh, ((Renderer)component3).sharedMaterials, skinned: true)); } foreach (Transform item in source) { Transform source2 = item; CollectVisuals(root, source2, visuals); } } private static VisualDescriptor CreateDescriptor(Transform root, Transform source, Mesh mesh, Material[] materials, bool skinned) { //IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0028: Unknown result type (might be due to invalid IL or missing references) Decompose(root.worldToLocalMatrix * source.localToWorldMatrix, out var position, out var rotation, out var scale); return new VisualDescriptor(((Object)source).name, mesh, materials, skinned, position, rotation, scale); } private static void Decompose(Matrix4x4 matrix, out Vector3 position, out Quaternion rotation, out Vector3 scale) { //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_000d: 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_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_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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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) Vector3 val = Vector4.op_Implicit(((Matrix4x4)(ref matrix)).GetColumn(0)); Vector3 val2 = Vector4.op_Implicit(((Matrix4x4)(ref matrix)).GetColumn(1)); Vector3 val3 = Vector4.op_Implicit(((Matrix4x4)(ref matrix)).GetColumn(2)); position = Vector4.op_Implicit(((Matrix4x4)(ref matrix)).GetColumn(3)); scale = new Vector3(((Vector3)(ref val)).magnitude, ((Vector3)(ref val2)).magnitude, ((Vector3)(ref val3)).magnitude); rotation = ((((Vector3)(ref val3)).sqrMagnitude > 1E-06f && ((Vector3)(ref val2)).sqrMagnitude > 1E-06f) ? Quaternion.LookRotation(val3, val2) : Quaternion.identity); } } internal sealed class ZoneBlueprintSaveTool : MonoBehaviour { private sealed class SaveSelection { public Vector3 Anchor { get; } public Quaternion AnchorRotation { get; } public float Radius { get; } public List Zdos { get; } public SaveSelection(Vector3 anchor, Quaternion anchorRotation, float radius, List zdos) { //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_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) Anchor = anchor; AnchorRotation = anchorRotation; Radius = radius; Zdos = zdos; } } [CompilerGenerated] private sealed class <>c__DisplayClass73_0 { public Sprite icon; public bool renderFinished; internal void b__0(Sprite? renderedIcon) { icon = renderedIcon; renderFinished = true; } } [CompilerGenerated] private sealed class d__59 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public SaveSelection selection; public IReadOnlyList zdos; public ZoneBlueprintSaveTool <>4__this; public GameObject root; private Quaternion 5__2; private int 5__3; private IEnumerator <>7__wrap3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__59(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap3 = null; <>1__state = -2; } private bool MoveNext() { //IL_002d: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00d4: 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) //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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) bool result; try { int num = <>1__state; ZoneBlueprintSaveTool zoneBlueprintSaveTool = <>4__this; switch (num) { default: result = false; goto end_IL_0000; case 0: <>1__state = -1; 5__2 = Quaternion.Inverse(selection.AnchorRotation); 5__3 = 0; <>7__wrap3 = zdos.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (true) { if (<>7__wrap3.MoveNext()) { ZDO current = <>7__wrap3.Current; if (zoneBlueprintSaveTool._selection != selection || (Object)(object)zoneBlueprintSaveTool._selectionPreviewRoot != (Object)(object)root) { zoneBlueprintSaveTool._previewBuildCoroutine = null; result = false; <>m__Finally1(); break; } if (ZoneBlueprintCommands.TryReadSavableWearNTear(current, out GameObject prefab)) { Vector3 vec = current.GetVec3(ZDOVars.s_scaleHash, prefab.transform.localScale); Vector3 localPosition = 5__2 * (current.GetPosition() - selection.Anchor); Quaternion localRotation = 5__2 * current.GetRotation(); GameObject val = zoneBlueprintSaveTool.CreateVisualPreview(prefab, localPosition, localRotation, vec, 5__3, zoneBlueprintSaveTool._selectionPreviewRoot.transform); if ((Object)(object)val != (Object)null) { zoneBlueprintSaveTool._previewVisuals.Add(val); } 5__3++; if (5__3 % 64 == 0) { <>2__current = null; <>1__state = 1; result = true; break; } } continue; } <>m__Finally1(); <>7__wrap3 = null; zoneBlueprintSaveTool._previewBuildCoroutine = null; result = false; break; } end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap3 != null) { <>7__wrap3.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__73 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZoneBlueprintSaveTool <>4__this; private <>c__DisplayClass73_0 <>8__1; private Stopwatch 5__2; private string 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__73(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Expected O, but got Unknown int num = <>1__state; ZoneBlueprintSaveTool zoneBlueprintSaveTool = <>4__this; ManualLogSource? logger2; switch (num) { default: return false; case 0: <>1__state = -1; goto IL_0234; case 1: <>1__state = -1; goto IL_0234; case 2: <>1__state = -1; goto IL_0234; case 3: <>1__state = -1; goto IL_0188; case 4: { <>1__state = -1; <>8__1 = null; 5__2 = null; 5__3 = null; goto IL_0234; } IL_0234: if (zoneBlueprintSaveTool._iconRenderQueue.Count > 0) { <>8__1 = new <>c__DisplayClass73_0(); if (ShouldDelayIconRenderForPlacement()) { <>2__current = (object)new WaitForSecondsRealtime(1f); <>1__state = 1; return true; } 5__2 = Stopwatch.StartNew(); 5__3 = zoneBlueprintSaveTool._iconRenderQueue.Dequeue(); zoneBlueprintSaveTool._queuedIconRenders.Remove(5__3); if (!zoneBlueprintSaveTool._queuedIconBlueprints.TryGetValue(5__3, out ZoneBlueprintFile value) && !ZoneBlueprintCommands.TryLoadBlueprint(5__3, out value)) { zoneBlueprintSaveTool._queuedIconBlueprints.Remove(5__3); <>2__current = null; <>1__state = 2; return true; } zoneBlueprintSaveTool._queuedIconBlueprints.Remove(5__3); <>8__1.icon = null; <>8__1.renderFinished = false; try { ZoneBlueprintVisuals.EnqueueRenderAndCacheIcon(5__3, value, delegate(Sprite? renderedIcon) { <>8__1.icon = renderedIcon; <>8__1.renderFinished = true; }); } catch (Exception ex) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogWarning((object)("Failed to render Homestead blueprint icon '" + 5__3 + "': " + ex.Message)); } <>8__1.renderFinished = true; } goto IL_0188; } zoneBlueprintSaveTool._iconRenderCoroutine = null; return false; IL_0188: if (!<>8__1.renderFinished) { <>2__current = null; <>1__state = 3; return true; } ZoneBlueprintSaveToolMenu.ApplyBlueprintIcon(5__3, <>8__1.icon); 5__2.Stop(); logger2 = _logger; if (logger2 != null) { logger2.LogDebug((object)$"Homestead blueprint icon render completed for '{5__3}' in {5__2.Elapsed.TotalMilliseconds:0.0} ms; queued={zoneBlueprintSaveTool._iconRenderQueue.Count}."); } <>2__current = (object)new WaitForSecondsRealtime(1.25f); <>1__state = 4; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const float MinSideLength = 2f; private const float SizeStep = 2f; private const float PreviewLift = 4f; private const int PreviewBuildBatchSize = 64; private const int SaveNameMaxLength = 64; private const float TargetOverlayRefreshInterval = 0.3f; private const float IconRenderIntervalSeconds = 1.25f; private const float IconRenderPlacementDelaySeconds = 1f; private static ManualLogSource? _logger; private static ZoneBlueprintSaveTool? _instance; private static float? _lastAreaYaw; private readonly List _previewVisuals = new List(); private readonly List _nearbyTargetZdos = new List(); private readonly List _targetCandidateZdos = new List(); private readonly Queue _iconRenderQueue = new Queue(); private readonly HashSet _queuedIconRenders = new HashSet(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _queuedIconBlueprints = new Dictionary(StringComparer.OrdinalIgnoreCase); private ZoneAreaToolController? _areaTool; private GameObject? _selectionPreviewRoot; private SaveSelection? _selection; private Coroutine? _iconRenderCoroutine; private Coroutine? _previewBuildCoroutine; private bool _active; private GameObject? _savePanel; private InputField? _saveNameInput; private Text? _saveCountText; private Text? _saveStatusText; private string _saveName = ""; private string _saveStatus = ""; private bool _focusSaveName; private bool _saveInputBlocked; private float _selectionPreviewYawOffset; public static bool HasSelection => _instance?._selection != null; public static bool IsActive { get { ZoneBlueprintSaveTool? instance = _instance; if (instance == null) { return false; } return (instance._areaTool?.Active).GetValueOrDefault(); } } private static float MaxSelectableSide => Mathf.Max(2f, BlueprintConfig.AreaSaveMaxSide); private ZoneAreaToolController AreaTool => _areaTool ?? (_areaTool = new ZoneAreaToolController((MonoBehaviour)(object)this, new ZoneAreaToolController.Options { MinSide = 2f, SizeStep = 2f, MaxSide = () => MaxSelectableSide, DefaultWidth = () => BlueprintConfig.AreaSaveDefaultWidth, DefaultDepth = () => BlueprintConfig.AreaSaveDefaultDepth, Color = () => BlueprintConfig.AreaSaveBoundaryColor, RangeLineName = "HomesteadBlueprintRadius", TargetOverlayName = "HomesteadAreaSaveTarget", TargetOverlayRefreshInterval = 0.3f, GetSavedYaw = () => _lastAreaYaw, SetSavedYaw = delegate(float yaw) { _lastAreaYaw = yaw; }, IsLocked = () => _selection != null, GetEffectiveYaw = (float yaw) => (_selection != null) ? ZoneAreaSelection.NormalizeYaw(yaw + _selectionPreviewYawOffset) : yaw, OnLockedScroll = delegate(float scroll) { float num = ((scroll > 0f) ? PlacementControlConfig.RotationStep : (0f - PlacementControlConfig.RotationStep)); _selectionPreviewYawOffset = ZoneAreaSelection.NormalizeYaw(_selectionPreviewYawOffset + num); }, OnFrame = delegate { UpdateSelectionPreview(); UpdateSavePanel(); }, ShouldBlockToolInput = () => _selection != null && IsSaveNameInputFocused(), StatusTitle = () => (_selection != null) ? HomesteadLocalization.Text("hs_area_save_preview_name") : HomesteadLocalization.Text("hs_area_save_name"), FindCandidates = FindSaveBoundaryPreviewCandidates, OnClick = PickSelection })); public static void Initialize(ManualLogSource logger) { _logger = logger; ZoneBlueprintSaveToolMenu.Initialize(); EnsureInstance(); } public static void Activate(Player player) { EnsureInstance(); _instance?.ActivateInternal(player); } public static void Deactivate() { _instance?.DeactivateInternal(); } public static void ClearSelection() { _instance?.ClearSelectionInternal(); } public static void QueueMenuRefresh(string blueprintName) { EnsureInstance(); ZoneBlueprintSaveToolMenu.RequestHammerTableRefresh(blueprintName); } public static void QueueIconRender(string blueprintName, ZoneBlueprintFile? blueprint = null) { EnsureInstance(); _instance?.QueueIconRenderInternal(blueprintName, blueprint); } public static bool TryGetSelectedBlueprint(string name, Player player, out ZoneBlueprintFile blueprint, out string reason) { //IL_0087: 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_0092: 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_00e8: Unknown result type (might be due to invalid IL or missing references) blueprint = null; reason = ""; if (_instance?._selection == null) { reason = HomesteadLocalization.Format("hs_blueprint_no_preview_selected", "Wheel", ZoneAreaToolShared.FormatScaleInput(), ZoneAreaToolShared.FormatDepthInput(), ZoneAreaToolShared.FormatWidthInput()); return false; } if (ZDOMan.instance == null) { reason = HomesteadLocalization.Text("hs_common_world_not_ready"); return false; } SaveSelection selection = _instance._selection; List list = new List(); foreach (ZDOID zdo in selection.Zdos) { ZDO zDO = ZDOMan.instance.GetZDO(zdo); if (zDO != null && zDO.IsValid()) { list.Add(zDO); } } if (list.Count == 0) { reason = HomesteadLocalization.Text("hs_blueprint_preview_invalid"); return false; } blueprint = ZoneBlueprintCommands.CaptureBlueprintFromZdos(name, player, selection.Anchor, selection.AnchorRotation, list, selection.Radius); return true; } private static void EnsureInstance() { //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 if (!((Object)(object)_instance != (Object)null) || !Object.op_Implicit((Object)(object)_instance)) { GameObject val = new GameObject("HomesteadBlueprintSaveTool"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void ActivateInternal(Player player) { _active = true; AreaTool.Activate(player); } private void DeactivateInternal() { _active = false; _areaTool?.Deactivate(); _saveStatus = ""; _focusSaveName = false; _selectionPreviewYawOffset = 0f; SetSaveUiInputBlocked(blocked: false); SetSavePanelVisible(visible: false); _selection = null; ClearPreviewLines(); } private void ClearSelectionInternal() { _selection = null; _saveStatus = ""; _focusSaveName = false; _selectionPreviewYawOffset = 0f; _areaTool?.ResetOffsets(); SetSaveUiInputBlocked(blocked: false); SetSavePanelVisible(visible: false); ClearPreviewLines(); ZoneAreaToolStatusHud.Hide(); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, HomesteadLocalization.Text("hs_blueprint_preview_cleared"), 0, (Sprite)null); } } private void Update() { if (!_active) { ZoneAreaToolController? areaTool = _areaTool; if (areaTool == null || !areaTool.Active) { return; } } if (!AreaTool.Tick()) { DeactivateInternal(); } } private void OnDestroy() { SetSaveUiInputBlocked(blocked: false); DestroySavePanel(); _areaTool?.Destroy(); _areaTool = null; ClearPreviewLines(); if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } private void PickSelection(Player player) { PickSelection(player, AreaTool.CurrentArea); } private void PickSelection(Player player, ZoneAreaSelection area) { //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_006a: 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) if (!AreaTool.HasAimPoint) { return; } BlueprintAreaSaveCreatorMode areaSaveCreatorMode = BlueprintConfig.AreaSaveCreatorMode; List list = ZoneBlueprintCommands.FindBlueprintWearNTearZdos(player, area, areaSaveCreatorMode); if (list.Count == 0) { _selection = null; ClearPreviewLines(); Message(player, HomesteadLocalization.Format("hs_blueprint_no_targets_in_area", BlueprintConfig.AreaSaveEligibleTargetLabel, AreaTool.FormattedSize)); return; } Quaternion rotation = area.Rotation; _selection = new SaveSelection(area.Center, rotation, area.HalfDiagonal, list.Select((ZDO zdo) => zdo.m_uid).ToList()); _selectionPreviewYawOffset = 0f; _saveName = GenerateDefaultBlueprintName(); _saveStatus = ""; _focusSaveName = false; EnsureSavePanel(); RefreshSavePanel(); SetSavePanelVisible(visible: true); ReleaseSaveNameFocus(); DrawSelectionPreview(list); } private void SaveSelectionFromUi() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { HomesteadCommandResult homesteadCommandResult = ZoneBlueprintCommands.SaveSelectedBlueprint(_saveName, localPlayer); _saveStatus = (homesteadCommandResult.Success ? "Saved." : homesteadCommandResult.Message); Message(localPlayer, homesteadCommandResult.Message, (MessageType)(homesteadCommandResult.Success ? 1 : 2)); if (homesteadCommandResult.Success) { _selection = null; _selectionPreviewYawOffset = 0f; _focusSaveName = false; SetSaveUiInputBlocked(blocked: false); SetSavePanelVisible(visible: false); ClearPreviewLines(); } } } private IReadOnlyList FindSaveBoundaryPreviewCandidates(Player player, ZoneAreaSelection area) { _targetCandidateZdos.Clear(); if (ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)player == (Object)null) { return _targetCandidateZdos; } long playerID = player.GetPlayerID(); if (playerID == 0L) { return _targetCandidateZdos; } ZoneAreaTargetOverlay.CollectNearbyZdos(area, _nearbyTargetZdos); foreach (ZDO nearbyTargetZdo in _nearbyTargetZdos) { if (!ZoneBlueprintCommands.IsHomesteadBlueprintChest(nearbyTargetZdo) && ZoneBlueprintCommands.TryReadSavableWearNTear(nearbyTargetZdo, out GameObject _) && IsLoadedWearNTear(nearbyTargetZdo)) { long @long = nearbyTargetZdo.GetLong(ZDOVars.s_creator, 0L); if (BlueprintConfig.AreaSaveAllowsCreator(playerID, @long)) { _targetCandidateZdos.Add(nearbyTargetZdo); } } } return _targetCandidateZdos; } private static bool IsLoadedWearNTear(ZDO zdo) { if ((Object)(object)ZNetScene.instance == (Object)null) { return false; } ZNetView val = ZNetScene.instance.FindInstance(zdo); if ((Object)(object)val != (Object)null) { return (Object)(object)((Component)val).GetComponent() != (Object)null; } return false; } private void DrawSelectionPreview(IReadOnlyList zdos) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0047: 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_0056: 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) //IL_0076: Unknown result type (might be due to invalid IL or missing references) ClearPreviewLines(); if (_selection != null) { _selectionPreviewRoot = new GameObject("HomesteadBlueprintHeldPreview"); _selectionPreviewRoot.transform.SetParent(((Component)this).transform, false); _selectionPreviewRoot.transform.position = AreaTool.AimPoint + Vector3.up * 4f; _selectionPreviewRoot.transform.rotation = _selection.AnchorRotation; _previewBuildCoroutine = ((MonoBehaviour)this).StartCoroutine(BuildSelectionPreview(zdos.ToList(), _selection, _selectionPreviewRoot)); } } [IteratorStateMachine(typeof(d__59))] private IEnumerator BuildSelectionPreview(IReadOnlyList zdos, SaveSelection selection, GameObject root) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__59(0) { <>4__this = this, zdos = zdos, selection = selection, root = root }; } private void UpdateSelectionPreview() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) //IL_003c: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_selectionPreviewRoot == (Object)null) && _selection != null) { _selectionPreviewRoot.transform.position = AreaTool.AimPoint + Vector3.up * 4f; _selectionPreviewRoot.transform.rotation = _selection.AnchorRotation * Quaternion.Euler(0f, _selectionPreviewYawOffset, 0f); } } private void EnsureSavePanel() { //IL_0046: 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_00a6: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_0100: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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_01bb: 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_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_0246: 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_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Expected O, but got Unknown //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Expected O, but got Unknown //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) if ((!((Object)(object)_savePanel != (Object)null) || !Object.op_Implicit((Object)(object)_savePanel)) && !((Object)(object)GUIManager.CustomGUIFront == (Object)null)) { GUIManager instance = GUIManager.Instance; _savePanel = instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 382f, 214f, true); ((Object)_savePanel).name = "HomesteadBlueprintSavePanel"; Transform transform = _savePanel.transform; instance.CreateText(HomesteadLocalization.Text("hs_blueprint_save_title"), transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -28f), instance.AveriaSerifBold, 20, instance.ValheimOrange, true, Color.black, 320f, 28f, false); _saveCountText = instance.CreateText("", transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -62f), instance.AveriaSerif, 15, instance.ValheimBeige, true, Color.black, 320f, 24f, false).GetComponent(); instance.CreateText(HomesteadLocalization.Text("hs_blueprint_name_label"), transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -88f), instance.AveriaSerifBold, 15, instance.ValheimOrange, true, Color.black, 320f, 22f, false); GameObject val = instance.CreateInputField(transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -122f), (ContentType)0, HomesteadLocalization.Text("hs_blueprint_name_placeholder"), 16, 292f, 34f); _saveNameInput = val.GetComponent(); _saveNameInput.characterLimit = 64; ((UnityEvent)(object)_saveNameInput.onValueChanged).AddListener((UnityAction)delegate(string value) { _saveName = value; }); ((UnityEvent)instance.CreateButton(HomesteadLocalization.Text("hs_common_save"), transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(-76f, -166f), 132f, 34f).GetComponent