Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ChallengeHub BlutEid v2.12.50
BepInEx\plugins\ChallengeHubValheim.BlutEid\ChallengeHubValheim.BlutEid.dll
Decompiled 4 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Net.WebSockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ChallengeHubValheim { internal static class AdvancedQoLFeature { private static Plugin _plugin; private static AdvancedQoLBehaviour _behaviour; private static ConfigEntry<float> _harvestRadius; private static ConfigEntry<int> _harvestMaxTargets; private static ConfigEntry<int> _maxGridSize; private static ConfigEntry<float> _doorCloseDelay; private static ConfigEntry<float> _doorSafetyRadius; private static ConfigEntry<float> _fuelContainerRadius; private static ConfigEntry<int> _storageMaxContainers; private static ConfigEntry<int> _signMaxFontSize; private static readonly float[] RotationSteps = new float[6] { 1f, 5f, 15f, 22.5f, 45f, 90f }; private const string ContainerLockOwnerKey = "ChallengeHub.QoL.LockOwner"; private const string ContainerLockUntilKey = "ChallengeHub.QoL.LockUntil"; internal static float HarvestRadius { get { QoLWebConfig qoLWebConfig = RemoteQol(); if (qoLWebConfig == null || !(qoLWebConfig.harvestRadius > 0f)) { return Mathf.Clamp(_harvestRadius?.Value ?? 7f, 2f, 20f); } return Mathf.Clamp(RemoteQol().harvestRadius, 2f, 20f); } } internal static int HarvestMaxTargets { get { QoLWebConfig qoLWebConfig = RemoteQol(); if (qoLWebConfig == null || qoLWebConfig.harvestMaxTargets <= 0) { return Mathf.Clamp(_harvestMaxTargets?.Value ?? 24, 2, 80); } return Mathf.Clamp(RemoteQol().harvestMaxTargets, 2, 80); } } internal static int MaximumGridSize { get { QoLWebConfig qoLWebConfig = RemoteQol(); if (qoLWebConfig == null || qoLWebConfig.maxPlantGridSize <= 0) { return Mathf.Clamp(_maxGridSize?.Value ?? 5, 2, 5); } return Mathf.Clamp(RemoteQol().maxPlantGridSize, 2, 5); } } internal static float DoorCloseDelay { get { QoLWebConfig qoLWebConfig = RemoteQol(); if (qoLWebConfig == null || !(qoLWebConfig.doorCloseDelaySeconds > 0f)) { return Mathf.Clamp(_doorCloseDelay?.Value ?? 5f, 1f, 60f); } return Mathf.Clamp(RemoteQol().doorCloseDelaySeconds, 1f, 60f); } } internal static float DoorSafetyRadius { get { QoLWebConfig qoLWebConfig = RemoteQol(); if (qoLWebConfig == null || !(qoLWebConfig.doorSafetyRadius > 0f)) { return Mathf.Clamp(_doorSafetyRadius?.Value ?? 1.8f, 0.8f, 5f); } return Mathf.Clamp(RemoteQol().doorSafetyRadius, 0.8f, 5f); } } internal static float FuelContainerRadius { get { QoLWebConfig qoLWebConfig = RemoteQol(); if (qoLWebConfig == null || !(qoLWebConfig.fuelContainerRadius > 0f)) { return Mathf.Clamp(_fuelContainerRadius?.Value ?? 12f, 2f, 30f); } return Mathf.Clamp(RemoteQol().fuelContainerRadius, 2f, 30f); } } internal static int StorageMaxContainers { get { QoLWebConfig qoLWebConfig = RemoteQol(); if (qoLWebConfig == null || qoLWebConfig.storageMaxContainers <= 0) { return Mathf.Clamp(_storageMaxContainers?.Value ?? 20, 1, 40); } return Mathf.Clamp(RemoteQol().storageMaxContainers, 1, 40); } } internal static int SignMaxFontSize { get { QoLWebConfig qoLWebConfig = RemoteQol(); if (qoLWebConfig == null || qoLWebConfig.signMaxFontSize <= 0) { return Mathf.Clamp(_signMaxFontSize?.Value ?? 48, 18, 64); } return Mathf.Clamp(RemoteQol().signMaxFontSize, 18, 64); } } internal static float SwimCriticalStaminaPercent { get { QoLWebConfig qoLWebConfig = RemoteQol(); if (qoLWebConfig == null || !(qoLWebConfig.swimCriticalStaminaPercent > 0f)) { return 0.25f; } return Mathf.Clamp(RemoteQol().swimCriticalStaminaPercent, 0.05f, 0.9f); } } private static QoLWebConfig RemoteQol() { return _plugin?.RemoteConfig?.qol; } internal static void Initialize(Plugin plugin) { if (!((Object)(object)plugin == (Object)null)) { _plugin = plugin; _harvestRadius = ((BaseUnityPlugin)plugin).Config.Bind<float>("QoLSkilltree.Advanced", "AreaHarvestRadius", 7f, "Radius der bewusst mit Alt+Benutzen ausgeloesten Flaechenernte."); _harvestMaxTargets = ((BaseUnityPlugin)plugin).Config.Bind<int>("QoLSkilltree.Advanced", "AreaHarvestMaxTargets", 24, "Maximale Anzahl zusaetzlicher Pickables pro Flaechenernte."); _maxGridSize = ((BaseUnityPlugin)plugin).Config.Bind<int>("QoLSkilltree.Advanced", "MaximumPlantGridSize", 5, "Maximal erlaubte Rastergroesse. Unterstuetzt werden 2, 3 und 5."); _doorCloseDelay = ((BaseUnityPlugin)plugin).Config.Bind<float>("QoLSkilltree.Advanced", "DoorCloseDelaySeconds", 5f, "Verzoegerung des Tuerwaechters."); _doorSafetyRadius = ((BaseUnityPlugin)plugin).Config.Bind<float>("QoLSkilltree.Advanced", "DoorSafetyRadius", 1.8f, "Tuer wird nur geschlossen, wenn kein Spieler in diesem Radius steht."); _fuelContainerRadius = ((BaseUnityPlugin)plugin).Config.Bind<float>("QoLSkilltree.Advanced", "FuelContainerRadius", 12f, "Reichweite berechtigter Lager fuer den Brennstoffhelfer."); _storageMaxContainers = ((BaseUnityPlugin)plugin).Config.Bind<int>("QoLSkilltree.Advanced", "StorageMaxContainers", 20, "Maximale Anzahl Kisten pro bewusst ausgeloestem Lager-Routing."); _signMaxFontSize = ((BaseUnityPlugin)plugin).Config.Bind<int>("QoLSkilltree.Advanced", "SignMaximumFontSize", 48, "Sicheres Schriftgroessenlimit der Schildwerkstatt."); _behaviour = ((Component)plugin).gameObject.GetComponent<AdvancedQoLBehaviour>() ?? ((Component)plugin).gameObject.AddComponent<AdvancedQoLBehaviour>(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Erweiterte QoL-Talente bereit: Lager-Routing, Landwirtschaft, Tueren, Brennstoff, Rotation, Schilder und Schwimm-HUD."); } } } internal static void OnTalentDataChanged() { _behaviour?.OnTalentDataChanged(); } internal static IEnumerator IntelligentStoreNearby() { Player player = Player.m_localPlayer; TalentData data = TalentStore.GetLocalData(); if ((Object)(object)player == (Object)null || data == null || !data.HasSkill("storage.quick_store")) { yield break; } Inventory playerInventory = ((Humanoid)player).GetInventory(); if (playerInventory == null) { yield break; } List<Container> containers = (from container in QoLSkillRuntimeFeature.FindNearbyContainers(((Component)player).transform.position, QoLSkillRuntimeFeature.ContainerRadius) where IsContainerEligible(container, player.GetPlayerID()) select container).Take((!data.HasSkill("storage.stack_nearby")) ? 1 : StorageMaxContainers).ToList(); if (containers.Count == 0) { QoLSkillRuntimeFeature.ShowCenter("Keine berechtigte freie Kiste in Reichweite."); yield break; } int movedItems = 0; HashSet<Container> touched = new HashSet<Container>(); List<ItemData> list = (from item in playerInventory.GetAllItems() where item != null && item.m_stack > 0 && !item.m_equipped && item.m_gridPos.y != 0 where !QoLSkillRuntimeFeature.IsReservedItem(data, playerInventory, item) select item).ToList(); foreach (ItemData source in list) { if (source == null || source.m_stack <= 0) { continue; } string itemKey = QoLSkillRuntimeFeature.ItemKey(source); string group = MaterialGroup(source); List<Container> list2 = (from container in containers select new { Container = container, Score = StorageTargetScore(container.GetInventory(), source, itemKey, @group, data.AllowEmptyStorageTargets) } into entry where entry.Score > 0 orderby entry.Score descending, Vector3.Distance(((Component)player).transform.position, ((Component)entry.Container).transform.position) select entry.Container).ToList(); foreach (Container item in list2) { if (source.m_stack <= 0) { break; } Inventory inventory = item.GetInventory(); if (inventory != null) { inventory.CanAddItem(source, source.m_stack); } if (!TryAcquireContainerLock(item, player.GetPlayerID())) { continue; } try { ClaimContainer(item); int num = CountCompatible(inventory, source); ItemData val = source.Clone(); val.m_stack = source.m_stack; try { inventory.AddItem(val); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)("Lager-Routing Ziel uebersprungen: " + ex.Message)); } goto end_IL_03a6; } int num2 = Mathf.Clamp(CountCompatible(inventory, source) - num, 0, source.m_stack); if (num2 <= 0) { continue; } playerInventory.RemoveItem(source, num2); movedItems += num2; touched.Add(item); InventoryReflection.NotifyChanged(inventory); InventoryReflection.NotifyChanged(playerInventory); SaveContainer(item); goto IL_04d7; end_IL_03a6:; } finally { ReleaseContainerLock(item, player.GetPlayerID()); } continue; IL_04d7: yield return null; } } int count = touched.Count; if (movedItems > 0) { MeadowsSettlementFeature.TouchLocal(((Component)player).transform.position, "qol_storage"); } QoLSkillRuntimeFeature.ShowCenter((movedItems > 0) ? (movedItems + " Gegenstaende auf " + count + " Lager verteilt.") : "Keine passende Lagergruppe oder kein freier Stapel gefunden."); } private static bool IsContainerEligible(Container container, long playerId) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)container == (Object)null || container.GetInventory() == null || container.IsInUse()) { return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !MeadowsSettlementFeature.CanModify(localPlayer, ((Component)container).transform.position, showMessage: false)) { return false; } try { Vagon wagon = container.m_wagon; if ((Object)(object)wagon != (Object)null && wagon.InUse()) { return false; } } catch { } try { MethodInfo methodInfo = AccessTools.Method(typeof(Container), "CheckAccess", (Type[])null, (Type[])null); if (methodInfo != null) { object obj2 = methodInfo.Invoke(container, new object[1] { playerId }); if (obj2 is bool && !(bool)obj2) { return false; } } } catch { return false; } try { if (container.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false)) { return false; } } catch { } return true; } private static bool TryAcquireContainerLock(Container container, long playerId) { try { ZNetView val = (((Object)(object)container.m_rootObjectOverride != (Object)null) ? container.m_rootObjectOverride : ((Component)container).GetComponent<ZNetView>()); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); if (val2 == null || (Object)(object)ZNet.instance == (Object)null) { return false; } if (!val.IsOwner()) { val.ClaimOwnership(); } long ticks = ZNet.instance.GetTime().Ticks; long num = val2.GetLong("ChallengeHub.QoL.LockUntil", 0L); long num2 = val2.GetLong("ChallengeHub.QoL.LockOwner", 0L); if (num > ticks && num2 != 0L && num2 != playerId) { return false; } val2.Set("ChallengeHub.QoL.LockOwner", playerId); val2.Set("ChallengeHub.QoL.LockUntil", ticks + TimeSpan.FromSeconds(12.0).Ticks); return true; } catch { return false; } } private static void ReleaseContainerLock(Container container, long playerId) { try { ZNetView val = (((Object)(object)container.m_rootObjectOverride != (Object)null) ? container.m_rootObjectOverride : ((Component)container).GetComponent<ZNetView>()); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); if (val2 != null && val2.GetLong("ChallengeHub.QoL.LockOwner", 0L) == playerId) { val2.Set("ChallengeHub.QoL.LockOwner", 0L); val2.Set("ChallengeHub.QoL.LockUntil", 0L); } } catch { } } private static int StorageTargetScore(Inventory inventory, ItemData source, string itemKey, string group, bool allowEmpty) { if (inventory == null || source == null) { return 0; } List<ItemData> allItems = inventory.GetAllItems(); if (allItems.Any((ItemData item) => item != null && string.Equals(QoLSkillRuntimeFeature.ItemKey(item), itemKey, StringComparison.Ordinal))) { return 300; } if (!string.IsNullOrEmpty(group) && allItems.Any((ItemData item) => item != null && MaterialGroup(item) == group)) { return 200; } if (allowEmpty && allItems.Count == 0) { return 100; } return 0; } private static int CountCompatible(Inventory inventory, ItemData source) { if (inventory == null || source == null) { return 0; } string key = QoLSkillRuntimeFeature.ItemKey(source); return (from item in inventory.GetAllItems() where item != null && string.Equals(QoLSkillRuntimeFeature.ItemKey(item), key, StringComparison.Ordinal) && item.m_quality == source.m_quality && item.m_variant == source.m_variant && item.m_worldLevel == source.m_worldLevel select item).Sum((ItemData item) => Math.Max(0, item.m_stack)); } private static string MaterialGroup(ItemData item) { //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Invalid comparison between Unknown and I4 //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Invalid comparison between Unknown and I4 //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Invalid comparison between Unknown and I4 //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected I4, but got Unknown if (item?.m_shared == null) { return string.Empty; } string text = (QoLSkillRuntimeFeature.ItemKey(item) + " " + item.m_shared.m_name).ToLowerInvariant(); if (ContainsAny(text, "ore", "copper", "tin", "iron", "silver", "blackmetal", "flametal")) { return "ore-metal"; } if (ContainsAny(text, "wood", "finewood", "roundlog", "yggdrasil")) { return "wood"; } if (ContainsAny(text, "seed", "seeds", "carrot", "turnip", "onion", "barley", "flax", "sapling")) { return "seed-crop"; } if (ContainsAny(text, "trophy")) { return "trophy"; } if (ContainsAny(text, "hide", "leather", "pelt", "wolf", "deer")) { return "hide"; } if (ContainsAny(text, "stone", "marble", "coal", "resin", "tar")) { return "construction"; } if ((int)item.m_shared.m_itemType == 2) { return "food"; } if ((int)item.m_shared.m_itemType == 9 || (int)item.m_shared.m_itemType == 23) { return "ammo"; } return "type-" + ((int)item.m_shared.m_itemType).ToString(CultureInfo.InvariantCulture); } private static bool ContainsAny(string text, params string[] values) { return values.Any((string value) => text.Contains(value)); } private static void ClaimContainer(Container container) { try { ZNetView val = (((Object)(object)container.m_rootObjectOverride != (Object)null) ? container.m_rootObjectOverride : ((Component)container).GetComponent<ZNetView>()); if ((Object)(object)val != (Object)null && val.IsValid() && !val.IsOwner()) { val.ClaimOwnership(); } } catch { } } private static void SaveContainer(Container container) { try { AccessTools.Method(typeof(Container), "Save", (Type[])null, (Type[])null)?.Invoke(container, Array.Empty<object>()); } catch { } } internal static string BuildPlantProgress(Plant plant) { if ((Object)(object)plant == (Object)null || !TalentStore.HasSkill("comfort.growth_sight")) { return string.Empty; } try { ZNetView component = ((Component)plant).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val == null || (Object)(object)ZNet.instance == (Object)null) { return string.Empty; } long ticks = val.GetLong(ZDOVars.s_plantTime, ZNet.instance.GetTime().Ticks); double num = Math.Max(0.0, (ZNet.instance.GetTime() - new DateTime(ticks)).TotalSeconds); MethodInfo methodInfo = AccessTools.Method(typeof(Plant), "GetGrowTime", (Type[])null, (Type[])null); float val2 = ((methodInfo != null) ? Convert.ToSingle(methodInfo.Invoke(plant, Array.Empty<object>()), CultureInfo.InvariantCulture) : plant.m_growTimeMax); val2 = Math.Max(1f, val2); float num2 = Mathf.Clamp01((float)(num / (double)val2)); TimeSpan remaining = TimeSpan.FromSeconds(Math.Max(0.0, (double)val2 - num)); return ProgressLine(num2, remaining, (num2 >= 1f) ? "erntereif" : "waechst"); } catch { return string.Empty; } } internal static string BuildPickableProgress(Pickable pickable) { if ((Object)(object)pickable == (Object)null || !TalentStore.HasSkill("comfort.growth_sight")) { return string.Empty; } try { ZNetView component = ((Component)pickable).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val == null) { return string.Empty; } if (!val.GetBool(ZDOVars.s_picked, false)) { return ProgressLine(1f, TimeSpan.Zero, "erntereif"); } if (pickable.m_respawnTimeMinutes <= 0f) { return "\n<color=#8fa0aa>Nicht nachwachsend</color>"; } long num = val.GetLong(ZDOVars.s_pickedTime, 0L); if (num <= 1 || (Object)(object)ZNet.instance == (Object)null) { return string.Empty; } double num2 = Math.Max(0.0, (ZNet.instance.GetTime() - new DateTime(num)).TotalMinutes); float percent = Mathf.Clamp01((float)(num2 / (double)pickable.m_respawnTimeMinutes)); TimeSpan remaining = TimeSpan.FromMinutes(Math.Max(0.0, (double)pickable.m_respawnTimeMinutes - num2)); return ProgressLine(percent, remaining, "Regeneration"); } catch { return string.Empty; } } private static string ProgressLine(float percent, TimeSpan remaining, string label) { string text = ((percent >= 0.99f) ? "#8CFF8C" : ((percent >= 0.66f) ? "#E7E47A" : ((percent >= 0.33f) ? "#FFC266" : "#FF8B78"))); string text2 = ((remaining.TotalSeconds <= 1.0) ? "bereit" : HumanDuration(remaining)); return "\n<color=" + text + ">" + label + ": " + Mathf.RoundToInt(percent * 100f) + "% · " + text2 + "</color>"; } private static string HumanDuration(TimeSpan time) { if (time.TotalHours >= 1.0) { return Math.Floor(time.TotalHours) + " Std. " + time.Minutes + " Min."; } if (time.TotalMinutes >= 1.0) { return Math.Floor(time.TotalMinutes) + " Min. " + time.Seconds + " Sek."; } return Math.Max(1, time.Seconds) + " Sek."; } internal static IEnumerator HarvestArea(Pickable origin, Player player) { if ((Object)(object)origin == (Object)null || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !TalentStore.HasSkill("comfort.area_harvest")) { yield break; } string prefab = Utils.GetPrefabName(((Component)origin).gameObject); if (string.IsNullOrWhiteSpace(prefab)) { yield break; } List<Pickable> list = (from target in (from hit in Physics.OverlapSphere(((Component)origin).transform.position, HarvestRadius) select (!((Object)(object)hit != (Object)null)) ? null : ((Component)hit).GetComponentInParent<Pickable>() into target where (Object)(object)target != (Object)null && (Object)(object)target != (Object)(object)origin && Utils.GetPrefabName(((Component)target).gameObject) == prefab select target).Distinct() orderby Vector3.Distance(((Component)origin).transform.position, ((Component)target).transform.position) select target).Take(HarvestMaxTargets).ToList(); int harvested = 0; foreach (Pickable item in list) { if (CanHarvest(item) && MeadowsSettlementFeature.CanModify(player, ((Component)item).transform.position, showMessage: false) && PrivateArea.CheckAccess(((Component)item).transform.position, 0f, false, false) && HasLineOfSight(player, ((Component)item).transform.position)) { try { item.Interact((Humanoid)(object)player, false, false); harvested++; } catch { } if (harvested % 5 == 0) { yield return null; } } } if (harvested > 0) { MeadowsSettlementFeature.TouchLocal(((Component)origin).transform.position, "qol_harvest"); QoLSkillRuntimeFeature.ShowCenter("Flächenernte: " + harvested + " zusätzliche Ziele."); } } private static bool CanHarvest(Pickable target) { try { ZNetView component = ((Component)target).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); return (Object)(object)component != (Object)null && component.IsValid() && val != null && !val.GetBool(ZDOVars.s_picked, false) && val.GetBool(ZDOVars.s_enabled, true) && target.GetEnabled != 0; } catch { return false; } } private static bool HasLineOfSight(Player player, Vector3 target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_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_0022: 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_0026: 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) Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 val = target + Vector3.up * 0.5f - eyePoint; RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(eyePoint, ((Vector3)(ref val)).normalized, ref val2, ((Vector3)(ref val)).magnitude, LayerMask.GetMask(new string[4] { "Default", "static_solid", "piece", "terrain" }))) { return true; } return Vector3.Distance(((RaycastHit)(ref val2)).point, target) < 1.25f; } internal static IEnumerator PlantGridExtras(Player player, Piece piecePrefab, Vector3 center, Quaternion rotation, int requestedGridSize) { //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) if ((Object)(object)player == (Object)null || (Object)(object)piecePrefab == (Object)null || !TalentStore.HasSkill("building.grid_planting")) { yield break; } Plant plantPrefab = ((Component)piecePrefab).GetComponentInChildren<Plant>(true); if ((Object)(object)plantPrefab == (Object)null) { yield break; } int size = ((requestedGridSize <= 2) ? 2 : ((requestedGridSize >= 5 && MaximumGridSize >= 5) ? 5 : 3)); float spacing = Mathf.Max(1.25f, plantPrefab.m_growRadius * 2.15f); List<Vector3> list = GridPositions(center, ((Component)player).transform.rotation, size, spacing); int placed = 0; foreach (Vector3 item in list) { if (Vector3.Distance(item, center) < 0.2f || !TryGroundPosition(item, out var position) || !CanPlantAt(player, plantPrefab, position)) { continue; } if (!player.HaveRequirements(piecePrefab, (RequirementMode)0)) { break; } try { TerrainModifier.SetTriggerOnPlaced(true); GameObject val = Object.Instantiate<GameObject>(((Component)piecePrefab).gameObject, position, rotation); TerrainModifier.SetTriggerOnPlaced(false); Piece component = val.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { component.SetCreator(player.GetPlayerID()); } WearNTear component2 = val.GetComponent<WearNTear>(); if (component2 != null) { component2.OnPlaced(); } piecePrefab.m_placeEffect.Create(position, rotation, val.transform, 1f, -1); player.ConsumeResources(piecePrefab.m_resources, 0, -1, 1); ConsumePlantingCost(player); placed++; } catch (Exception ex) { TerrainModifier.SetTriggerOnPlaced(false); ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)("Rasterpflanzung Position uebersprungen: " + ex.Message)); } } if (placed % 3 == 0) { yield return null; } } if (placed > 0) { MeadowsSettlementFeature.TouchLocal(center, "qol_planting"); QoLSkillRuntimeFeature.ShowCenter("Rasterpflanzung: " + placed + " zusätzliche Pflanzen gesetzt."); } } internal static List<Vector3> GridPositions(Vector3 center, Quaternion playerRotation, int size, float spacing) { //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_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_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_0028: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_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) List<Vector3> list = new List<Vector3>(); float num = (float)(size - 1) * 0.5f; Vector3 val = playerRotation * Vector3.right; Vector3 val2 = playerRotation * Vector3.forward; val.y = 0f; val2.y = 0f; ((Vector3)(ref val)).Normalize(); ((Vector3)(ref val2)).Normalize(); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { list.Add(center + val * (((float)j - num) * spacing) + val2 * (((float)i - num) * spacing)); } } return list; } private static bool TryGroundPosition(Vector3 raw, out Vector3 position) { //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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) position = raw; float y = default(float); if (Heightmap.GetHeight(raw, ref y)) { position.y = y; return true; } RaycastHit val = default(RaycastHit); if (Physics.Raycast(raw + Vector3.up * 8f, Vector3.down, ref val, 20f, LayerMask.GetMask(new string[3] { "terrain", "piece", "static_solid" }))) { position = ((RaycastHit)(ref val)).point; return true; } return false; } private static bool CanPlantAt(Player player, Plant plant, Vector3 position) { //IL_0001: 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_001e: 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_003b: 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_004f: 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_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_005d: Unknown result type (might be due to invalid IL or missing references) if (!MeadowsSettlementFeature.CanModify(player, position, showMessage: false)) { return false; } if (!PrivateArea.CheckAccess(position, 0f, false, false)) { return false; } if (!HasLineOfSight(player, position)) { return false; } Heightmap val = Heightmap.FindHeightmap(position); if ((Object)(object)val == (Object)null) { return false; } Biome biome = val.GetBiome(position, 0.02f, false); if ((plant.m_biome & biome) == 0) { return false; } if (plant.m_needCultivatedGround && !val.IsCultivated(position)) { return false; } return Physics.OverlapSphere(position + Vector3.up * 0.5f, Mathf.Max(0.5f, plant.m_growRadius * 0.85f), LayerMask.GetMask(new string[3] { "piece", "piece_nonsolid", "Default_small" })).All((Collider collider) => (Object)(object)collider == (Object)null || collider.isTrigger); } private static void ConsumePlantingCost(Player player) { try { ((Character)player).UseStamina(1f); } catch { } try { ItemData representativeEquippedItem = PlayerItemReflection.GetRepresentativeEquippedItem(player); ((representativeEquippedItem != null) ? AccessTools.Method(((object)representativeEquippedItem).GetType(), "UseDurability", (Type[])null, (Type[])null) : null)?.Invoke(representativeEquippedItem, new object[1] { 1f }); } catch { } } internal static bool TryFuelHoveredDevice(Player player, out string result) { result = string.Empty; TalentData localData = TalentStore.GetLocalData(); if ((Object)(object)player == (Object)null || localData == null || !localData.HasSkill("storage.fuel_helper")) { return false; } Fireplace val = LookTarget.FindComponent<Fireplace>(7f); if ((Object)(object)val != (Object)null) { return FillFireplace(player, localData, val, out result); } Smelter val2 = LookTarget.FindComponent<Smelter>(7f); if ((Object)(object)val2 != (Object)null) { return FillSmelter(player, localData, val2, out result); } result = "Keine Feuerstelle oder Produktionsanlage anvisiert."; return false; } private static bool FillFireplace(Player player, TalentData data, Fireplace fireplace, out string result) { //IL_0040: 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_011a: 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) result = string.Empty; if (fireplace.m_infiniteFuel || (Object)(object)fireplace.m_fuelItem == (Object)null || !MeadowsSettlementFeature.CanModify(player, ((Component)fireplace).transform.position, showMessage: false) || !PrivateArea.CheckAccess(((Component)fireplace).transform.position, 0f, false, false)) { return false; } ZNetView component = ((Component)fireplace).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val == null) { return false; } float num = val.GetFloat(ZDOVars.s_fuel, 0f); int num2 = Mathf.Clamp(Mathf.CeilToInt(fireplace.m_maxFuel * (float)data.FuelTargetPercent / 100f), 1, Mathf.CeilToInt(fireplace.m_maxFuel)); int num3 = Math.Max(0, num2 - Mathf.CeilToInt(num)); if (num3 == 0) { result = "Brennstoffziel bereits erreicht."; return true; } string name = fireplace.m_fuelItem.m_itemData.m_shared.m_name; int num4 = ConsumeFuel(player, data, name, num3, ((Component)fireplace).transform.position, delegate { fireplace.AddFuel(1f); }); if (num4 > 0) { MeadowsSettlementFeature.TouchLocal(((Component)fireplace).transform.position, "qol_fuel"); } result = ((num4 > 0) ? ("Brennstoffhelfer: " + num4 + " × " + QoLSkillRuntimeFeature.Localize(name) + " nachgefüllt.") : "Kein berechtigter Brennstoff vorhanden."); return num4 > 0; } private static bool FillSmelter(Player player, TalentData data, Smelter smelter, out string result) { //IL_001c: 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_0106: 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) result = string.Empty; if ((Object)(object)smelter.m_fuelItem == (Object)null || !MeadowsSettlementFeature.CanModify(player, ((Component)smelter).transform.position, showMessage: false) || !PrivateArea.CheckAccess(((Component)smelter).transform.position, 0f, false, false)) { return false; } MethodInfo methodInfo = AccessTools.Method(typeof(Smelter), "GetFuel", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Smelter), "SetFuel", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { return false; } float num = Convert.ToSingle(methodInfo.Invoke(smelter, Array.Empty<object>()), CultureInfo.InvariantCulture); int num2 = Mathf.Clamp(Mathf.CeilToInt((float)(smelter.m_maxFuel * data.FuelTargetPercent) / 100f), 1, smelter.m_maxFuel); int num3 = Math.Max(0, num2 - Mathf.CeilToInt(num)); if (num3 == 0) { result = "Brennstoffziel bereits erreicht."; return true; } string name = smelter.m_fuelItem.m_itemData.m_shared.m_name; int num4 = 0; int num5 = ConsumeFuel(player, data, name, num3, ((Component)smelter).transform.position, delegate { }); if (num5 > 0) { ZNetView val = ((Component)smelter).GetComponent<ZNetView>() ?? ((Component)smelter).GetComponentInParent<ZNetView>(); if ((Object)(object)val != (Object)null && !val.IsOwner()) { val.ClaimOwnership(); } methodInfo2.Invoke(smelter, new object[1] { num + (float)num5 }); num4 = num5; } if (num4 > 0) { MeadowsSettlementFeature.TouchLocal(((Component)smelter).transform.position, "qol_fuel"); } result = ((num4 > 0) ? ("Brennstoffhelfer: " + num4 + " × " + QoLSkillRuntimeFeature.Localize(name) + " nachgefüllt.") : "Kein berechtigter Brennstoff vorhanden."); return num4 > 0; } private static int ConsumeFuel(Player player, TalentData data, string itemName, int need, Vector3 devicePosition, Action addOne) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) int i = 0; Inventory inventory = ((Humanoid)player).GetInventory(); for (; i < need; i++) { if (!inventory.HaveItem(itemName, true)) { break; } inventory.RemoveItem(itemName, 1, -1, true); addOne(); } if (i >= need || !data.HasSkill("storage.fuel_helper_storage")) { return i; } foreach (Container item in from c in QoLSkillRuntimeFeature.FindNearbyContainers(devicePosition, FuelContainerRadius) where IsContainerEligible(c, player.GetPlayerID()) select c) { Inventory inventory2 = item.GetInventory(); if (inventory2 == null || !TryAcquireContainerLock(item, player.GetPlayerID())) { continue; } try { ClaimContainer(item); for (; i < need; i++) { if (!inventory2.HaveItem(itemName, true)) { break; } inventory2.RemoveItem(itemName, 1, -1, true); addOne(); } InventoryReflection.NotifyChanged(inventory2); SaveContainer(item); } finally { ReleaseContainerLock(item, player.GetPlayerID()); } if (i >= need) { break; } } return i; } internal static string BuildSignRichText(string raw, TalentData data) { string text = Regex.Replace(raw ?? string.Empty, "<[^>]+>", string.Empty).Replace("\r", " ").Replace("\0", string.Empty); if (text.Length > 120) { text = text.Substring(0, 120); } string text2 = ((data.SignAlignment == 1) ? "center" : ((data.SignAlignment == 2) ? "right" : "left")); string text3 = text; if (data.SignBold) { text3 = "<b>" + text3 + "</b>"; } if (data.SignItalic) { text3 = "<i>" + text3 + "</i>"; } string text4 = (data.SignColor = NormalizeSignColor(data.SignColor)); return "<align=\"" + text2 + "\"><size=" + Mathf.Clamp(data.SignFontSize, 12, SignMaxFontSize) + "><color=" + text4 + ">" + text3 + "</color></size></align>"; } private static string NormalizeSignColor(string value) { string text = (value ?? string.Empty).Trim(); if (!Regex.IsMatch(text, "^#[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$")) { return "#FFFFFF"; } return text.ToUpperInvariant(); } internal static void CycleFineRotationStep(float direction) { TalentData localData = TalentStore.GetLocalData(); if (localData == null || !localData.HasSkill("building.fine_rotation")) { return; } int num = 0; float num2 = float.MaxValue; for (int i = 0; i < RotationSteps.Length; i++) { float num3 = Mathf.Abs(RotationSteps[i] - localData.FineRotationStep); if (num3 < num2) { num2 = num3; num = i; } } num = ((direction >= 0f) ? ((num + 1) % RotationSteps.Length) : ((num - 1 + RotationSteps.Length) % RotationSteps.Length)); localData.FineRotationStep = RotationSteps[num]; TalentStore.SaveLocalSettings(); QoLSkillRuntimeFeature.ShowCenter("Drehschritt: " + localData.FineRotationStep.ToString("0.#", CultureInfo.InvariantCulture) + "°"); } internal static string RotationHudText() { //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_007a: 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_007f: 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) //IL_00a8: 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) TalentData localData = TalentStore.GetLocalData(); if (localData == null || !localData.HasSkill("building.fine_rotation")) { return string.Empty; } string text = ((localData.FineRotationAxis == 1) ? "X" : ((localData.FineRotationAxis == 2) ? "Z" : "Y")); Player localPlayer = Player.m_localPlayer; GameObject val = (((Object)(object)localPlayer != (Object)null) ? PlayerBuildReflection.GetPlacementGhost(localPlayer) : null); Vector3 val2; if (!((Object)(object)val != (Object)null)) { val2 = Vector3.zero; } else { Quaternion rotation = val.transform.rotation; val2 = ((Quaternion)(ref rotation)).eulerAngles; } Vector3 val3 = val2; string text2 = "Welt X " + FormatWorldAngle(val3.x) + " | Y " + FormatWorldAngle(val3.y) + " | Z " + FormatWorldAngle(val3.z); return text2 + " · Achse " + text + " · Schritt " + localData.FineRotationStep.ToString("0.#", CultureInfo.InvariantCulture) + "° · " + (localData.FineRotationLocalFrame ? "Eingabe lokal" : "Eingabe Welt") + " [Alt+V Achse | Alt+Shift+V Rahmen | Alt+Shift+Rad Schritt | Alt+Z Reset]"; } private static string FormatWorldAngle(float angle) { float num = Mathf.Repeat(angle, 360f); if (num >= 359.95f || num < 0.05f) { num = 0f; } return num.ToString("0.0", CultureInfo.InvariantCulture) + "°"; } internal static void ApplyFineRotation(Player player) { //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_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_008e: 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_0076: 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) TalentData localData = TalentStore.GetLocalData(); if (!((Object)(object)player == (Object)null) && localData != null && localData.HasSkill("building.fine_rotation")) { GameObject placementGhost = PlayerBuildReflection.GetPlacementGhost(player); Piece selectedPiece = PlayerBuildReflection.GetSelectedPiece(player); if (!((Object)(object)placementGhost == (Object)null) && !((Object)(object)selectedPiece == (Object)null) && !IsRotationExcluded(selectedPiece)) { Quaternion val = Quaternion.Euler(localData.FineRotationX, localData.FineRotationY, localData.FineRotationZ); placementGhost.transform.rotation = (localData.FineRotationLocalFrame ? (placementGhost.transform.rotation * val) : (val * placementGhost.transform.rotation)); } } } private static bool IsRotationExcluded(Piece piece) { if ((Object)(object)piece == (Object)null) { return true; } if ((Object)(object)((Component)piece).GetComponentInChildren<Plant>(true) != (Object)null) { return true; } if ((Object)(object)((Component)piece).GetComponentInChildren<TerrainModifier>(true) != (Object)null) { return true; } return ContainsAny(Utils.GetPrefabName(((Component)piece).gameObject).ToLowerInvariant(), "sapling", "seed", "terrain", "raise", "cultivate", "path"); } internal static void AdjustFineRotation(float delta) { TalentData localData = TalentStore.GetLocalData(); if (localData != null && localData.HasSkill("building.fine_rotation")) { float num = Mathf.Sign(delta) * localData.FineRotationStep; if (localData.FineRotationAxis == 1) { localData.FineRotationX = Mathf.Repeat(localData.FineRotationX + num, 360f); } else if (localData.FineRotationAxis == 2) { localData.FineRotationZ = Mathf.Repeat(localData.FineRotationZ + num, 360f); } else { localData.FineRotationY = Mathf.Repeat(localData.FineRotationY + num, 360f); } TalentStore.SaveLocalSettings(); } } internal static string SwimOverview(Player player) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || !TalentStore.HasSkill("orientation.swim_overview")) { return string.Empty; } try { if (!((Character)player).IsSwimming()) { return string.Empty; } } catch { return string.Empty; } float num = 0f; float num2 = 0f; try { num = player.GetStamina(); num2 = ((Character)player).GetMaxStamina(); } catch { } float num3 = 0f; try { num3 = ((Character)player).GetSkills().GetSkillLevel((SkillType)103); } catch { } float num4 = ReadFloatField(player, "m_swimStaminaDrainMinSkill", 5f); float num5 = ReadFloatField(player, "m_swimStaminaDrainMaxSkill", 2f); float num6 = Mathf.Lerp(num4, num5, Mathf.Clamp01(num3 / 100f)); float num7 = ((num6 > 0.01f) ? (num / num6) : 999f); float num8 = EstimateGroundDistance(((Component)player).transform.position); string text = ((num2 > 0f && num / num2 < SwimCriticalStaminaPercent) ? " · KRITISCH" : string.Empty); return "Schwimmen: " + num.ToString("0", CultureInfo.InvariantCulture) + "/" + num2.ToString("0", CultureInfo.InvariantCulture) + " · ca. " + num7.ToString("0", CultureInfo.InvariantCulture) + " s · Effizienz " + Mathf.RoundToInt((1f - num6 / Math.Max(0.01f, num4)) * 100f) + "% · fester Grund ~" + ((num8 < 999f) ? (Mathf.RoundToInt(num8) + " m") : ">100 m") + text; } private static float ReadFloatField(object instance, string name, float fallback) { try { FieldInfo fieldInfo = AccessTools.Field(instance.GetType(), name); return (fieldInfo != null) ? Convert.ToSingle(fieldInfo.GetValue(instance), CultureInfo.InvariantCulture) : fallback; } catch { return fallback; } } private static float EstimateGroundDistance(Vector3 position) { //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_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_008b: 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) int mask = LayerMask.GetMask(new string[3] { "terrain", "static_solid", "piece" }); float num = 999f; Vector3 val = default(Vector3); RaycastHit val2 = default(RaycastHit); for (int i = 0; i < 16; i++) { float num2 = (float)i * 22.5f * ((float)Math.PI / 180f); ((Vector3)(ref val))..ctor(Mathf.Cos(num2), 0f, Mathf.Sin(num2)); if (Physics.Raycast(position + Vector3.up, val, ref val2, 100f, mask)) { num = Mathf.Min(num, ((RaycastHit)(ref val2)).distance); } } float num3 = default(float); if (Heightmap.GetHeight(position, ref num3)) { num = Mathf.Min(num, Mathf.Max(0f, position.y - num3)); } return num; } } internal sealed class AdvancedQoLBehaviour : MonoBehaviour { private readonly Dictionary<Door, float> _scheduledDoors = new Dictionary<Door, float>(); private readonly List<GameObject> _gridPreview = new List<GameObject>(); private Material _gridPreviewMaterial; private bool _cursorStateCaptured; private bool _previousCursorVisible; private CursorLockMode _previousCursorLock; private float _nextDoorCheck; private float _nextPreviewUpdate; private bool _showSignEditor; private Sign _editingSign; private string _signText = string.Empty; private Rect _signWindow = new Rect(80f, 80f, 520f, 430f); private static readonly int SignWindowId = "ChallengeHub_SignWorkshop_v280".GetHashCode(); private GUIStyle _hudStyle; private GUIStyle _signPreviewStyle; internal void ScheduleDoor(Door door) { if (!((Object)(object)door == (Object)null) && TalentStore.HasSkill("comfort.door_guardian")) { _scheduledDoors[door] = Time.realtimeSinceStartup + AdvancedQoLFeature.DoorCloseDelay; } } internal void OnTalentDataChanged() { if (!TalentStore.HasSkill("building.sign_workshop")) { CloseSignEditor(); } if (!TalentStore.HasSkill("building.grid_planting")) { ClearGridPreview(); } } private void Update() { //IL_0342: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { ClearGridPreview(); return; } bool flag = Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); bool flag2 = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); if (flag && !TalentMenuBehaviour.IsVisible) { if (Input.GetKeyDown((KeyCode)117) && TalentStore.HasSkill("storage.stack_nearby")) { TalentData localData = TalentStore.GetLocalData(); localData.AllowEmptyStorageTargets = !localData.AllowEmptyStorageTargets; TalentStore.SaveLocalSettings(); QoLSkillRuntimeFeature.ShowCenter("Leere Lagerziele: " + (localData.AllowEmptyStorageTargets ? "erlaubt" : "nur vorhandene Typen/Gruppen")); } else if (Input.GetKeyDown((KeyCode)106) && TalentStore.HasSkill("building.grid_planting")) { TalentData localData2 = TalentStore.GetLocalData(); int num = (localData2.FarmingGridSize = ((localData2.FarmingGridSize == 2) ? 3 : ((localData2.FarmingGridSize == 3 && AdvancedQoLFeature.MaximumGridSize >= 5) ? 5 : 2))); TalentStore.SaveLocalSettings(); QoLSkillRuntimeFeature.ShowCenter("Pflanzraster: " + num + "×" + num); } else if (Input.GetKeyDown((KeyCode)104) && TalentStore.HasSkill("storage.fuel_helper")) { TalentData localData3 = TalentStore.GetLocalData(); localData3.FuelTargetPercent = ((localData3.FuelTargetPercent >= 100) ? 25 : (localData3.FuelTargetPercent + 25)); TalentStore.SaveLocalSettings(); QoLSkillRuntimeFeature.ShowCenter("Brennstoffziel: " + localData3.FuelTargetPercent + "%"); } else if (Input.GetKeyDown((KeyCode)121) && TalentStore.HasSkill("storage.fuel_helper")) { AdvancedQoLFeature.TryFuelHoveredDevice(localPlayer, out var result); QoLSkillRuntimeFeature.ShowCenter(result); } else if (Input.GetKeyDown((KeyCode)100) && TalentStore.HasSkill("comfort.door_guardian")) { TalentData localData4 = TalentStore.GetLocalData(); localData4.AutoCloseDoorsInDungeons = !localData4.AutoCloseDoorsInDungeons; TalentStore.SaveLocalSettings(); QoLSkillRuntimeFeature.ShowCenter("Türwächter in Dungeons: " + (localData4.AutoCloseDoorsInDungeons ? "an" : "aus")); } else if (Input.GetKeyDown((KeyCode)105) && TalentStore.HasSkill("building.sign_workshop")) { Sign val = LookTarget.FindComponent<Sign>(7f); if ((Object)(object)val != (Object)null) { OpenSignEditor(val); } } else if (Input.GetKeyDown((KeyCode)118) && TalentStore.HasSkill("building.fine_rotation")) { TalentData localData5 = TalentStore.GetLocalData(); if (flag2) { localData5.FineRotationLocalFrame = !localData5.FineRotationLocalFrame; } else { localData5.FineRotationAxis = (localData5.FineRotationAxis + 1) % 3; } TalentStore.SaveLocalSettings(); QoLSkillRuntimeFeature.ShowCenter(AdvancedQoLFeature.RotationHudText()); } else if (Input.GetKeyDown((KeyCode)122) && TalentStore.HasSkill("building.fine_rotation")) { TalentData localData6 = TalentStore.GetLocalData(); if (flag2) { localData6.FineRotationX = (localData6.FineRotationY = (localData6.FineRotationZ = 0f)); } else if (localData6.FineRotationAxis == 1) { localData6.FineRotationX = 0f; } else if (localData6.FineRotationAxis == 2) { localData6.FineRotationZ = 0f; } else { localData6.FineRotationY = 0f; } TalentStore.SaveLocalSettings(); QoLSkillRuntimeFeature.ShowCenter("Drehung zurückgesetzt."); } float y = Input.mouseScrollDelta.y; if (Mathf.Abs(y) > 0.01f && TalentStore.HasSkill("building.fine_rotation")) { if (flag2) { AdvancedQoLFeature.CycleFineRotationStep(y); } else { AdvancedQoLFeature.AdjustFineRotation(y); } } } if (Time.realtimeSinceStartup >= _nextDoorCheck) { _nextDoorCheck = Time.realtimeSinceStartup + 0.25f; ProcessDoors(localPlayer); } if (Time.realtimeSinceStartup >= _nextPreviewUpdate) { _nextPreviewUpdate = Time.realtimeSinceStartup + 0.15f; UpdateGridPreview(localPlayer, flag); } } private void ProcessDoors(Player player) { //IL_012e: 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) KeyValuePair<Door, float>[] array = _scheduledDoors.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<Door, float> keyValuePair = array[i]; Door door = keyValuePair.Key; if ((Object)(object)door == (Object)null) { _scheduledDoors.Remove(keyValuePair.Key); } else { if (Time.realtimeSinceStartup < keyValuePair.Value) { continue; } _scheduledDoors.Remove(door); TalentData localData = TalentStore.GetLocalData(); if (localData == null || !localData.HasSkill("comfort.door_guardian") || (((Character)player).InInterior() && !localData.AutoCloseDoorsInDungeons)) { continue; } ZNetView component = ((Component)door).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val == null || val.GetInt(ZDOVars.s_state, 0) == 0 || door.m_canNotBeClosed) { continue; } if (Player.GetAllPlayers().Any((Player other) => (Object)(object)other != (Object)null && Vector3.Distance(((Component)other).transform.position, ((Component)door).transform.position) <= AdvancedQoLFeature.DoorSafetyRadius)) { _scheduledDoors[door] = Time.realtimeSinceStartup + 1f; } else if (MeadowsSettlementFeature.CanModify(player, ((Component)door).transform.position, showMessage: false) && (!door.m_checkGuardStone || PrivateArea.CheckAccess(((Component)door).transform.position, 0f, false, false))) { try { door.Interact((Humanoid)(object)player, false, false); } catch { } } } } } private void UpdateGridPreview(Player player, bool alt) { //IL_0083: 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_0139: 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_00dd: 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_0101: Expected O, but got Unknown //IL_01c3: 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_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) if (!alt || !TalentStore.HasSkill("building.grid_planting")) { ClearGridPreview(); return; } Piece selectedPiece = PlayerBuildReflection.GetSelectedPiece(player); GameObject placementGhost = PlayerBuildReflection.GetPlacementGhost(player); Plant val = (((Object)(object)selectedPiece != (Object)null) ? ((Component)selectedPiece).GetComponentInChildren<Plant>(true) : null); if ((Object)(object)selectedPiece == (Object)null || (Object)(object)placementGhost == (Object)null || (Object)(object)val == (Object)null) { ClearGridPreview(); return; } int farmingGridSize = TalentStore.GetLocalData().FarmingGridSize; float spacing = Mathf.Max(1.25f, val.m_growRadius * 2.15f); List<Vector3> list = AdvancedQoLFeature.GridPositions(placementGhost.transform.position, ((Component)player).transform.rotation, farmingGridSize, spacing); if ((Object)(object)_gridPreviewMaterial == (Object)null) { Shader val2 = Shader.Find("Unlit/Color") ?? Shader.Find("Standard"); if ((Object)(object)val2 != (Object)null) { _gridPreviewMaterial = new Material(val2) { color = new Color(0.25f, 1f, 0.35f, 0.55f) }; } } while (_gridPreview.Count < list.Count) { GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)val3).name = "ChallengeHub_PlantGridPreview"; Object.Destroy((Object)(object)val3.GetComponent<Collider>()); val3.transform.localScale = new Vector3(0.25f, 0.02f, 0.25f); Renderer component = val3.GetComponent<Renderer>(); if ((Object)(object)component != (Object)null && (Object)(object)_gridPreviewMaterial != (Object)null) { component.sharedMaterial = _gridPreviewMaterial; } _gridPreview.Add(val3); } float num = default(float); for (int i = 0; i < _gridPreview.Count; i++) { bool flag = i < list.Count; _gridPreview[i].SetActive(flag); if (flag) { Vector3 val4 = list[i]; if (Heightmap.GetHeight(val4, ref num)) { val4.y = num + 0.03f; } _gridPreview[i].transform.position = val4; } } } private void ClearGridPreview() { foreach (GameObject item in _gridPreview) { if ((Object)(object)item != (Object)null) { Object.Destroy((Object)(object)item); } } _gridPreview.Clear(); } private void OpenSignEditor(Sign sign) { //IL_0014: 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_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) if (!((Object)(object)sign == (Object)null) && MeadowsSettlementFeature.CanModify(Player.m_localPlayer, ((Component)sign).transform.position, showMessage: false) && PrivateArea.CheckAccess(((Component)sign).transform.position, 0f, true, false)) { _editingSign = sign; string text = string.Empty; try { text = sign.GetText(); } catch { } _signText = Regex.Replace(text ?? string.Empty, "<[^>]+>", string.Empty); if (!_cursorStateCaptured) { _previousCursorVisible = Cursor.visible; _previousCursorLock = Cursor.lockState; _cursorStateCaptured = true; } _showSignEditor = true; Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } } private void CloseSignEditor() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) _showSignEditor = false; _editingSign = null; if (_cursorStateCaptured) { Cursor.visible = _previousCursorVisible; Cursor.lockState = _previousCursorLock; _cursorStateCaptured = false; } } private void OnGUI() { //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_001f: 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_0033: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0065: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: 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) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if (_hudStyle == null) { _hudStyle = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = 15, wordWrap = true }; _signPreviewStyle = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = 18, wordWrap = true, richText = true }; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !TalentMenuBehaviour.IsVisible) { string text = AdvancedQoLFeature.RotationHudText(); if (!string.IsNullOrEmpty(text) && (Object)(object)PlayerBuildReflection.GetPlacementGhost(localPlayer) != (Object)null) { GUI.Box(new Rect((float)Screen.width * 0.5f - 330f, (float)Screen.height - 178f, 660f, 30f), text, _hudStyle); } string text2 = AdvancedQoLFeature.SwimOverview(localPlayer); if (!string.IsNullOrEmpty(text2)) { GUI.Box(new Rect((float)Screen.width * 0.5f - 330f, 86f, 660f, 34f), text2, _hudStyle); } } if (_showSignEditor && (Object)(object)_editingSign != (Object)null) { _signWindow = GUI.Window(SignWindowId, _signWindow, new WindowFunction(DrawSignWindow), "ChallengeHub Schildwerkstatt"); } } private void DrawSignWindow(int id) { //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) TalentData localData = TalentStore.GetLocalData(); if (localData == null) { CloseSignEditor(); return; } GUILayout.Label("Text (max. 120 Zeichen)", Array.Empty<GUILayoutOption>()); _signText = GUILayout.TextArea(_signText ?? string.Empty, 120, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(80f) }); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Farbe", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); localData.SignColor = GUILayout.TextField(localData.SignColor ?? "#FFFFFF", 9, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); GUILayout.Label("Größe", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); if (int.TryParse(GUILayout.TextField(localData.SignFontSize.ToString(CultureInfo.InvariantCulture), 3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }), out var result)) { localData.SignFontSize = Mathf.Clamp(result, 12, AdvancedQoLFeature.SignMaxFontSize); } localData.SignBold = GUILayout.Toggle(localData.SignBold, "Fett", Array.Empty<GUILayoutOption>()); localData.SignItalic = GUILayout.Toggle(localData.SignItalic, "Kursiv", Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Links", Array.Empty<GUILayoutOption>())) { localData.SignAlignment = 0; } if (GUILayout.Button("Mitte", Array.Empty<GUILayoutOption>())) { localData.SignAlignment = 1; } if (GUILayout.Button("Rechts", Array.Empty<GUILayoutOption>())) { localData.SignAlignment = 2; } GUILayout.EndHorizontal(); GUILayout.Label("Vorschau:", Array.Empty<GUILayoutOption>()); GUILayout.Box(AdvancedQoLFeature.BuildSignRichText(_signText, localData), _signPreviewStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(70f) }); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); for (int i = 0; i < 3; i++) { int index = i; if (GUILayout.Button("Vorlage " + (i + 1), Array.Empty<GUILayoutOption>())) { ApplyOrSavePreset(localData, index, Event.current.shift); } } GUILayout.EndHorizontal(); GUILayout.Label("Shift+Klick speichert den aktuellen Stil in die Vorlage.", Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Speichern", Array.Empty<GUILayoutOption>())) { try { _editingSign.SetText(AdvancedQoLFeature.BuildSignRichText(_signText, localData)); MeadowsSettlementFeature.TouchLocal(((Component)_editingSign).transform.position, "qol_sign"); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Schildtext konnte nicht gespeichert werden: " + ex.Message)); } } TalentStore.SaveLocalSettings(); CloseSignEditor(); } if (GUILayout.Button("Abbrechen", Array.Empty<GUILayoutOption>())) { CloseSignEditor(); } GUILayout.EndHorizontal(); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _signWindow)).width, 22f)); } private static void ApplyOrSavePreset(TalentData data, int index, bool save) { while (data.SignStylePresets.Count <= index) { data.SignStylePresets.Add(new SignStylePresetData { Name = "Vorlage " + (data.SignStylePresets.Count + 1) }); } SignStylePresetData signStylePresetData = data.SignStylePresets[index]; if (save) { signStylePresetData.Color = data.SignColor; signStylePresetData.FontSize = data.SignFontSize; signStylePresetData.Bold = data.SignBold; signStylePresetData.Italic = data.SignItalic; signStylePresetData.Alignment = data.SignAlignment; signStylePresetData.Normalize(); TalentStore.SaveLocalSettings(); } else { data.SignColor = signStylePresetData.Color; data.SignFontSize = signStylePresetData.FontSize; data.SignBold = signStylePresetData.Bold; data.SignItalic = signStylePresetData.Italic; data.SignAlignment = signStylePresetData.Alignment; } } private void OnDestroy() { CloseSignEditor(); ClearGridPreview(); if ((Object)(object)_gridPreviewMaterial != (Object)null) { Object.Destroy((Object)(object)_gridPreviewMaterial); } _gridPreviewMaterial = null; } } [HarmonyPatch(typeof(Plant), "GetHoverText")] internal static class QoLPlantProgressPatch { [HarmonyPostfix] private static void Postfix(Plant __instance, ref string __result) { __result += AdvancedQoLFeature.BuildPlantProgress(__instance); } } [HarmonyPatch(typeof(Pickable), "GetHoverText")] internal static class QoLPickableProgressPatch { [HarmonyPostfix] private static void Postfix(Pickable __instance, ref string __result) { __result += AdvancedQoLFeature.BuildPickableProgress(__instance); } } [HarmonyPatch(typeof(Pickable), "Interact")] internal static class QoLAreaHarvestPatch { [HarmonyPostfix] private static void Postfix(Pickable __instance, Humanoid character, bool repeat, bool alt) { Player val = (Player)(object)((character is Player) ? character : null); if (!(!alt || repeat) && !((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && TalentStore.HasSkill("comfort.area_harvest")) { Plugin instance = Plugin.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(AdvancedQoLFeature.HarvestArea(__instance, val)); } } } } [HarmonyPatch(typeof(Door), "Interact")] internal static class QoLDoorGuardianPatch { [HarmonyPostfix] private static void Postfix(Door __instance, Humanoid character, bool hold, ref bool __result) { Player val = (Player)(object)((character is Player) ? character : null); if (!__result || hold || (Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || !TalentStore.HasSkill("comfort.door_guardian")) { return; } object obj; if (__instance == null) { obj = null; } else { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); obj = ((component != null) ? component.GetZDO() : null); } ZDO val2 = (ZDO)obj; if (val2 != null && val2.GetInt(ZDOVars.s_state, 0) != 0) { Plugin instance = Plugin.Instance; if (instance != null) { ((Component)instance).GetComponent<AdvancedQoLBehaviour>()?.ScheduleDoor(__instance); } } } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] internal static class QoLFineRotationGhostPatch { [HarmonyPostfix] private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { AdvancedQoLFeature.ApplyFineRotation(__instance); } } } [HarmonyPatch(typeof(Player), "PlacePiece", new Type[] { typeof(Piece), typeof(Vector3), typeof(Quaternion), typeof(bool) })] internal static class QoLGridPlantingPatch { internal sealed class State { internal Piece Piece; internal Vector3 Position; internal Quaternion Rotation; internal bool Requested; internal int Size; } [HarmonyPrefix] private static void Prefix(Player __instance, out State __state) { //IL_0083: 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_0094: 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) __state = null; if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && TalentStore.HasSkill("building.grid_planting") && (Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307))) { Piece selectedPiece = PlayerBuildReflection.GetSelectedPiece(__instance); GameObject placementGhost = PlayerBuildReflection.GetPlacementGhost(__instance); if (!((Object)(object)selectedPiece == (Object)null) && !((Object)(object)placementGhost == (Object)null) && !((Object)(object)((Component)selectedPiece).GetComponentInChildren<Plant>(true) == (Object)null)) { TalentData localData = TalentStore.GetLocalData(); __state = new State { Piece = selectedPiece, Position = placementGhost.transform.position, Rotation = placementGhost.transform.rotation, Requested = true, Size = (localData?.FarmingGridSize ?? 3) }; } } } [HarmonyPostfix] private static void Postfix(Player __instance, State __state) { //IL_002b: 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) if (__state != null && __state.Requested && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { Plugin instance = Plugin.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(AdvancedQoLFeature.PlantGridExtras(__instance, __state.Piece, __state.Position, __state.Rotation, __state.Size)); } } } } internal static class StartupWelcomeFeature { internal static void Initialize(Plugin plugin) { if (!((Object)(object)plugin == (Object)null) && !Application.isBatchMode && (Object)(object)((Component)plugin).GetComponent<BlutEidStartupBehaviour>() == (Object)null) { ((Component)plugin).gameObject.AddComponent<BlutEidStartupBehaviour>(); } } } internal sealed class BlutEidStartupBehaviour : MonoBehaviour { [Serializable] private sealed class MainMenuCharacterRegistration { public string action; public string clientVersion; public string challengeShortCode; public string linkCode; public string characterId; public string characterName; } [Serializable] private sealed class DeathRunEnvelope { public bool ok; public bool worldReady; public DeathRunWeb run; } [Serializable] private sealed class DeathRunWeb { public string id; public string worldCode; public string worldPackageStatus; } internal static bool CharacterSelected; private Texture2D _image; private Texture2D _panel; private GUIStyle _button; private GUIStyle _title; private GUIStyle _status; private GUIStyle _version; private string _message = "Vorzeichen des Nordens · Charakter auswählen und Challenge-Welt starten"; private bool _resumeRunning; private string _installedWorldCode = string.Empty; private void OnGUI() { //IL_0054: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_0162: Unknown result type (might be due to invalid IL or missing references) if (IsMainMenuHome()) { EnsureAssets(); float num = Mathf.Clamp((float)Screen.width * 0.34f, 390f, 610f); float num2 = num / 1.777f; Rect val = default(Rect); ((Rect)(ref val))..ctor((float)Screen.width - num - 24f, 24f, num, num2 + 128f); GUI.DrawTexture(val, (Texture)(object)_panel, (ScaleMode)0); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 6f, ((Rect)(ref val)).y + 6f, num - 12f, num2 - 2f); if ((Object)(object)_image != (Object)null) { GUI.DrawTexture(val2, (Texture)(object)_image, (ScaleMode)2, true); } if (GUI.Button(val2, GUIContent.none, _button)) { HandleCardClick(); } GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val2)).yMax + 8f, num - 36f, 34f), "Der Blut-Eid: Vorzeichen des Nordens", _title); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val2)).yMax + 45f, num - 36f, 42f), _message, _status); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val2)).yMax + 91f, num - 36f, 24f), "ChallengeHub Blut-Eid v2.12.50 · Modpaket aktuell", _version); } } private static bool IsMainMenuHome() { //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) Scene activeScene = SceneManager.GetActiveScene(); if (string.Equals(((Scene)(ref activeScene)).name, "start", StringComparison.OrdinalIgnoreCase)) { return (Object)(object)Player.m_localPlayer == (Object)null; } return false; } private void HandleCardClick() { FejdStartup startup = Object.FindFirstObjectByType<FejdStartup>(); if ((Object)(object)startup == (Object)null) { _message = "Valheim-Hauptmenü ist noch nicht bereit"; return; } if (!string.IsNullOrWhiteSpace(_installedWorldCode)) { RefreshAndSelectWorld(startup, _installedWorldCode); return; } if (!CharacterSelected) { _message = "Schritt 1 von 2 · Charakter auswählen"; AccessTools.Method(typeof(FejdStartup), "ShowCharacterSelection", (Type[])null, (Type[])null)?.Invoke(startup, null); return; } PlayerLinkSetupFeature playerLinkSetupFeature = (((Object)(object)Plugin.Instance != (Object)null) ? ((Component)Plugin.Instance).GetComponent<PlayerLinkSetupFeature>() : null); _message = "Schritt 2 von 2 · Blut-Eid-Welt wird eingerichtet ..."; if ((Object)(object)playerLinkSetupFeature == (Object)null) { _message = "ChallengeHub-Verbindung ist nicht bereit"; return; } playerLinkSetupFeature.SelectDeathRunFromMainMenu(delegate(string message) { if (message.IndexOf("eingerichtet", StringComparison.OrdinalIgnoreCase) < 0) { _message = message; } else { ((MonoBehaviour)this).StartCoroutine(RegisterSelectedCharacterAndOpenWebApp(startup)); } }); } private IEnumerator RegisterSelectedCharacterAndOpenWebApp(FejdStartup startup) { PlayerProfile val = SelectedProfile(startup); if (val == null) { CharacterSelected = false; _message = "Bitte zuerst einen Charakter auswählen"; yield break; } string text = ((Plugin.PlayerLinkCode != null) ? (Plugin.PlayerLinkCode.Value ?? string.Empty).Trim() : string.Empty); if (string.IsNullOrWhiteSpace(text)) { _message = "Player-Link-Code fehlt · bitte im ChallengeHub-Dialog eintragen"; yield break; } string characterId = val.GetPlayerID().ToString(); string characterName = val.GetName() ?? "Valheim-Charakter"; MainMenuCharacterRegistration value = new MainMenuCharacterRegistration { action = "register", challengeShortCode = "BLUTEID", linkCode = text, characterId = characterId, characterName = characterName, clientVersion = "2.12.50" }; string text2 = Plugin.ApiBaseUrl.Value.TrimEnd(new char[1] { '/' }) + "/api/valheim/admission"; byte[] bytes = Encoding.UTF8.GetBytes(ChallengeHubJson.Serialize(value)); UnityWebRequest request = new UnityWebRequest(text2, "POST"); try { request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bytes); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); request.SetRequestHeader("x-challengehub-key", Plugin.ApiKey.Value ?? string.Empty); request.timeout = 15; yield return request.SendWebRequest(); if ((int)request.result != 1) { _message = ((request.responseCode == 401) ? "Player-Link-Code oder Challenge-Zugang ungültig" : "Charakter konnte nicht übertragen werden"); ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Blut-Eid Charakterregistrierung fehlgeschlagen: HTTP " + request.responseCode + " " + request.error)); } yield break; } } finally { ((IDisposable)request)?.Dispose(); } _message = characterName + " übertragen · Schwierigkeit in der Webapp wählen"; Application.OpenURL(Plugin.ApiBaseUrl.Value.TrimEnd(new char[1] { '/' }) + "/deathrun?characterId=" + UnityWebRequest.EscapeURL(characterId) + "&source=valheim"); yield return WaitForPreparedWorld(startup, characterId); } private IEnumerator WaitForPreparedWorld(FejdStartup startup, string characterId) { float deadline = Time.realtimeSinceStartup + 1800f; while (Time.realtimeSinceStartup < deadline) { string text = Plugin.ApiBaseUrl.Value.TrimEnd(new char[1] { '/' }) + "/api/valheim/deathrun?characterId=" + UnityWebRequest.EscapeURL(characterId); UnityWebRequest request = UnityWebRequest.Get(text); try { ApplyMainMenuAuthorization(request); request.timeout = 12; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Blut-Eid: Run-Status wird direkt bei ChallengeHub abgefragt."); } yield return request.SendWebRequest(); if ((int)request.result == 1) { DeathRunEnvelope deathRunEnvelope = ChallengeHubJson.Deserialize<DeathRunEnvelope>(request.downloadHandler.text); if (deathRunEnvelope != null && deathRunEnvelope.ok && deathRunEnvelope.run != null) { if (deathRunEnvelope.worldReady || string.Equals(deathRunEnvelope.run.worldPackageStatus, "ready", StringComparison.OrdinalIgnoreCase)) { yield return DownloadAndInstallWorld(startup, deathRunEnvelope.run); yield break; } _message = "Run " + deathRunEnvelope.run.worldCode + " · Welt wird vorbereitet ..."; } } } finally { ((IDisposable)request)?.Dispose(); } yield return (object)new WaitForSecondsRealtime(4f); } _message = "Weltvorbereitung dauert länger · Valheim kann geöffnet bleiben"; } internal void ResumeSelectedRun(FejdStartup startup, PlayerProfile selectedProfile) { if (!_resumeRunning && (Object)(object)startup != (Object)null && selectedProfile != null) { ((MonoBehaviour)this).StartCoroutine(ResumeSelectedRunRoutine(startup, selectedProfile)); } } private IEnumerator ResumeSelectedRunRoutine(FejdStartup startup, PlayerProfile selectedProfile) { _resumeRunning = true; yield return (object)new WaitForSecondsRealtime(0.35f); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("Blut-Eid: aktiver Run wird für Charakter " + (selectedProfile.GetName() ?? "unbekannt") + " gesucht.")); } string characterId = selectedProfile.GetPlayerID().ToString(); string text = Plugin.ApiBaseUrl.Value.TrimEnd(new char[1] { '/' }) + "/api/valheim/deathrun?characterId=" + UnityWebRequest.EscapeURL(characterId); UnityWebRequest request = UnityWebRequest.Get(text); try { ApplyMainMenuAuthorization(request); request.timeout = 12; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)"Blut-Eid: vorhandener Run wird direkt bei ChallengeHub abgefragt."); } yield return request.SendWebRequest(); if ((int)request.result != 1) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("Blut-Eid Run-Wiederaufnahme fehlgeschlagen: HTTP " + request.responseCode + " " + request.error)); } _resumeRunning = false; yield break; } DeathRunEnvelope deathRunEnvelope = ChallengeHubJson.Deserialize<DeathRunEnvelope>(request.downloadHandler.text); if (deathRunEnvelope == null || !deathRunEnvelope.ok || deathRunEnvelope.run == null) { _resumeRunning = false; yield break; } _message = "Aktiver Run " + deathRunEnvelope.run.worldCode + " wird fortgesetzt ..."; bool flag = deathRunEnvelope.worldReady || string.Equals(deathRunEnvelope.run.worldPackageStatus, "ready", StringComparison.OrdinalIgnoreCase); ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)("Blut-Eid: Run-Antwort empfangen; ready=" + flag + "; worldReady=" + deathRunEnvelope.worldReady + "; packageStatus=" + (deathRunEnvelope.run.worldPackageStatus ?? "<leer>"))); } if (flag) { string path = Path.Combine(Application.persistentDataPath, "worlds_local"); string path2 = Path.Combine(path, deathRunEnvelope.run.worldCode + ".db"); string path3 = Path.Combine(path, deathRunEnvelope.run.worldCode + ".fwl"); if (File.Exists(path2) && File.Exists(path3)) { _installedWorldCode = deathRunEnvelope.run.worldCode; RefreshAndSelectWorld(startup, deathRunEnvelope.run.worldCode); } else { _message = deathRunEnvelope.run.worldCode + " fehlt lokal · wird erneut heruntergeladen ..."; yield return DownloadAndInstallWorld(startup, deathRunEnvelope.run); } } else { yield return WaitForPreparedWorld(startup, characterId); } } finally { ((IDisposable)request)?.Dispose(); } _resumeRunning = false; } private static void ApplyMainMenuAuthorization(UnityWebRequest request) { string text = ((Plugin.PlayerLinkCode != null) ? (Plugin.PlayerLinkCode.Value ?? string.Empty).Trim() : string.Empty); request.SetRequestHeader("x-challengehub-key", Plugin.ApiKey.Value ?? string.Empty); request.SetRequestHeader("x-player-link-code", text); } private IEnumerator DownloadAndInstallWorld(FejdStartup startup, DeathRunWeb run) { _message = run.worldCode + " · Welt wird heruntergeladen ..."; string text = Plugin.ApiBaseUrl.Value.TrimEnd(new char[1] { '/' }) + "/api/valheim/deathrun/world?runId=" + UnityWebRequest.EscapeURL(run.id); UnityWebRequest request = UnityWebRequest.Get(text); try { ApplyMainMenuAuthorization(request); request.timeout = 60; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Blut-Eid: fertiges Weltpaket wird direkt heruntergeladen."); } yield return request.SendWebRequest(); if ((int)request.result != 1) { _message = "Welt-Download fehlgeschlagen · erneut auf die Kachel klicken"; yield break; } try { string text2 = Path.Combine(Application.persistentDataPath, "worlds_local"); Directory.CreateDirectory(text2); using (MemoryStream stream = new MemoryStream(request.downloadHandler.data, writable: false)) { using ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen: false); int num = 0; foreach (ZipArchiveEntry entry in zipArchive.Entries) { string fileName = Path.GetFileName(entry.FullName); string extension = Path.GetExtension(fileName); if (string.IsNullOrWhiteSpace(fileName) || (!extension.Equals(".db", StringComparison.OrdinalIgnoreCase) && !extension.Equals(".fwl", StringComparison.OrdinalIgnoreCase))) { continue; } string path = Path.Combine(text2, fileName); using (Stream stream2 = entry.Open()) { using FileStream destination = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None); stream2.CopyTo(destination); } num++; } if (num < 2) { throw new InvalidDataException("Weltpaket enthält keine vollständige .db/.fwl-Welt."); } } _installedWorldCode = run.worldCode; RefreshAndSelectWorld(startup, run.worldCode); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("Blut-Eid-Welt automatisch installiert: " + run.worldCode)); } } catch (Exception ex) { _message = "Welt konnte lokal nicht installiert werden"; ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("Automatische Blut-Eid-Weltinstallation fehlgeschlagen: " + ex)); } } } finally { ((IDisposable)request)?.Dispose(); } } private void RefreshAndSelectWorld(FejdStartup startup, string worldCode) { try { SaveSystem.InvalidateCache(); SaveSystem.ClearWorldListCache(false); AccessTools.Method(typeof(FejdStartup), "ShowStartGame", (Type[])null, (Type[])null)?.Invoke(startup, null); AccessTools.Method(typeof(FejdStartup), "UpdateWorldList", new Type[1] { typeof(bool) }, (Type[])null)?.Invoke(startup, new object[1] { false }); FieldInfo fieldInfo = AccessTools.Field(typeof(FejdStartup), "m_worlds"); IList<World> list = ((fieldInfo != null) ? (fieldInfo.GetValue(startup) as IList<World>) : null); FieldInfo fieldInfo2 = AccessTools.Field(typeof(World), "m_fileName"); FieldInfo fieldInfo3 = AccessTools.Field(typeof(World), "m_name"); int num = -1; if (list != null) { for (int i = 0; i < list.Count; i++) { World obj = list[i]; string a = ((fieldInfo2 != null) ? (fieldInfo2.GetValue(obj) as string) : string.Empty); string a2 = ((fieldInfo3 != null) ? (fieldInfo3.GetValue(obj) as string) : string.Empty); if (string.Equals(a, worldCode, StringComparison.OrdinalIgnoreCase) || string.Equals(a2, worldCode, StringComparison.OrdinalIgnoreCase)) { num = i; break; } } } if (num < 0) { _message = worldCode + " installiert · erneut auf die Kachel klicken"; ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Blut-Eid: installierte Welt wurde nach UpdateWorldList nicht gefunden: " + worldCode)); } return; } AccessTools.Method(typeof(FejdStartup), "SetSelectedWorld", new Type[2] { typeof(int), typeof(bool) }, (Type[])null)?.Invoke(startup, new object[2] { num, true }); AccessTools.Method(typeof(FejdStartup), "RefreshWorldSelection", (Type[])null, (Type[])null)?.Invoke(startup, null); _message = worldCode + " ausgewählt · Multiplayer und Passwort festlegen, dann Start drücken"; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("Blut-Eid: Weltliste aktualisiert und Run-Welt ausgewählt: " + worldCode)); } } catch (Exception ex) { _message = "Weltliste konnte nicht aktualisiert werden · erneut auf die Kachel klicken"; ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("Blut-Eid Weltlisten-Aktualisierung fehlgeschlagen: " + ex)); } } } internal static PlayerProfile SelectedProfile(FejdStartup startup) { FieldInfo fieldInfo = AccessTools.Field(typeof(FejdStartup), "m_profiles"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(FejdStartup), "m_profileIndex"); IList<PlayerProfile> list = ((fieldInfo != null) ? (fieldInfo.GetValue(startup) as IList<PlayerProfile>) : null); int num = ((fieldInfo2 != null) ? Convert.ToInt32(fieldInfo2.GetValue(startup)) : (-1)); if (list == null || num < 0 || num >= list.Count) { return null; } return list[num]; } private void EnsureAssets() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0091: 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_00bd: 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_00d1: Expected O, but got Unknown //IL_00f0: 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_010a: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0180: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown if (_button != null) { return; } _button = new GUIStyle(GUI.skin.button); GUIStyleState normal = _button.normal; GUIStyleState hover = _button.hover; Texture2D val = (_button.active.background = null); Texture2D background = (hover.background = val); normal.background = background; _button.focused.background = null; _panel = new Texture2D(1, 1, (TextureFormat)4, false); _panel.SetPixel(0, 0, new Color(0.035f, 0.045f, 0.04f, 0.94f)); _panel.Apply(); _title = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 27, fontStyle = (FontStyle)1 }; _title.normal.textColor = new Color(0.96f, 0.77f, 0.35f, 1f); _status = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 17, fontStyle = (FontStyle)1, wordWrap = true }; _status.normal.textColor = new Color(0.55f, 0.86f, 0.62f, 1f); _version = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 14, fontStyle = (FontStyle)1 }; _version.normal.textColor = new Color(0.9f, 0.91f, 0.86f, 1f); try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ChallengeHubValheim.Assets.BlutEid.png"); using MemoryStream memoryStream = new MemoryStream(); stream?.CopyTo(memoryStream); _image = new Texture2D(2, 2, (TextureFormat)4, false); if (stream == null || !LoadImageCompat(_image, memoryStream.ToArray())) { Object.Destroy((Object)(object)_image); _image = null; } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Blut-Eid-Titelbild konnte nicht geladen werden: " + ex.Message)); } } } private static bool LoadImageCompat(Texture2D texture, byte[] bytes) { Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule", throwOnError: false); MethodInfo methodInfo = ((type != null) ? type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }, null) : null); if (methodInfo == null) { return false; } object obj = methodInfo.Invoke(null, new object[3] { texture, bytes, true }); if (obj is bool) { return (bool)obj; } return false; } } [HarmonyPatch(typeof(FejdStartup), "OnSelelectCharacterBack")] internal static class BlutEidShowCardOnMainMenuReturnPatch { private static void Postfix() { BlutEidStartupBehaviour.CharacterSelected = false; } } [HarmonyPatch(typeof(FejdStartup), "OnCharacterStart")] internal static class BlutEidCharacterStartFallbackPatch { private static void Prefix(FejdStartup __instance, ref PlayerProfile __state) { __state = BlutEidStartupBehaviour.SelectedProfile(__instance); } private static void Postfix(FejdStartup __instance, PlayerProfile __state) { BlutEidStartupBehaviour.CharacterSelected = true; BlutEidStartupBehaviour blutEidStartupBehaviour = (((Object)(object)Plugin.Instance != (Object)null) ? ((Component)Plugin.Instance).GetComponent<BlutEidStartupBehaviour>() : null); if ((Object)(object)blutEidStartupBehaviour != (Object)null && __state != null) { blutEidStartupBehaviour.ResumeSelectedRun(__instance, __state); return; } ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"Blut-Eid: ausgewähltes Charakterprofil konnte beim Start nicht übernommen werden."); } } private static IEnumerator OpenWorldSelectionIfStillClosed(FejdStartup startup) { yield return (object)new WaitForSecondsRealtime(0.35f); if ((Object)(object)startup == (Object)null) { yield break; } Scene activeScene = SceneManager.GetActiveScene(); if (!string.Equals(((Scene)(ref activeScene)).name, "start", StringComparison.OrdinalIgnoreCase)) { yield break; } FieldInfo fieldInfo = AccessTools.Field(typeof(FejdStartup), "m_startGamePanel"); GameObject val = (GameObject)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null && val.activeInHierarchy) { yield break; } MethodInfo methodInfo = AccessTools.Method(typeof(FejdStartup), "ShowStartGame", (Type[])null, (Type[])null); if (methodInfo == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"Blut-Eid: FejdStartup.ShowStartGame wurde nicht gefunden."); } yield break; } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)"Blut-Eid: Weltwahl-Fallback nach Charakterauswahl aktiviert."); } methodInfo.Invoke(startup, null); } } [Serializable] internal sealed class BossArenaResetRecord { public string id = string.Empty; public string boss = string.Empty; public float x; public float y; public float z; public string queuedAtUtc = string.Empty; } [Serializable] internal sealed class BossArenaResetStore { public BossArenaResetRecord[] pending = new BossArenaResetRecord[0]; } internal static class BossArenaResetFeature { private static Plugin _plugin; private static ConfigEntry<bool> _enabled; private static ConfigEntry<float> _radius; private static ConfigEntry<float> _clearSeconds; private static readonly List<BossArenaResetRecord> Pending = new List<BossArenaResetRecord>(); private static readonly Dictionary<string, float> ClearSince = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase); private static bool _loaded; private static bool _processing; private static string StorePath => Path.Combine(Paths.ConfigPath, "ChallengeHubValheim", "boss-arena-resets.json"); private static float Radius => Mathf.Clamp(_radius?.Value ?? 100f, 25f, 200f); internal static void Initialize(Plugin plugin) { _plugin = plugin; _enabled = ((BaseUnityPlugin)plugin).Config.Bind<bool>("BossArenaReset", "Enabled", true, "Setzt den Bossbereich nach dem Bosskill zurueck, sobald kein Spieler mehr im Radius ist."); _radius = ((BaseUnityPlugin)plugin).Config.Bind<float>("BossArenaReset", "Radius", 100f, "Radius des Bossbereichs in Metern."); _clearSeconds = ((BaseUnityPlugin)plugin).Config.Bind<float>("BossArenaReset", "PlayerFreeConfirmSeconds", 5f, "Durchgehend spielerfreie Zeit vor dem Reset."); ((MonoBehaviour)plugin).StartCoroutine(Loop()); } internal static void Queue(Vector3 center, string boss, string completionId) { //IL_0058: 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_00d0: 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_00e8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_plugin == (Object)null || _enabled == null || !_enabled.Value || !ChallengeHubWorldState.IsServer) { return; } EnsureLoaded(); string id = (string.IsNullOrWhiteSpace(completionId) ? (Plugin.NormalizeKey(boss) + ":" + Mathf.RoundToInt(center.x) + ":" + Mathf.RoundToInt(center.z)) : completionId); if (!Pending.Any((BossArenaResetRecord record) => string.Equals(record.id, id, StringComparison.OrdinalIgnoreCase))) { Pending.Add(new BossArenaResetRecord { id = id, boss = Plugin.CanonicalBossKey(boss), x = center.x, y = center.y, z = center.z, queuedAtUtc = DateTime.UtcNow.ToString("O", CultureInfo.InvariantCulture) }); Save(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("Bossbereich-Reset vorgemerkt: " + boss + "; Radius=" + Radius.ToString("0", CultureInfo.InvariantCulture) + "m.")); } } } private static IEnumerator Loop() { Vector3 center = default(Vector3); while (true) { yield return (object)new WaitForSeconds(2f); if (_processing || _enabled == null || !_enabled.Value || !ChallengeHubWorldState.IsServer || !ChallengeHubServerGateFeature.GameplayAllowed || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { continue; } EnsureLoaded(); BossArenaResetRecord bossArenaResetRecord = Pending.FirstOrDefault(); if (bossArenaResetRecord != null) { ((Vector3)(ref center))..ctor(bossArenaResetRecord.x, bossAren