Decompiled source of FogAndColdControl v1.2.0
plugins/Thanks.Fog&ColdControl.dll
Decompiled 2 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.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Thanks.Fog&ColdControl")] [assembly: AssemblyDescription("Host-only PEAK fog and cold control mode with synced fog movement, compass rewards, HUD, and separate fog-cold and night-cold handling.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Thanks")] [assembly: AssemblyProduct("Fog&ColdControl")] [assembly: AssemblyCopyright("Copyright (c) Thanks 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f3d09c64-b194-4a16-9196-85106f2f0d01")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.0.0")] [module: UnverifiableCode] [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 FogColdControl { [HarmonyPatch(typeof(Fog), "MakePlayerCold")] internal static class FogMakePlayerColdPatch { private static bool Prefix() { if (Plugin.ShouldSuppressFogColdDamage()) { return false; } Plugin.BeginLocalFogStatusSource(); return true; } private static Exception Finalizer(Exception __exception) { Plugin.EndLocalFogStatusSource(); return __exception; } } [HarmonyPatch(typeof(FogSphere), "SetSharderVars")] internal static class FogSphereSetShaderVarsPatch { private static void Prefix() { Plugin.BeginLocalFogStatusSource(); } private static Exception Finalizer(Exception __exception) { Plugin.EndLocalFogStatusSource(); return __exception; } } [HarmonyPatch(typeof(OrbFogHandler), "WaitToMove")] internal static class OrbFogHandlerWaitToMovePatch { private static bool Prefix(OrbFogHandler __instance) { return !Plugin.ShouldBlockVanillaOrbFogWait(__instance); } } [HarmonyPatch(typeof(OrbFogHandler), "Start")] internal static class OrbFogHandlerStartPatch { private static void Postfix(OrbFogHandler __instance) { Plugin.NotifyFogHandlerChanged(__instance); } } [HarmonyPatch(typeof(OrbFogHandler), "SetFogOrigin")] internal static class OrbFogHandlerSetFogOriginPatch { private static void Postfix(OrbFogHandler __instance) { Plugin.NotifyFogHandlerChanged(__instance); } } [HarmonyPatch(typeof(OrbFogHandler), "RPC_InitFog")] internal static class OrbFogHandlerRpcInitFogPatch { private static void Postfix(OrbFogHandler __instance, float s, bool moving, PhotonMessageInfo info) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) Plugin.NotifyFogHandlerChanged(__instance); if (info.Sender != null && info.Sender.IsMasterClient) { Plugin.NotifyGuestFogSnapshot(__instance, s, moving); } } } [HarmonyPatch(typeof(OrbFogHandler), "RPCA_SyncFog")] internal static class OrbFogHandlerSyncFogPatch { private static void Postfix(OrbFogHandler __instance, float s, bool moving) { Plugin.NotifyGuestFogSnapshot(__instance, s, moving); } } [HarmonyPatch(typeof(Ascents), "get_fogEnabled")] internal static class AscentsFogEnabledPatch { private static void Postfix(ref bool __result) { if (Plugin.ShouldForceFogCoverageEverywhere()) { __result = true; } } } [HarmonyPatch(typeof(Ascents), "get_isNightCold")] internal static class AscentsNightColdPatch { private static void Postfix(ref bool __result) { if (Plugin.ShouldDisableNightColdFeatureLocally()) { __result = false; } } } [HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")] internal static class CharacterAfflictionsAddStatusPatch { private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref bool __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.ShouldSuppressLocalFogSourceStatus(__instance, statusType)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Campfire), "Light_Rpc")] internal static class CampfireLightRpcPatch { private static void Postfix(Campfire __instance) { Plugin.NotifyCampfireLit(__instance); } } [HarmonyPatch(typeof(WindChillZone), "RPCA_ToggleWind")] internal static class WindChillZoneToggleWindPatch { private static void Postfix(WindChillZone __instance) { Plugin.NotifyWeatherTransition(__instance); } } internal static class NextBiomeResolver { private static readonly int KnownSegmentCount = Enum.GetValues(typeof(Segment)).Length; internal static bool TryGetNextBiome(MapHandler mapHandler, Segment currentSegment, out BiomeType biome) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected I4, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Invalid comparison between Unknown and I4 //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected I4, but got Unknown //IL_0108: 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) biome = (BiomeType)0; try { if ((Object)(object)mapHandler == (Object)null || !MapHandler.ExistsAndInitialized || RunSettings.isMiniRun || !Enum.IsDefined(typeof(Segment), currentSegment) || (int)currentSegment == 4 || (int)currentSegment == 5 || (int)currentSegment == 6) { return false; } MapSegment[] segments = mapHandler.segments; int num = (int)currentSegment; if (segments == null || segments.Length > KnownSegmentCount || num < 0 || num >= segments.Length - 1 || mapHandler.biomes == null) { return false; } MapSegment val = segments[num]; MapSegment val2 = segments[num + 1]; if (val == null || val2 == null || !HasReadableVariantChain(mapHandler, val) || !HasReadableVariantChain(mapHandler, val2)) { return false; } BiomeType biome2 = val.biome; BiomeType biome3 = val2.biome; if (!Enum.IsDefined(typeof(BiomeType), biome2) || !Enum.IsDefined(typeof(BiomeType), biome3) || !mapHandler.biomes.Contains(biome2) || !mapHandler.biomes.Contains(biome3)) { return false; } if ((int)currentSegment == 3 && biome2 == biome3) { return false; } biome = (BiomeType)(int)biome3; return true; } catch (Exception) { return false; } } private static bool HasReadableVariantChain(MapHandler mapHandler, MapSegment segment) { MapSegment[] variantSegments = mapHandler.variantSegments; int num = ((variantSegments != null) ? variantSegments.Length : 0) + 1; while (segment.hasVariant) { int variantBiomeIndex = segment.variantBiomeIndex; if (num-- <= 0 || mapHandler.biomes == null || variantSegments == null || variantBiomeIndex < 0 || variantBiomeIndex >= variantSegments.Length || variantSegments[variantBiomeIndex] == null) { return false; } segment = variantSegments[variantBiomeIndex]; } return true; } } internal enum WeatherHazardKind { Wind, Snow, Rain } internal static class WeatherWarningText { internal static bool IsKnownKind(WeatherHazardKind kind) { if (kind != WeatherHazardKind.Wind && kind != WeatherHazardKind.Snow) { return kind == WeatherHazardKind.Rain; } return true; } internal static bool IsValidRemaining(float seconds) { if (!float.IsNaN(seconds) && !float.IsInfinity(seconds) && seconds > 0.05f) { return seconds <= 9999.9f; } return false; } internal static bool TryFormat(WeatherHazardKind kind, float seconds, bool incoming, bool chinese, out string prefix, out string timer, out string suffix) { prefix = (timer = (suffix = string.Empty)); if (!IsKnownKind(kind) || !IsValidRemaining(seconds)) { return false; } prefix = "<color=#FF7B7B>" + kind switch { WeatherHazardKind.Wind => chinese ? "强风" : "Strong winds", WeatherHazardKind.Snow => chinese ? "暴风雪" : "Snowstorm", _ => chinese ? "暴雨" : "Heavy rain", } + "</color>" + ((!chinese) ? (incoming ? " arriving in " : " ending in ") : (incoming ? "将在" : "还剩")); timer = Math.Ceiling(seconds).ToString(CultureInfo.InvariantCulture); suffix = ((!chinese) ? " seconds!" : (incoming ? "秒后到来!" : "秒结束")); return true; } } internal static class WeatherWarningLayout { internal static bool TryFitLine(float prefixWidth, float timerWidth, float suffixWidth, float availableWidth, out float width, out float scale) { width = (scale = 0f); float[] array = new float[4] { prefixWidth, timerWidth, suffixWidth, availableWidth }; foreach (float num in array) { if (float.IsNaN(num) || float.IsInfinity(num) || num <= 0f) { return false; } } float num2 = prefixWidth + timerWidth + suffixWidth + 30f; if (float.IsInfinity(num2)) { return false; } scale = Math.Min(1f, availableWidth / num2); if (scale < 0.53846157f) { return false; } width = num2 * scale; return true; } internal static bool TryGetCenterY(float safeBottom, float safeTop, float height, float? locatorBottom, out float center) { center = 0f; if (float.IsNaN(safeBottom) || float.IsInfinity(safeBottom) || float.IsNaN(safeTop) || float.IsInfinity(safeTop) || float.IsNaN(height) || float.IsInfinity(height) || height <= 0f || safeTop - safeBottom < height) { return false; } float num = height * 0.5f; float num2 = safeTop - 40f - num; if (locatorBottom.HasValue) { float value = locatorBottom.Value; if (float.IsNaN(value) || float.IsInfinity(value)) { return false; } num2 = Math.Min(num2, value - 10f - num); if (num2 < safeBottom + num) { return false; } } center = Math.Max(num2, safeBottom + num); return true; } } internal static class HudPanelLayout { internal static bool TryFit(float canvasWidth, float canvasHeight, float width, float height, float requestedScale, float requestedX, float requestedY, out float scale, out float x, out float y) { scale = 1f; x = (y = 0f); if (!IsPositiveFinite(canvasWidth) || !IsPositiveFinite(canvasHeight) || !IsPositiveFinite(width) || !IsPositiveFinite(height)) { return false; } requestedScale = (IsPositiveFinite(requestedScale) ? Math.Max(0.5f, Math.Min(2.5f, requestedScale)) : 0.9f); scale = Math.Min(requestedScale, Math.Min(canvasWidth / width, canvasHeight / height)); x = ClampPosition(requestedX, Math.Max(0f, canvasWidth - width * scale)); y = ClampPosition(requestedY, Math.Max(0f, canvasHeight - height * scale)); return IsPositiveFinite(scale); } private static float ClampPosition(float value, float maximum) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return Math.Max(0f, Math.Min(value, maximum)); } return 0f; } private static bool IsPositiveFinite(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return value > 0f; } return false; } } internal static class HudNumericText { internal static string Compact(string value) { if (!string.IsNullOrEmpty(value)) { return "<mspace=0.65em>" + value + "</mspace>"; } return string.Empty; } } internal static class HudModuleLayout { internal readonly struct Placement { internal readonly float X; internal readonly float Y; internal readonly float Width; internal Placement(float x, float y, float width) { X = x; Y = y; Width = width; } } internal static Placement[] Arrange(IReadOnlyList<float> moduleWidths, bool vertical, float spacing, float moduleHeight, float paddingX, float paddingY, out float width, out float height) { int count = moduleWidths.Count; width = (height = 0f); if (count == 0) { return Array.Empty<Placement>(); } for (int i = 0; i < count; i++) { width = (vertical ? Math.Max(width, moduleWidths[i]) : (width + moduleWidths[i])); } width += paddingX * 2f + (vertical ? 0f : (spacing * (float)(count - 1))); height = paddingY * 2f + (vertical ? (moduleHeight * (float)count + spacing * (float)(count - 1)) : moduleHeight); Placement[] array = new Placement[count]; float num = paddingX; for (int j = 0; j < count; j++) { array[j] = new Placement(vertical ? paddingX : num, vertical ? (height - paddingY - moduleHeight - (float)j * (moduleHeight + spacing)) : paddingY, moduleWidths[j]); num += moduleWidths[j] + spacing; } return array; } } internal static class FogEtaText { internal const string UnknownText = "--:--"; internal const float MinimumRate = 0.02f; internal static bool TryEstimate(float remainingUnits, float unitsPerSecond, out float etaSeconds) { etaSeconds = 0f; if (!IsUsable(remainingUnits) || !IsUsable(unitsPerSecond)) { return false; } if (remainingUnits <= 0.05f) { return true; } if (unitsPerSecond < 0.02f) { return false; } etaSeconds = remainingUnits / unitsPerSecond; return IsUsable(etaSeconds); } internal static string Format(float etaSeconds) { int num = Math.Max(0, (int)Math.Ceiling(IsUsable(etaSeconds) ? etaSeconds : 0f)); return string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}", num / 60, num % 60); } internal static string FormatOrUnknown(bool hasEta, float etaSeconds) { if (!hasEta) { return "--:--"; } return Format(etaSeconds); } private static bool IsUsable(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } [HarmonyPatch] internal static class ModConfigSettingNamePatch { private static bool _logged; private static bool Prepare() { List<MethodBase> list = ModConfigPatchTypes.ResolveSettingMethods("GetDisplayName"); ModConfigPatchTypes.LogResolvedOnce(ref _logged, "display-name", list.Count); return list.Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return ModConfigPatchTypes.ResolveSettingMethods("GetDisplayName"); } private static void Postfix(object __instance, ref string __result) { if (Plugin.TryGetLocalizedModConfigSettingName(__instance, out var localizedName)) { __result = localizedName; } } } [HarmonyPatch] internal static class ModConfigSettingCategoryPatch { private static bool _logged; private static bool Prepare() { List<MethodBase> list = ModConfigPatchTypes.ResolveSettingMethods("GetCategory"); ModConfigPatchTypes.LogResolvedOnce(ref _logged, "category", list.Count); return list.Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return ModConfigPatchTypes.ResolveSettingMethods("GetCategory"); } private static void Postfix(object __instance, ref string __result) { if (Plugin.TryGetLocalizedModConfigCategoryName(__instance, out var localizedName)) { __result = localizedName; } } } [HarmonyPatch] internal static class ModConfigFloatFormatPatch { private static bool Prepare() { return ModConfigPatchTypes.ResolveFloatSettingMethod("GetFormattedString") != null; } private static MethodBase TargetMethod() { return ModConfigPatchTypes.ResolveFloatSettingMethod("GetFormattedString"); } private static void Postfix(float value, ref string __result) { if (!string.IsNullOrEmpty(__result) && __result.IndexOf('%') < 0 && !(Mathf.Abs(value - Mathf.Round(value)) < 0.0005f)) { __result = value.ToString("0.###", CultureInfo.InvariantCulture); } } } [HarmonyPatch] internal static class ModConfigFloatSliderPatch { private static bool Prepare() { return ModConfigPatchTypes.ResolveFloatSettingMethod("Setup") != null; } private static MethodBase TargetMethod() { return ModConfigPatchTypes.ResolveFloatSettingMethod("Setup"); } private static void Postfix(object __0, Slider ___slider) { if (!((Object)(object)___slider == (Object)null) && Plugin.IsModConfigFloatSetting(__0)) { ___slider.wholeNumbers = false; } } } [HarmonyPatch] internal static class ModConfigMenuRelocalizePatch { private static bool _logged; private static bool Prepare() { List<MethodBase> list = ModConfigPatchTypes.ResolveMenuRefreshMethods(); ModConfigPatchTypes.LogResolvedOnce(ref _logged, "menu relocalize", list.Count); return list.Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return ModConfigPatchTypes.ResolveMenuRefreshMethods(); } private static void Postfix(object __instance) { Plugin.Instance?.ScheduleModConfigUiLocalization(__instance); } } internal static class ModConfigMenuUiLocalizer { private const string TabsButtonTypeName = "PEAKLib.ModConfig.Components.ModdedTABSButton"; internal static object ResolveMenuInstance() { Type type = AccessTools.TypeByName("PEAKLib.ModConfig.Components.ModSettingsMenu"); if (type == null) { return null; } try { return type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); } catch { return null; } } internal static bool Localize(object menuInstance) { Object val = (Object)((menuInstance is Object) ? menuInstance : null); if (val == null || val == (Object)null) { return false; } try { Dictionary<string, string> map = Plugin.BuildModConfigUiTextMap(); int num = LocalizeSettingCells(menuInstance, map); int num2 = LocalizeTabs(menuInstance, map); if (num > 0 || num2 > 0) { Plugin.LogInfo($"[Fog&ColdControl] ModConfig UI relocalized: {num} rows, {num2} tabs."); } } catch { } return true; } private static int LocalizeSettingCells(object menuInstance, Dictionary<string, string> map) { if (!(AccessTools.Field(menuInstance.GetType(), "m_spawnedCells")?.GetValue(menuInstance) is IList list)) { return 0; } int num = 0; foreach (object item in list) { if (item != null && ApplyLocalizedText((TMP_Text)/*isinst with value type is only supported in some contexts*/, map)) { num++; } } return num; } private static int LocalizeTabs(object menuInstance, Dictionary<string, string> map) { if (!IsOwnedMenuContext(menuInstance)) { return 0; } Component val = (Component)((menuInstance is Component) ? menuInstance : null); Type type = AccessTools.TypeByName("PEAKLib.ModConfig.Components.ModdedTABSButton"); if ((Object)(object)val == (Object)null || type == null) { return 0; } int num = 0; Component[] componentsInChildren = val.GetComponentsInChildren(type, true); for (int i = 0; i < componentsInChildren.Length; i++) { TMP_Text[] componentsInChildren2 = componentsInChildren[i].GetComponentsInChildren<TMP_Text>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if (ApplyLocalizedText(componentsInChildren2[j], map)) { num++; } } } return num; } private static bool IsOwnedMenuContext(object menuInstance) { string text = AccessTools.Field(menuInstance.GetType(), "selectedMod")?.GetValue(menuInstance) as string; if (!string.IsNullOrEmpty(text)) { return string.Equals(text, "Fog&ColdControl", StringComparison.OrdinalIgnoreCase); } return true; } private static bool ApplyLocalizedText(TMP_Text text, Dictionary<string, string> map) { if ((Object)(object)text == (Object)null) { return false; } string text2 = text.text; if (string.IsNullOrEmpty(text2)) { return false; } if (!map.TryGetValue(text2.Trim(), out var value) || string.IsNullOrEmpty(value) || string.Equals(text2, value, StringComparison.Ordinal)) { return false; } text.text = value; return true; } } internal static class ModConfigPatchTypes { internal const string ModConfigAssemblyName = "com.github.PEAKModding.PEAKLib.ModConfig"; internal const string MenuTypeName = "PEAKLib.ModConfig.Components.ModSettingsMenu"; private const string FloatSettingUiTypeName = "Zorro.Settings.UI.FloatSettingUI"; private const string SettingInterfaceName = "PEAKLib.ModConfig.IBepInExProperty"; internal static List<MethodBase> ResolveMenuRefreshMethods() { List<MethodBase> list = new List<MethodBase>(); Type type = AccessTools.TypeByName("PEAKLib.ModConfig.Components.ModSettingsMenu"); if (type == null) { return list; } AddResolvedMethod(list, AccessTools.Method(type, "ShowSettings", Type.EmptyTypes, (Type[])null)); AddResolvedMethod(list, AccessTools.Method(type, "OnEnable", Type.EmptyTypes, (Type[])null)); AddResolvedMethod(list, AccessTools.Method(type, "UpdateSectionTabs", new Type[1] { typeof(string) }, (Type[])null)); return list; } private static void AddResolvedMethod(List<MethodBase> methods, MethodBase method) { if (method != null && !method.ContainsGenericParameters && !methods.Contains(method)) { methods.Add(method); } } internal static void LogResolvedOnce(ref bool logged, string label, int targetCount) { if (!logged) { logged = true; Plugin.LogInfo($"[Fog&ColdControl] ModConfig {label} targets: {targetCount}."); } } internal static List<MethodBase> ResolveSettingMethods(string methodName) { List<MethodBase> list = new List<MethodBase>(); try { Type type = AccessTools.TypeByName("PEAKLib.ModConfig.IBepInExProperty"); if (type?.Assembly == null) { return list; } Type[] types = type.Assembly.GetTypes(); foreach (Type type2 in types) { if (!type2.ContainsGenericParameters && type.IsAssignableFrom(type2) && !(type2 == type)) { MethodBase methodBase = AccessTools.Method(type2, methodName, Type.EmptyTypes, (Type[])null); if (!(methodBase == null) && !methodBase.ContainsGenericParameters && !list.Contains(methodBase)) { list.Add(methodBase); } } } } catch { } return list; } internal static MethodBase ResolveFloatSettingMethod(string methodName) { Type type = AccessTools.TypeByName("Zorro.Settings.UI.FloatSettingUI"); if (type == null) { return null; } if (string.Equals(methodName, "GetFormattedString", StringComparison.Ordinal)) { return AccessTools.Method(type, methodName, new Type[1] { typeof(float) }, (Type[])null); } return AccessTools.Method(type, methodName, (Type[])null, (Type[])null); } } internal sealed class FogSpeedSamples { private struct Sample { internal float Size; internal double Time; } private readonly List<Sample> _samples = new List<Sample>(); private int _origin = -1; private const double WindowSeconds = 5.0; private const double TimeoutSeconds = 12.0; internal static bool IsValidSpeed(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return value >= 0f; } return false; } internal void Reset() { _samples.Clear(); _origin = -1; } internal void Observe(int origin, float size, bool moving, double gameTime) { if (!moving || !IsValidSpeed(size) || double.IsNaN(gameTime) || double.IsInfinity(gameTime)) { Reset(); return; } if (_samples.Count > 0) { Sample sample = _samples[_samples.Count - 1]; if (_origin != origin || size > sample.Size + 0.01f || gameTime < sample.Time || gameTime - sample.Time > 12.0) { Reset(); } else if (gameTime == sample.Time) { return; } } _origin = origin; _samples.Add(new Sample { Size = size, Time = gameTime }); while (_samples.Count > 2 && _samples[1].Time <= gameTime - 5.0) { _samples.RemoveAt(0); } } internal bool TryGetSpeed(int origin, double gameTime, out float speed) { speed = 0f; if (_origin != origin || _samples.Count < 2 || double.IsNaN(gameTime) || double.IsInfinity(gameTime)) { return false; } Sample sample = _samples[0]; Sample sample2 = _samples[_samples.Count - 1]; double num = sample2.Time - sample.Time; if (num < 5.0 || gameTime < sample2.Time || gameTime - sample2.Time > 12.0) { return false; } speed = (float)((double)(sample.Size - sample2.Size) / num); if (IsValidSpeed(speed)) { return speed >= 0.02f; } return false; } } internal static class GameplayRules { internal static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } internal static bool ShouldShowMovingFogSpeed(bool moving, bool paused, bool arrived, float speed) { if (moving && !paused && !arrived && IsFinite(speed)) { return speed > 0f; } return false; } internal static bool TryGetVerticalHazardDistance(float playerHeight, float surfaceHeight, out float distance) { distance = 0f; if (!IsFinite(playerHeight) || !IsFinite(surfaceHeight)) { return false; } float num = playerHeight - surfaceHeight; if (!IsFinite(num)) { return false; } distance = Math.Max(num, 0f); return true; } internal static bool ShouldBlockFogStatus(bool localCharacter, bool skeleton, int statusIndex, bool fogSource, bool suppressFog) { if (localCharacter && fogSource && suppressFog) { return statusIndex == ((!skeleton) ? 2 : 0); } return false; } internal static float GetNightColdRate(bool enabled, bool skeleton, int progress, float dayFactor, float baseRate) { if (!enabled || skeleton || progress >= 3 || !IsFinite(dayFactor) || dayFactor >= 0.5f || !IsFinite(baseRate) || baseRate <= 0f) { return 0f; } return baseRate * (1f - Math.Max(0f, dayFactor)); } internal static float GetFogDamageRate(float baseRate, float difficulty) { float num = ((IsFinite(baseRate) && IsFinite(difficulty)) ? (Math.Max(0f, baseRate) * Math.Max(0f, difficulty)) : 0f); if (!IsFinite(num)) { return 0f; } return num; } internal static float GetWeatherRemaining(float remaining, double sentAt, double now, float timeScale) { return (float)Math.Max(0.0, (double)remaining - Math.Max(0.0, now - sentAt) * (double)timeScale); } } internal sealed class StatusCompensationLedger { private struct Entry { internal int Status; internal float Pending; } private readonly Dictionary<int, Entry> _entries = new Dictionary<int, Entry>(); internal float Accumulate(int actor, int status, float rate, float gameElapsed, bool send) { _entries.TryGetValue(actor, out var value); if (value.Status != status) { value.Pending = 0f; } value.Status = status; if (GameplayRules.IsFinite(rate) && rate > 0f && GameplayRules.IsFinite(gameElapsed) && gameElapsed > 0f) { float num = value.Pending + rate * gameElapsed; if (GameplayRules.IsFinite(num)) { value.Pending = num; } } float result = (send ? value.Pending : 0f); if (send) { _entries.Remove(actor); return result; } _entries[actor] = value; return result; } internal void Remove(int actor) { _entries.Remove(actor); } internal void Clear() { _entries.Clear(); } internal void Retain(HashSet<int> actors) { int[] array = _entries.Keys.Where((int actor) => !actors.Contains(actor)).ToArray(); foreach (int key in array) { _entries.Remove(key); } } } [BepInPlugin("com.github.Thanks.FogClimb", "Fog&ColdControl", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin, IOnEventCallback { private sealed class PendingWeatherSnapshot { internal object[] Data; internal int Sender; internal float ReceivedAt; } private enum ConfigKey { ModEnabled, FogColdSuppression, NightColdEnabled, FogSpeed, FogDelay, CompassEnabled, CompassHotkey, FogPauseHotkey, FogUiEnabled, CampfireLocatorUiEnabled, FogUiX, FogUiY, FogUiScale, FogUiEntrySpacing, FogUiLayout, FogUiBackgroundOpacity, FogStateUiEnabled, RunTimerUiEnabled, DayNightTimeUiEnabled, AltitudeUiEnabled, FogSpeedUiEnabled, CampfireDistanceUiEnabled, WeatherHazardUiEnabled, FogTimingUiEnabled, DirectStartUiEnabled, FogApproachUiEnabled, LavaApproachUiEnabled, NextBiomeUiEnabled } internal enum FogUiLayoutKind { Horizontal, Vertical } private enum VanillaProgressStartUiState { Hidden, Unavailable, Tracking } private enum FogUiIconKind { StateRunning, StateWaiting, StatePaused, StateArrived, StateSyncing, StateOff, StateLobby, StateIdle, Speed, Delay, Timer, Campfire, Biome, Altitude, Lava, Distance, Direct, FogHandling, Night, DayTime, NightTime, Wind, Snowstorm, Rain } private enum FogUiThemeKind { Day, Night, Fog } private sealed class FogUiEntryView { public RectTransform Root; public Image Icon; public TextMeshProUGUI Text; public string LastText = string.Empty; public FogUiIconKind LastIconKind; public Color LastIconColor = Color.clear; public Color LastTextColor = Color.clear; public float LastContentWidth = -1f; } private sealed class ConfigFileEntryBlock { public ConfigKey Key; public bool HasKnownKey; public string SectionName = string.Empty; public List<string> Lines = new List<string>(); } private readonly struct FogUiDisplayEntry { public readonly FogUiIconKind Kind; public readonly Color IconColor; public readonly string Text; public FogUiDisplayEntry(FogUiIconKind kind, Color iconColor, string text) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Kind = kind; IconColor = iconColor; Text = text ?? string.Empty; } } private const int StatusProtocolVersion = 2; private const string StatusProtocolKey = "FogClimb.StatusProtocol"; private const string StatusSceneKey = "FogClimb.StatusScene"; private const string SuppressFogKey = "FogClimb.SuppressFog"; private const string SuppressNightKey = "FogClimb.SuppressNight"; private const byte WeatherSnapshotEventCode = 169; private const string WeatherSnapshotTag = "FogClimb.Weather.2"; private readonly HashSet<int> _pendingWeatherActors = new HashSet<int>(); private readonly List<PendingWeatherSnapshot> _pendingWeatherSnapshots = new List<PendingWeatherSnapshot>(); private readonly Dictionary<WindChillZone, double> _weatherTransitionTimes = new Dictionary<WindChillZone, double>(); private static readonly FieldInfo WindDurationField = AccessTools.Field(typeof(WindChillZone), "timeUntilNextWind"); private static readonly FieldInfo WindRemainingField = AccessTools.Field(typeof(WindChillZone), "untilSwitch"); private static readonly FieldInfo WindDirectionField = AccessTools.Field(typeof(WindChillZone), "currentWindDirection"); private static readonly FieldInfo WindActiveTimeField = AccessTools.Field(typeof(WindChillZone), "hasBeenActiveFor"); private static readonly FieldInfo WindForceField = AccessTools.Field(typeof(WindChillZone), "currentForceMult"); private readonly Dictionary<OrbFogHandler, float> _originalFogSpeeds = new Dictionary<OrbFogHandler, float>(); private readonly Dictionary<FogSphereOrigin, bool> _originalFogDisabled = new Dictionary<FogSphereOrigin, bool>(); private readonly Dictionary<GameObject, bool> _originalFogObjectActive = new Dictionary<GameObject, bool>(); public const string PluginGuid = "com.github.Thanks.FogClimb"; public const string PluginName = "Fog&ColdControl"; public const string PluginVersion = "1.2.0"; private static readonly string[] LegacyConfigFileNames = new string[2] { "Thanks.FogClimb.cfg", "com.github.Thanks.FogClimb.cfg" }; private static readonly string[] LegacyPluginFileNames = new string[2] { "Thanks.FogClimb.dll", "com.github.Thanks.FogClimb.dll" }; private const float DefaultFogUiEntrySpacing = 8f; private const float MinFogUiEntrySpacing = 0f; private const float MaxFogUiEntrySpacing = 40f; private const float DefaultFogUiBackgroundOpacity = 0f; private const float MinFogUiBackgroundOpacity = 0f; private const float MaxFogUiBackgroundOpacity = 1f; private const int FogUiBackgroundSpriteSize = 64; private const float FogUiBackgroundCornerRadiusX = 12f; private const float FogUiBackgroundCornerRadiusY = 10f; private const float FogUiBackgroundSliceBorderX = 12f; private const float FogUiBackgroundSliceBorderY = 10f; private const float FogUiVerticalContainerWidth = 176f; private const float FogUiVerticalMinHeight = 34f; private const float FogUiEntryHeight = 34f; private const float FogUiHorizontalWidth = 1180f; private const float FogUiHorizontalHeight = 34f; private const float FogUiBackgroundVerticalPadding = 2f; private const float FogUiIconSize = 20f; private const float FogUiEntryIconTextSpacing = 4f; private const float CampfireLocatorUiWidth = 420f; private const float CampfireLocatorUiHeight = 52f; private const float CampfireLocatorLineWidth = 400f; private const float CampfireLocatorLineHeight = 2f; private const float CampfireLocatorDotSize = 22f; private const float CampfireLocatorTickHeight = 8f; private const float CampfireLocatorTickWidth = 1.5f; private const float CampfireLocatorCenterTickHeight = 12f; private const float CampfireLocatorCenterTickWidth = 2.5f; private const float CampfireLocatorDistanceFontSize = 14f; private const float WeatherIncomingWarningSeconds = 5f; private const float WeatherNoticeFontSize = 22f; private const string FogUiCountdownDangerLabelColor = "#FF6B5F"; private const string FogUiCountdownDangerValueColor = "#FFD0C8"; private const string FogUiDelayCountdownStartLabelColor = "#FF9A8A"; private const string FogUiDelayCountdownStartValueColor = "#FFD6D6"; private const string FogUiDelayCountdownEndLabelColor = "#FF5A4D"; private const string FogUiDelayCountdownEndValueColor = "#FFB0A8"; private const float FogUiEntryMaxWidth = 220f; private static readonly ushort CompassItemIdOverride = 0; private const string NetworkInstallStateKey = "FogClimb.Enabled"; private static readonly BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly PropertyInfo ConfigFileEntriesProperty = typeof(ConfigFile).GetProperty("Entries", InstanceBindingFlags); private static readonly FieldInfo BasePluginConfigBackingField = typeof(BaseUnityPlugin).GetField("<Config>k__BackingField", InstanceBindingFlags); private static readonly FieldInfo OrbFogHandlerOriginsField = typeof(OrbFogHandler).GetField("origins", InstanceBindingFlags); private static readonly FieldInfo OrbFogHandlerSphereField = typeof(OrbFogHandler).GetField("sphere", InstanceBindingFlags); private static readonly FieldInfo RunManagerRunStartedField = typeof(RunManager).GetField("runStarted", InstanceBindingFlags); private static readonly FieldInfo RunManagerTimerActiveField = typeof(RunManager).GetField("timerActive", InstanceBindingFlags); private static readonly int StatusTypeCount = Enum.GetNames(typeof(STATUSTYPE)).Length; private static readonly string[] DayNightTimeMemberCandidates = new string[6] { "timeOfDayNormalized", "currentTime", "time", "timeOfDay", "timeNormalized", "cycleTime" }; private static readonly string[] DayNightDayCountMemberCandidates = new string[7] { "dayCount", "dayIndex", "currentDay", "dayNumber", "daysPassed", "totalDays", "day" }; private static readonly ConfigKey[] BasicConfigFileOrder = new ConfigKey[5] { ConfigKey.FogColdSuppression, ConfigKey.NightColdEnabled, ConfigKey.FogSpeed, ConfigKey.FogDelay, ConfigKey.FogPauseHotkey }; private static readonly ConfigKey[] AdjustmentConfigFileOrder = new ConfigKey[23] { ConfigKey.ModEnabled, ConfigKey.FogUiEnabled, ConfigKey.CampfireLocatorUiEnabled, ConfigKey.FogStateUiEnabled, ConfigKey.RunTimerUiEnabled, ConfigKey.DayNightTimeUiEnabled, ConfigKey.AltitudeUiEnabled, ConfigKey.FogSpeedUiEnabled, ConfigKey.CampfireDistanceUiEnabled, ConfigKey.WeatherHazardUiEnabled, ConfigKey.FogTimingUiEnabled, ConfigKey.DirectStartUiEnabled, ConfigKey.FogApproachUiEnabled, ConfigKey.LavaApproachUiEnabled, ConfigKey.NextBiomeUiEnabled, ConfigKey.CompassEnabled, ConfigKey.CompassHotkey, ConfigKey.FogUiX, ConfigKey.FogUiY, ConfigKey.FogUiScale, ConfigKey.FogUiEntrySpacing, ConfigKey.FogUiLayout, ConfigKey.FogUiBackgroundOpacity }; private static readonly Color CampfireLocatorLineColor = new Color(1f, 1f, 1f, 0.95f); private static int _localFogStatusSourceDepth; private Harmony _harmony; private OrbFogHandler _orbFogHandler; private FogSphere _fogSphere; private Fog _legacyFog; private bool _fogStateInitialized; private bool _initialDelayCompleted; private int _trackedFogOriginId = -1; private float _fogDelayTimer; private float _fogHiddenBufferTimer; private float _fogHandlerSearchTimer; private float _lastFogStateSyncTime = -0.18f; private float _lastRemoteStatusSyncTime = -0.25f; private float _lastCompassGrantSyncTime = -0.75f; private bool _lastHadFogAuthority; private bool _lastModEnabledState; private bool _lastDetectedChineseLanguage; private bool _isRefreshingLanguage; private bool _pendingConfigFileLocalizationRefresh; private bool _pendingConfigFileLocalizationSave; private bool _pendingConfigFileOrderRefresh; private FogUiLayoutKind _lastFogUiLayout; private bool _hasAdvertisedInstallState; private bool _lastAdvertisedInstallState; private string _lastObservedRoomKey = string.Empty; private float _hiddenNightTestHoldTimer; private bool _hiddenNightTestTriggeredThisHold; private bool _fogPaused; private readonly HashSet<int> _grantedCampfireCompassIds = new HashSet<int>(); private readonly HashSet<int> _restoredCheckpointCampfireIds = new HashSet<int>(); private readonly Dictionary<int, int> _playerCompassGrantCounts = new Dictionary<int, int>(); private readonly Dictionary<int, float> _remotePlayerFirstSeenTimes = new Dictionary<int, float>(); private readonly Dictionary<int, int> _remotePlayerCompassBaselineCounts = new Dictionary<int, int>(); private readonly Dictionary<int, float> _pendingCampfireCompassGrantTimes = new Dictionary<int, float>(); private Item _compassItem; private RectTransform _fogUiRect; private bool _fogUiLayoutDirty; private int _lastFogUiEntryLayoutCount = -1; private float _lastFogUiEntrySpacing = -1f; private RectTransform _fogUiEntriesRect; private Image _fogUiBackgroundImage; private Sprite _fogUiBackgroundSprite; private bool _fogUiThemeInitialized; private FogUiThemeKind _fogUiThemeKind; private readonly List<FogUiEntryView> _fogUiEntryViews = new List<FogUiEntryView>(); private readonly List<FogUiDisplayEntry> _fogUiDisplayEntries = new List<FogUiDisplayEntry>(9); private readonly Dictionary<FogUiIconKind, Sprite> _fogUiIconSprites = new Dictionary<FogUiIconKind, Sprite>(); private Sprite _campfireLocatorDotSprite; private Sprite _campfireLocatorLineSprite; private Sprite _nativeCampfireIconSprite; private Sprite _nativePoisonIconSprite; private Sprite _nativeDrowsyIconSprite; private Sprite _nativeAltitudeIconSprite; private float _lastNativeIconAttemptTime = -999f; private StormVisual[] _cachedStormVisuals; private float _lastStormVisualScanTime = -999f; private WeatherHazardKind _weatherUiShownKind; private float _weatherUiShownRemaining; private bool _weatherUiShownIsWarning; private RectTransform _weatherHazardNoticeRect; private TextMeshProUGUI _weatherHazardNoticeText; private TextMeshProUGUI _weatherHazardTimerText; private TextMeshProUGUI _weatherHazardSuffixText; private readonly List<Material> _weatherNoticeMaterials = new List<Material>(); private float _weatherNoticeTimerWidth; private WeatherHazardKind _weatherNoticeLayoutKind; private bool _weatherNoticeLayoutIncoming; private static readonly bool EnableDebugDiagnostics = false; private static LavaRising _cachedSceneLavaRising; private static Segment _cachedSceneLavaSegment = (Segment)0; private static bool _cachedSceneLavaValid; private static float _cachedSceneLavaScanTime = -999f; private float _pendingWeatherStateBroadcastTime = -1f; private int _weatherStateBroadcastRetryCount; private RectTransform _campfireLocatorUiRect; private RectTransform _campfireLocatorDotRect; private Image _campfireLocatorDotImage; private TextMeshProUGUI _campfireLocatorDistanceText; private float _campfireLocatorCurrentDotX; private RectTransform _compassLobbyNoticeRect; private TextMeshProUGUI _compassLobbyNoticeText; private string _lastCompassLobbyNoticeText = string.Empty; private float _fogUiStateAnimTime; private bool _initialCompassGranted; private int _totalCompassGrantCount; private bool _hasSyncedFogStateSnapshot; private int _lastSyncedFogOriginId = -1; private float _lastSyncedFogSize = float.NaN; private bool _lastSyncedFogIsMoving; private bool _lastSyncedFogHasArrived; private int _delayedFogOriginId = -1; private int _pendingSyntheticFogSegmentId = -1; private int _activeSyntheticFogSegmentId = -1; private Vector3 _syntheticFogPoint; private float _syntheticFogStartSize; private int _fogDistanceTrackedOriginId = -1; private float _fogDistanceLastObservedSize = float.NaN; private float _fogDistanceLastObservedTime = -1f; private float _fogDistanceEstimatedUnitsPerSecond; private bool _fogDistanceHasReliableRate; private float _fogDistanceLastAppliedHandlerSpeed = -1f; private float _lastAdvertisedFogSpeed = -1f; private int _lastAdvertisedFogSpeedOrigin = -1; private string _lastAdvertisedFogSpeedScene; private float _lastFogSpeedAdvertiseTime = -999f; private float _syncedHostFogSpeed = -1f; private float _guestAppliedFogSpeed = -1f; private float _fogDistanceLastRefreshTime = -1f; private bool _fogDistanceHasSnapshot; private float _fogDistanceRemainingDistance; private float _lastGuestFogDiagLogTime = -999f; private float _lastHostFogSyncDiagLogTime = -999f; private float _lastInstallAdvertiseDiagLogTime = -999f; private static FieldInfo _stormVisualZoneField; private static FieldInfo _windChillDirectionField; private static FieldInfo _windChillUntilSwitchField; private static readonly FieldInfo MovingLavaStartedField = AccessTools.Field(typeof(MovingLava), "timeToMove"); private MovingLava[] _cachedKilnLava; private float _lastKilnLavaScan = -999f; private readonly StatusCompensationLedger _remoteStatusCompensation = new StatusCompensationLedger(); private static readonly FieldInfo CharacterInvincibilityField = AccessTools.Field(typeof(CharacterData), "isInvincible"); private readonly FogSpeedSamples _guestFogSpeedSamples = new FogSpeedSamples(); private OrbFogHandler _guestFogSampleHandler; private int _guestFogSampleHostId = -1; internal static ConfigEntry<bool> CompassEnabled { get; private set; } internal static ConfigEntry<KeyCode> CompassHotkey { get; private set; } internal static ConfigEntry<bool> ModEnabled { get; private set; } internal static ConfigEntry<bool> FogColdSuppression { get; private set; } internal static ConfigEntry<bool> NightColdEnabled { get; private set; } internal static ConfigEntry<float> FogSpeed { get; private set; } internal static ConfigEntry<float> FogDelay { get; private set; } internal static ConfigEntry<KeyCode> FogPauseHotkey { get; private set; } internal static ConfigEntry<bool> FogUiEnabled { get; private set; } internal static ConfigEntry<bool> CampfireLocatorUiEnabled { get; private set; } internal static ConfigEntry<float> FogUiX { get; private set; } internal static ConfigEntry<float> FogUiY { get; private set; } internal static ConfigEntry<float> FogUiScale { get; private set; } internal static ConfigEntry<float> FogUiEntrySpacing { get; private set; } internal static ConfigEntry<FogUiLayoutKind> FogUiLayout { get; private set; } internal static ConfigEntry<float> FogUiBackgroundOpacity { get; private set; } internal static ConfigEntry<bool> FogStateUiEnabled { get; private set; } internal static ConfigEntry<bool> RunTimerUiEnabled { get; private set; } internal static ConfigEntry<bool> DayNightTimeUiEnabled { get; private set; } internal static ConfigEntry<bool> AltitudeUiEnabled { get; private set; } internal static ConfigEntry<bool> FogSpeedUiEnabled { get; private set; } internal static ConfigEntry<bool> CampfireDistanceUiEnabled { get; private set; } internal static ConfigEntry<bool> WeatherHazardUiEnabled { get; private set; } internal static ConfigEntry<bool> FogTimingUiEnabled { get; private set; } internal static ConfigEntry<bool> DirectStartUiEnabled { get; private set; } internal static ConfigEntry<bool> FogApproachUiEnabled { get; private set; } internal static ConfigEntry<bool> LavaApproachUiEnabled { get; private set; } internal static ConfigEntry<bool> NextBiomeUiEnabled { get; private set; } internal static Plugin Instance { get; private set; } private static bool SupportsSourceStatusPolicy(Player player) { object obj; if (player == null) { obj = null; } else { Hashtable customProperties = player.CustomProperties; obj = ((customProperties != null) ? customProperties[(object)"FogClimb.StatusProtocol"] : null); } if (obj is int num) { return num >= 2; } return false; } private static bool UsesSourceStatusPolicy(Player player) { bool isEnabled = default(bool); return SupportsSourceStatusPolicy(player) && TryReadInstallState(player, out isEnabled) && isEnabled; } private void UpdateStatusPolicyAdvertisement() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00bf: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && PhotonNetwork.LocalPlayer != null) { bool flag = ShouldSuppressFogColdDamage(); bool flag2 = ShouldDisableNightColdFeatureLocally(); Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties; if (!object.Equals(customProperties[(object)"FogClimb.SuppressFog"], flag) || !object.Equals(customProperties[(object)"FogClimb.SuppressNight"], flag2) || !object.Equals(customProperties[(object)"FogClimb.StatusScene"], name)) { Player localPlayer = PhotonNetwork.LocalPlayer; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"FogClimb.SuppressFog", (object)flag); ((Dictionary<object, object>)val).Add((object)"FogClimb.SuppressNight", (object)flag2); ((Dictionary<object, object>)val).Add((object)"FogClimb.StatusScene", (object)name); localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } } private static bool TryReadHostStatusPolicy(out bool fog, out bool night) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) fog = (night = false); Player masterClient = PhotonNetwork.MasterClient; if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient && UsesSourceStatusPolicy(masterClient)) { object objA = masterClient.CustomProperties[(object)"FogClimb.StatusScene"]; Scene activeScene = SceneManager.GetActiveScene(); if (object.Equals(objA, ((Scene)(ref activeScene)).name)) { if (!(masterClient.CustomProperties[(object)"FogClimb.SuppressFog"] is bool flag) || !(masterClient.CustomProperties[(object)"FogClimb.SuppressNight"] is bool flag2)) { return false; } fog = flag; night = flag2; return true; } } return false; } public void OnEvent(EventData photonEvent) { if (photonEvent.Code == 169 && IsModFeatureEnabled() && PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient) { int sender = photonEvent.Sender; Player masterClient = PhotonNetwork.MasterClient; if (sender == ((masterClient != null) ? new int?(masterClient.ActorNumber) : ((int?)null)) && UsesSourceStatusPolicy(PhotonNetwork.MasterClient) && photonEvent.CustomData is object[] array && array.Length == 11 && object.Equals(array[0], "FogClimb.Weather.2")) { _pendingWeatherSnapshots.Add(new PendingWeatherSnapshot { Data = array, Sender = photonEvent.Sender, ReceivedAt = Time.unscaledTime }); } } } private void ApplyPendingWeatherSnapshots() { for (int num = _pendingWeatherSnapshots.Count - 1; num >= 0; num--) { PendingWeatherSnapshot pendingWeatherSnapshot = _pendingWeatherSnapshots[num]; if (IsModFeatureEnabled() && PhotonNetwork.InRoom) { int sender = pendingWeatherSnapshot.Sender; Player masterClient = PhotonNetwork.MasterClient; if (sender == ((masterClient != null) ? new int?(masterClient.ActorNumber) : ((int?)null)) && !(Time.unscaledTime - pendingWeatherSnapshot.ReceivedAt > 30f) && !TryApplyWeatherSnapshot(pendingWeatherSnapshot.Data)) { continue; } } _pendingWeatherSnapshots.RemoveAt(num); } } internal static void NotifyWeatherTransition(WindChillZone zone) { if ((Object)(object)Instance != (Object)null && (Object)(object)zone != (Object)null) { Instance._weatherTransitionTimes[zone] = PhotonNetwork.Time; } } private bool TryApplyWeatherSnapshot(object[] data) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) object objA = data[1]; Scene activeScene = SceneManager.GetActiveScene(); if (!object.Equals(objA, ((Scene)(ref activeScene)).name) || LoadingScreenHandler.loading) { return false; } if (!(data[2] is int num) || !(data[3] is bool flag) || !(data[4] is Vector3 val) || !(data[5] is float num2) || !(data[6] is float num3) || !(data[7] is double num4) || !(data[8] is float num5) || !(data[9] is float num6) || !(data[10] is float num7) || !GameplayRules.IsFinite(num6) || !GameplayRules.IsFinite(num7) || !GameplayRules.IsFinite(num2) || num2 < 0f || !GameplayRules.IsFinite(num3) || num3 <= 0f || !GameplayRules.IsFinite(num5) || num5 < 0f || double.IsNaN(num4) || double.IsInfinity(num4)) { return true; } PhotonView val2 = PhotonView.Find(num); WindChillZone val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<WindChillZone>() : null); if ((Object)(object)val3 == (Object)null || !((Behaviour)val3).isActiveAndEnabled || WindDurationField == null || WindRemainingField == null || WindDirectionField == null || WindActiveTimeField == null || WindForceField == null) { return false; } if (_weatherTransitionTimes.TryGetValue(val3, out var value) && value >= num4) { return true; } float num8 = (float)Math.Max(0.0, PhotonNetwork.Time - num4) * num5; float weatherRemaining = GameplayRules.GetWeatherRemaining(num2, num4, PhotonNetwork.Time, num5); if (weatherRemaining <= 0f) { return true; } val3.windActive = flag; WindRemainingField.SetValue(val3, weatherRemaining); WindDurationField.SetValue(val3, num3); WindDirectionField.SetValue(val3, val); WindActiveTimeField.SetValue(val3, flag ? Mathf.Max(num6 + num8, 0f) : 0f); WindForceField.SetValue(val3, Mathf.MoveTowards(num7, flag ? 1f : 0f, num8)); val3.StormProgress = (flag ? Mathf.Clamp01(1f - weatherRemaining / num3) : 0f); val3.timeUntilStorm = (flag ? 0f : Mathf.Clamp01(1f - weatherRemaining / num3)); if (val3.windIntensityCurve != null) { val3.windIntensity = val3.windIntensityCurve.Evaluate(val3.StormProgress); } return true; } private void CaptureFogSpeed(OrbFogHandler handler) { if ((Object)(object)handler != (Object)null && !_originalFogSpeeds.ContainsKey(handler)) { _originalFogSpeeds.Add(handler, handler.speed); } } private void SetFogObjectActive(GameObject target, bool active) { if (!((Object)(object)target == (Object)null) && target.activeSelf != active) { if (!_originalFogObjectActive.ContainsKey(target)) { _originalFogObjectActive.Add(target, target.activeSelf); } target.SetActive(active); } } private void EnableFogOrigin(FogSphereOrigin origin) { if (!((Object)(object)origin == (Object)null) && origin.disableFog) { if (!_originalFogDisabled.ContainsKey(origin)) { _originalFogDisabled.Add(origin, origin.disableFog); } origin.disableFog = false; } } private void RestoreFogOverrides() { foreach (KeyValuePair<OrbFogHandler, float> originalFogSpeed in _originalFogSpeeds) { if ((Object)(object)originalFogSpeed.Key != (Object)null) { originalFogSpeed.Key.speed = originalFogSpeed.Value; } } foreach (KeyValuePair<FogSphereOrigin, bool> item in _originalFogDisabled) { if ((Object)(object)item.Key != (Object)null) { item.Key.disableFog = item.Value; } } foreach (KeyValuePair<GameObject, bool> item2 in _originalFogObjectActive) { if ((Object)(object)item2.Key != (Object)null) { item2.Key.SetActive(item2.Value); } } _originalFogSpeeds.Clear(); _originalFogDisabled.Clear(); _originalFogObjectActive.Clear(); } private void TryGrantInitialCompassIfNeeded() { if (!_initialCompassGranted && !((Object)(object)_orbFogHandler == (Object)null) && _orbFogHandler.currentID == 0 && _initialDelayCompleted && _orbFogHandler.isMoving && !HasRemotePlayersInJoinGracePeriod()) { _initialCompassGranted = true; GrantCompassToAllPlayers("initial-delay-ended"); } } private bool TryResolveCompassItem() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_compassItem != (Object)null) { return true; } if (TryResolveCompassItemOverride(out var item)) { _compassItem = item; return true; } ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance; if ((Object)instance == (Object)null || ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects == null) { return false; } List<string> list = new List<string>(); foreach (Item @object in ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects) { if ((Object)(object)@object == (Object)null) { continue; } CompassPointer componentInChildren = ((Component)@object).GetComponentInChildren<CompassPointer>(true); if (!((Object)(object)componentInChildren == (Object)null) && (int)componentInChildren.compassType == 0) { list.Add(DescribeCompassItem(@object)); if (LooksLikeStandardCompassItem(@object)) { _compassItem = @object; ((BaseUnityPlugin)this).Logger.LogInfo((object)("[Fog&ColdControl] Using normal compass item: " + DescribeCompassItem(@object))); return true; } } } if (list.Count > 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[Fog&ColdControl] Failed to identify the standard compass automatically. Set CompassItemIdOverride manually. Candidates: " + string.Join(", ", list))); } return false; } private bool TryResolveCompassItemOverride(out Item item) { item = null; if (CompassItemIdOverride <= 0) { return false; } Item val = default(Item); if (!ItemDatabase.TryGetItem(CompassItemIdOverride, ref val) || (Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)string.Format("[{0}] CompassItemIdOverride={1} is invalid.", "Fog&ColdControl", CompassItemIdOverride)); return false; } item = val; ((BaseUnityPlugin)this).Logger.LogInfo((object)("[Fog&ColdControl] Using compass item override: " + DescribeCompassItem(item))); return true; } private static bool LooksLikeStandardCompassItem(Item item) { if ((Object)(object)item == (Object)null) { return false; } string obj = ((Object)item).name ?? string.Empty; string text = item.UIData?.itemName ?? string.Empty; if (obj.IndexOf("Compass", StringComparison.OrdinalIgnoreCase) < 0) { return text.IndexOf("Compass", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static string DescribeCompassItem(Item item) { if ((Object)(object)item == (Object)null) { return "<null>"; } string arg = item.UIData?.itemName ?? string.Empty; return $"{((Object)item).name} (itemID={item.itemID}, uiName={arg})"; } private void GrantCompassToAllPlayers(string reason) { if (IsModFeatureEnabled() && HasFogAuthority() && IsCompassFeatureEnabled()) { _totalCompassGrantCount++; ((BaseUnityPlugin)this).Logger.LogDebug((object)string.Format("[{0}] Queued compass grant #{1} ({2}).", "Fog&ColdControl", _totalCompassGrantCount, reason)); SyncCompassGrantsToPlayers(force: true, reason); } } private void SyncCompassGrantsToPlayersIfNeeded() { if (IsModFeatureEnabled() && HasFogAuthority() && IsCompassFeatureEnabled() && _totalCompassGrantCount > 0 && !(Time.unscaledTime - _lastCompassGrantSyncTime < 0.75f)) { SyncCompassGrantsToPlayers(force: false, "periodic-sync"); } } private void SyncCompassGrantsToPlayers(bool force, string reason) { if (!IsModFeatureEnabled() || !HasFogAuthority() || !IsCompassFeatureEnabled() || _totalCompassGrantCount <= 0) { return; } if (!TryResolveCompassItem()) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[Fog&ColdControl] Failed to resolve compass item while syncing grants (" + reason + ").")); return; } _lastCompassGrantSyncTime = Time.unscaledTime; HashSet<int> activePlayerKeys = new HashSet<int>(); Dictionary<int, Player> dictionary = new Dictionary<int, Player>(); foreach (Player item in EnumerateTargetPlayers()) { if (!IsPlayerPastJoinGrace(item)) { continue; } int playerCompassGrantKey = GetPlayerCompassGrantKey(item); activePlayerKeys.Add(playerCompassGrantKey); PhotonView component = ((Component)item).GetComponent<PhotonView>(); int? obj; if (component == null) { obj = null; } else { Player owner = component.Owner; obj = ((owner != null) ? new int?(owner.ActorNumber) : ((int?)null)); } int num = obj ?? (-1); if (num > 0 && !dictionary.ContainsKey(num)) { dictionary[num] = item; } int num2 = GetDeliveredCompassGrantCount(item); int num3 = 0; while (num2 < _totalCompassGrantCount && GrantCompassToPlayer(item, $"{reason}-{num2 + 1}/{_totalCompassGrantCount}")) { num2++; num3++; if (num3 >= 1) { break; } } _playerCompassGrantCounts[playerCompassGrantKey] = num2; } TrySyncCompassGrantsToMissingActorPlayers(reason, activePlayerKeys, dictionary); int[] array = _playerCompassGrantCounts.Keys.Where((int item) => !activePlayerKeys.Contains(item)).ToArray(); foreach (int key in array) { _playerCompassGrantCounts.Remove(key); } } private void TrySyncCompassGrantsToMissingActorPlayers(string reason, HashSet<int> activePlayerKeys, Dictionary<int, Player> playersByActorNumber) { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return; } Player localPlayer = PhotonNetwork.LocalPlayer; int num = ((localPlayer != null) ? localPlayer.ActorNumber : (-1)); foreach (Player item in PhotonNetwork.CurrentRoom.Players.Values.OrderBy((Player player) => (player == null) ? int.MaxValue : player.ActorNumber)) { int num2 = ((item != null) ? item.ActorNumber : (-1)); if (num2 <= 0 || num2 == num || playersByActorNumber.ContainsKey(num2)) { continue; } activePlayerKeys.Add(num2); if (!IsActorPastJoinGrace(num2)) { continue; } int num3 = GetDeliveredCompassGrantCountForActor(num2); int num4 = 0; while (num3 < _totalCompassGrantCount && GrantCompassToActor(num2, $"{reason}-{num3 + 1}/{_totalCompassGrantCount}")) { num3++; num4++; if (num4 >= 1) { break; } } _playerCompassGrantCounts[num2] = num3; } } private static int GetPlayerCompassGrantKey(Player player) { if ((Object)(object)player == (Object)null) { return 0; } PhotonView component = ((Component)player).GetComponent<PhotonView>(); if (((component != null) ? component.Owner : null) != null) { return component.Owner.ActorNumber; } return ((Object)player).GetInstanceID(); } private int GetDeliveredCompassGrantCount(Player player) { int playerCompassGrantKey = GetPlayerCompassGrantKey(player); if (_playerCompassGrantCounts.TryGetValue(playerCompassGrantKey, out var value)) { return value; } PhotonView val = (((Object)(object)player != (Object)null) ? ((Component)player).GetComponent<PhotonView>() : null); if (((val != null) ? val.Owner : null) != null && _remotePlayerCompassBaselineCounts.TryGetValue(val.Owner.ActorNumber, out var value2)) { return value2; } return 0; } private int GetDeliveredCompassGrantCountForActor(int actorNumber) { if (_playerCompassGrantCounts.TryGetValue(actorNumber, out var value)) { return value; } if (_remotePlayerCompassBaselineCounts.TryGetValue(actorNumber, out var value2)) { return value2; } return 0; } private void ProcessPendingCampfireCompassGrants() { if (IsModFeatureEnabled() && HasFogAuthority() && IsCompassFeatureEnabled() && _pendingCampfireCompassGrantTimes.Count > 0 && !LoadingScreenHandler.loading) { float now = Time.unscaledTime; int[] array = _pendingCampfireCompassGrantTimes.Where(delegate(KeyValuePair<int, float> entry) { float num3 = now; KeyValuePair<int, float> keyValuePair = entry; return num3 >= keyValuePair.Value; }).Select(delegate(KeyValuePair<int, float> entry) { KeyValuePair<int, float> keyValuePair = entry; return keyValuePair.Key; }).ToArray(); foreach (int num2 in array) { _pendingCampfireCompassGrantTimes.Remove(num2); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Delivering delayed campfire compass grant for campfire #{1}.", "Fog&ColdControl", num2)); GrantCompassToAllPlayers($"campfire-{num2}"); } } } private bool GrantCompassToPlayer(Player player, string reason) { if ((Object)(object)player == (Object)null || (Object)(object)_compassItem == (Object)null || !IsPlayerPastJoinGrace(player)) { return false; } PhotonView component = ((Component)player).GetComponent<PhotonView>(); int? obj; if (component == null) { obj = null; } else { Player owner = component.Owner; obj = ((owner != null) ? new int?(owner.ActorNumber) : ((int?)null)); } int actorNumber = obj ?? (-1); if (((component != null) ? component.Owner : null) != null && !component.IsMine) { Character val = player.character; if ((Object)(object)val == (Object)null || (Object)(object)val.data == (Object)null || val.data.dead) { val = ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)((Character character) => (Object)(object)character != (Object)null && (Object)(object)((MonoBehaviourPun)character).photonView != (Object)null && ((MonoBehaviourPun)character).photonView.Owner != null && ((MonoBehaviourPun)character).photonView.Owner.ActorNumber == actorNumber && !character.isBot && !character.isZombie && (Object)(object)character.data != (Object)null && !character.data.dead)); } if ((Object)(object)val != (Object)null) { return DropCompassInFrontOfCharacter(val, actorNumber, reason); } } return DropCompassInFrontOfPlayer(player, reason, preferLocalViewAnchor: true); } private bool GrantCompassToActor(int actorNumber, string reason) { if (actorNumber <= 0 || (Object)(object)_compassItem == (Object)null || !IsActorPastJoinGrace(actorNumber)) { return false; } Player val = EnumerateTargetPlayers().FirstOrDefault((Func<Player, bool>)delegate(Player player) { PhotonView val3 = (((Object)(object)player != (Object)null) ? ((Component)player).GetComponent<PhotonView>() : null); if (val3 != null) { Player owner = val3.Owner; if (owner == null) { return false; } return owner.ActorNumber == actorNumber; } return false; }); if ((Object)(object)val != (Object)null) { return GrantCompassToPlayer(val, reason); } Character val2 = ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)((Character character) => (Object)(object)character != (Object)null && (Object)(object)((MonoBehaviourPun)character).photonView != (Object)null && ((MonoBehaviourPun)character).photonView.Owner != null && ((MonoBehaviourPun)character).photonView.Owner.ActorNumber == actorNumber && !character.isBot && !character.isZombie && (Object)(object)character.data != (Object)null && !character.data.dead)); if ((Object)(object)val2 == (Object)null) { return false; } return DropCompassInFrontOfCharacter(val2, actorNumber, reason); } private bool DropCompassInFrontOfPlayer(Player player, string reason) { return DropCompassInFrontOfPlayer(player, reason, preferLocalViewAnchor: false); } private bool DropCompassInFrontOfPlayer(Player player, string reason, bool preferLocalViewAnchor) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)_compassItem == (Object)null) { return false; } ResolveCompassSpawnPose(player, preferLocalViewAnchor, out var spawnPosition, out var spawnRotation); try { if (PhotonNetwork.InRoom) { PhotonNetwork.InstantiateItemRoom(((Object)_compassItem).name, spawnPosition, spawnRotation, true); } else { Object.Instantiate<GameObject>(((Component)_compassItem).gameObject, spawnPosition, spawnRotation); } ((BaseUnityPlugin)this).Logger.LogDebug((object)("[Fog&ColdControl] Spawned compass in front of " + ((Object)player).name + " (" + reason + ").")); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[Fog&ColdControl] Failed to spawn compass in front of " + ((Object)player).name + " (" + reason + "): " + ex.Message)); return false; } } private bool DropCompassInFrontOfCharacter(Character character, int actorNumber, string reason) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null || (Object)(object)_compassItem == (Object)null) { return false; } ResolveCompassSpawnPose(character, out var spawnPosition, out var spawnRotation); try { if (PhotonNetwork.InRoom) { PhotonNetwork.InstantiateItemRoom(((Object)_compassItem).name, spawnPosition, spawnRotation, true); } else { Object.Instantiate<GameObject>(((Component)_compassItem).gameObject, spawnPosition, spawnRotation); } ((BaseUnityPlugin)this).Logger.LogDebug((object)string.Format("[{0}] Spawned compass near actor #{1} ({2}).", "Fog&ColdControl", actorNumber, reason)); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)string.Format("[{0}] Failed to spawn compass near actor #{1} ({2}): {3}", "Fog&ColdControl", actorNumber, reason, ex.Message)); return false; } } private static void ResolveCompassSpawnPose(Player player, out Vector3 spawnPosition, out Quaternion spawnRotation) { ResolveCompassSpawnPose(player, preferLocalViewAnchor: false, out spawnPosition, out spawnRotation); } private static void ResolveCompassSpawnPose(Player player, bool preferLocalViewAnchor, out Vector3 spawnPosition, out Quaternion spawnRotation) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (!preferLocalViewAnchor || !TryResolveLocalViewCompassSpawnPose(player, out spawnPosition, out spawnRotation)) { Vector3 val = ResolveCompassFaceAnchorPosition(player); Vector3 val2 = ResolveCompassFacingForward(player); if (((Vector3)(ref val2)).sqrMagnitude < 0.01f) { val2 = Vector3.forward; } val2 = ((Vector3)(ref val2)).normalized; Vector3 val3 = Vector3.ProjectOnPlane(val2, Vector3.up); if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { val3 = Vector3.ProjectOnPlane(((Component)player).transform.forward, Vector3.up); } if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { val3 = Vector3.forward; } val3 = ((Vector3)(ref val3)).normalized; spawnPosition = val + val2 * 0.85f; spawnRotation = Quaternion.LookRotation(val3, Vector3.up); } } private static void ResolveCompassSpawnPose(Character character, out Vector3 spawnPosition, out Quaternion spawnRotation) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) Vector3 val = character.Center + Vector3.up * 0.5f; Vector3 val2 = ((Component)character).transform.forward; if (((Vector3)(ref val2)).sqrMagnitude < 0.01f) { val2 = Vector3.forward; } val2 = ((Vector3)(ref val2)).normalized; Vector3 val3 = Vector3.ProjectOnPlane(val2, Vector3.up); if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { val3 = Vector3.forward; } val3 = ((Vector3)(ref val3)).normalized; spawnPosition = val + val2 * 0.85f; spawnRotation = Quaternion.LookRotation(val3, Vector3.up); } private static bool TryResolveLocalViewCompassSpawnPose(Player player, out Vector3 spawnPosition, out Quaternion spawnRotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) spawnPosition = default(Vector3); spawnRotation = Quaternion.identity; object obj = Player.localPlayer; if (obj == null) { Character localCharacter = Character.localCharacter; obj = ((localCharacter != null) ? localCharacter.player : null); } Player val = (Player)obj; if ((Object)(object)player == (Object)null || (Object)(object)val == (Object)null || (Object)(object)player != (Object)(object)val) { return false; } Camera val2 = Camera.main; if ((Object)(object)val2 == (Object)null || !((Behaviour)val2).isActiveAndEnabled) { val2 = ((IEnumerable<Camera>)Object.FindObjectsByType<Camera>((FindObjectsSortMode)0)).FirstOrDefault((Func<Camera, bool>)((Camera candidate) => (Object)(object)candidate != (Object)null && ((Behaviour)candidate).isActiveAndEnabled && ((Component)candidate).gameObject.activeInHierarchy)); } if ((Object)(object)val2 == (Object)null) { return false; } Transform transform = ((Component)val2).transform; Vector3 val3 = transform.forward; if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { return false; } val3 = ((Vector3)(ref val3)).normalized; Vector3 val4 = Vector3.ProjectOnPlane(val3, Vector3.up); if (((Vector3)(ref val4)).sqrMagnitude < 0.01f) { val4 = Vector3.ProjectOnPlane(((Component)player).transform.forward, Vector3.up); } if (((Vector3)(ref val4)).sqrMagnitude < 0.01f) { val4 = Vector3.forward; } val4 = ((Vector3)(ref val4)).normalized; spawnPosition = transform.position + val3 * 0.9f; spawnRotation = Quaternion.LookRotation(val4, Vector3.up); return true; } private static Vector3 ResolveCompassFaceAnchorPosition(Player player) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_002f: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (TryGetCompassFaceAnchor(player, out var anchor)) { Vector3 val = ((((Object)anchor).name.IndexOf("camera", StringComparison.OrdinalIgnoreCase) >= 0) ? (Vector3.down * 0.03f) : Vector3.zero); return anchor.position + val; } Character character = player.character; if ((Object)(object)character != (Object)null) { Vector3 center = character.Center; return new Vector3(center.x, center.y + 0.5f, center.z); } return ((Component)player).transform.position + Vector3.up * 1.45f; } private static Vector3 ResolveCompassFacingForward(Player player) { //IL_0065: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_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_007f: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (TryGetCompassFaceAnchor(player, out var anchor) && ShouldUseCompassAnchorForward(anchor)) { Vector3 forward = anchor.forward; if (((Vector3)(ref forward)).sqrMagnitude >= 0.01f) { return forward; } } Character character = player.character; Vector3 forward2; if ((Object)(object)character != (Object)null) { forward2 = ((Component)character).transform.forward; if (((Vector3)(ref forward2)).sqrMagnitude >= 0.01f) { return ((Component)character).transform.forward; } } forward2 = ((Component)player).transform.forward; if (((Vector3)(ref forward2)).sqrMagnitude >= 0.01f) { return ((Component)player).transform.forward; } if (TryGetCompassFaceAnchor(player, out anchor)) { forward2 = anchor.forward; if (((Vector3)(ref forward2)).sqrMagnitude >= 0.01f) { return anchor.forward; } } return Vector3.forward; } private static bool TryGetCompassFaceAnchor(Player player, out Transform anchor) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) anchor = null; if ((Object)(object)player == (Object)null) { return false; } Transform[] obj = (((Object)(object)player.character != (Object)null && (Object)(object)((Component)player.character).transform != (Object)(object)((Component)player).transform) ? new Transform[2] { ((Component)player.character).transform, ((Component)player).transform } : new Transform[1] { ((Component)player).transform }); int num = int.MaxValue; float num2 = float.MinValue; Transform[] array = (Transform[])(object)obj; foreach (Transform val in array) { if ((Object)(object)val == (Object)null) { continue; } Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { int compassFaceAnchorScore = GetCompassFaceAnchorScore(val2); if (compassFaceAnchorScore != int.MaxValue) { float y = val2.position.y; if (compassFaceAnchorScore < num || (compassFaceAnchorScore == num && y > num2)) { num = compassFaceAnchorScore; num2 = y; anchor = val2; } } } } return (Object)(object)anchor != (Object)null; } private static int GetCompassFaceAnchorScore(Transform candidate) { if ((Object)(object)candidate == (Object)null) { return int.MaxValue; } string text = ((Object)candidate).name ?? string.Empty; if (text.Equals("MainCamera", StringComparison.OrdinalIgnoreCase)) { return 0; } if (text.IndexOf("maincamera", StringComparison.OrdinalIgnoreCase) >= 0) { return 1; } if (text.IndexOf("camera", StringComparison.OrdinalIgnoreCase) >= 0) { return 2; } if (text.IndexOf("head", StringComparison.OrdinalIgnoreCase) >= 0) { return 3; } if (text.IndexOf("face", StringComparison.OrdinalIgnoreCase) >= 0) { return 4; } if (text.IndexOf("look", StringComparison.OrdinalIgnoreCase) >= 0) { return 5; } if (text.IndexOf("jaw", StringComparison.OrdinalIgnoreCase) >= 0) { return 6; } return int.MaxValue; } private static bool ShouldUseCompassAnchorForward(Transform anchor) { if ((Object)(object)anchor == (Object)null) { return false; } string text = ((Object)anchor).name ?? string.Empty; if (text.IndexOf("camera", StringComparison.OrdinalIgnoreCase) < 0) { return text.IndexOf("look", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private void HandleManualCompassHotkey() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!IsModFeatureEnabled() || !HasFogAuthority() || !IsCompassFeatureEnabled()) { return; } KeyCode compassHotkey = GetCompassHotkey(); if ((int)compassHotkey != 0) { GUIManager instance = GUIManager.instance; if ((!((Object)(object)instance != (Object)null) || !instance.windowBlockingInput) && Input.GetKeyDown(compassHotkey)) { TrySpawnManualCompassForLocalPlayer(); } } } private void TrySpawnManualCompassForLocalPlayer() { if (IsCompassFeatureEnabled()) { Player localPlayer; if (!TryResolveCompassItem()) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[Fog&ColdControl] Failed to resolve compass item for manual hotkey spawn."); } else if (TryGetLocalPlayablePlayer(out localPlayer) && !DropCompassInFrontOfPlayer(localPlayer, "manual-hotkey", preferLocalViewAnchor: true)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[Fog&ColdControl] Manual compass hotkey spawn failed for " + ((Object)localPlayer).name + ".")); } } } private static KeyCode GetCompassHotkey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (KeyCode)(((??)CompassHotkey?.Value) ?? 103); } private unsafe static string GetCompassHotkeyLabel() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) KeyCode compassHotkey = GetCompassHotkey(); string text = ((object)(*(KeyCode*)(&compassHotkey))/*cast due to .constrained prefix*/).ToString(); if (string.IsNullOrWhiteSpace(text) || (int)compassHotkey == 0) { return "G"; } return text.ToUpperInvariant(); } private bool ShouldShowCompassLobbyNotice() { //IL_0015: 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) if (IsModFeatureEnabled() && HasFogAuthority() && IsCompassFeatureEnabled() && (int)GetCompassHotkey() != 0) { return IsAirportScene(SceneManager.GetActiveScene()); } return false; } private string GetCompassLobbyNoticeTextSafe(bool isChineseLanguage) { string text = "<color=#FF3B30>" + GetCompassHotkeyLabel() + "</color>"; if (!isChineseLanguage) { return "Press " + text + " to spawn compass"; } return "按 " + text + " 生成指南针"; } private void UpdateCompassLobbyNotice() { if (!ShouldShowCompassLobbyNotice()) { CleanupCompassLobbyNotice(); return; } Canvas val = ResolveHudCanvas(); if (!IsCanvasUsable(val)) { CleanupCompassLobbyNotice(); return; } if ((Object)(object)_compassLobbyNoticeRect == (Object)null || (Object)(object)_compassLobbyNoticeText == (Object)null || (Object)(object)((Transform)_compassLobbyNoticeRect).parent != (Object)(object)((Component)val).transform) { CreateCompassLobbyNotice(val); if ((Object)(object)_compassLobbyNoticeRect == (Object)null || (Object)(object)_compassLobbyNoticeText == (Object)null) { return; } } string compassLobbyNoticeTextSafe = GetCompassLobbyNoticeTextSafe(DetectChineseLanguage()); if (!string.Equals(_lastCompassLobbyNoticeText, compassLobbyNoticeTextSafe, StringComparison.Ordinal)) { _lastCompassLobbyNoticeText = compassLobbyNoticeTextSafe; ((TMP_Text)_compassLobbyNoticeText).text = compassLobbyNoticeTextSafe; } ClampCompassLobbyNoticeToCanvas(val); ((Component)_compassLobbyNoticeRect).gameObject.SetActive(true); } private void CreateCompassLobbyNotice(Canvas targetCanvas = null) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) CleanupCompassLobbyNotice(); Canvas val = targetCanvas ?? ResolveHudCanvas(); if (IsCanvasUsable(val)) { GameObject val2 = new GameObject("FogClimbCompassLobbyNotice", new Type[1] { typeof(RectTransform) }); _compassLobbyNoticeRect = val2.GetComponent<RectTransform>(); ((Transform)_compassLobbyNoticeRect).SetParent(((Component)val).transform, false); ((Transform)_compassLobbyNoticeRect).SetAsLastSibling(); _compassLobbyNoticeRect.sizeDelta = new Vector2(735f, 81f); _compassLobbyNoticeText = val2.AddComponent<TextMeshProUGUI>(); ApplyCompassLobbyNoticeStyle(_compassLobbyNoticeText); _lastCompassLobbyNoticeText = GetCompassLobbyNoticeTextSafe(DetectChineseLanguage()); ((TMP_Text)_compassLobbyNoticeText).text = _lastCompassLobbyNoticeText; ClampCompassLobbyNoticeToCanvas(val); } } private void ApplyCompassLobbyNoticeStyle(TextMeshProUGUI target) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null)) { ApplyGameTextStyle(target, new Color(1f, 0.94f, 0.72f), 1.2f); ((TMP_Text)target).fontStyle = (FontStyles)0; ((TMP_Text)target).alignment = (TextAlignmentOptions)4100; ((TMP_Text)target).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)target).overflowMode = (TextOverflowModes)0; ((TMP_Text)target).lineSpacing = 1.125f; } } private void ClampCompassLobbyNoticeToCanvas(Canvas targetCanvas = null) { if ((Object)(object)_compassLobbyNoticeRect == (Object)null) { return; } Canvas val = targetCanvas ?? ResolveHudCanvas() ?? ((Component)_compassLobbyNoticeRect).GetComponentInParent<Canvas>(); if (IsCanvasUsable(val)) { if ((Object)(object)((Transform)_compassLobbyNoticeRect).parent != (Object)(object)((Component)val).transform) { ((Transform)_compassLobbyNoticeRect).SetParent(((Component)val).transform, false); } ApplyRightMiddleAnchoredRect(_compassLobbyNoticeRect, 735f, 81f, 28f, 0f); } } private void CleanupCompassLobbyNotice() { if ((Object)(object)_compassLobbyNoticeRect != (Object)null) { Object.Destroy((Object)(object)((Component)_compassLobbyNoticeRect).gameObject); } _compassLobbyNoticeRect = null; _compassLobbyNoticeText = null; _lastCompassLobbyNoticeText = string.Empty; } internal static bool IsCompassFeatureEnabled() { if (CompassEnabled != null) { return CompassEnabled.Value; } return true; } private void InitializeConfig(bool isChineseLanguage) { FogColdSuppression = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.FogColdSuppression), GetConfigKeyName(ConfigKey.FogColdSuppression), false, CreateConfigDescription(ConfigKey.FogColdSuppression, isChineseLanguage)); NightColdEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.NightColdEnabled), GetConfigKeyName(ConfigKey.NightColdEnabled), true, CreateConfigDescription(ConfigKey.NightColdEnabled, isChineseLanguage)); FogSpeed = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogSpeed), GetConfigKeyName(ConfigKey.FogSpeed), 0.4f, CreateConfigDescription(ConfigKey.FogSpeed, isChineseLanguage)); FogDelay = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogDelay), GetConfigKeyName(ConfigKey.FogDelay), 900f, CreateConfigDescription(ConfigKey.FogDelay, isChineseLanguage)); FogPauseHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>(GetConfigSectionName(ConfigKey.FogPauseHotkey), GetConfigKeyName(ConfigKey.FogPauseHotkey), (KeyCode)121, CreateConfigDescription(ConfigKey.FogPauseHotkey, isChineseLanguage)); ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.ModEnabled), GetConfigKeyName(ConfigKey.ModEnabled), true, CreateConfigDescription(ConfigKey.ModEnabled, isChineseLanguage)); FogUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.FogUiEnabled), GetConfigKeyName(ConfigKey.FogUiEnabled), true, CreateConfigDescription(ConfigKey.FogUiEnabled, isChineseLanguage)); CampfireLocatorUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.CampfireLocatorUiEnabled), GetConfigKeyName(ConfigKey.CampfireLocatorUiEnabled), true, CreateConfigDescription(ConfigKey.CampfireLocatorUiEnabled, isChineseLanguage)); CompassEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.CompassEnabled), GetConfigKeyName(ConfigKey.CompassEnabled), false, CreateConfigDescription(ConfigKey.CompassEnabled, isChineseLanguage)); CompassHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>(GetConfigSectionName(ConfigKey.CompassHotkey), GetConfigKeyName(ConfigKey.CompassHotkey), (KeyCode)103, CreateConfigDescription(ConfigKey.CompassHotkey, isChineseLanguage)); FogUiX = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogUiX), GetConfigKeyName(ConfigKey.FogUiX), 60f, CreateConfigDescription(ConfigKey.FogUiX, isChineseLanguage)); FogUiY = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogUiY), GetConfigKeyName(ConfigKey.FogUiY), 0f, CreateConfigDescription(ConfigKey.FogUiY, isChineseLanguage)); FogUiScale = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogUiScale), GetConfigKeyName(ConfigKey.FogUiScale), 0.9f, CreateConfigDescription(ConfigKey.FogUiScale, isChineseLanguage)); FogUiEntrySpacing = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogUiEntrySpacing), GetConfigKeyName(ConfigKey.FogUiEntrySpacing), 8f, CreateConfigDescription(ConfigKey.FogUiEntrySpacing, isChineseLanguage)); FogUiLayout = ((BaseUnityPlugin)this).Config.Bind<FogUiLayoutKind>(GetConfigSectionName(ConfigKey.FogUiLayout), GetConfigKeyName(ConfigKey.FogUiLayout), FogUiLayoutKind.Horizontal, CreateConfigDescription(ConfigKey.FogUiLayout, isChineseLanguage)); FogUiBackgroundOpacity = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogUiBackgroundOpacity), GetConfigKeyName(ConfigKey.FogUiBackgroundOpacity), 0f, CreateConfigDescription(ConfigKey.FogUiBackgroundOpacity, isChineseLanguage)); FogStateUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.FogStateUiEnabled), GetConfigKeyName(ConfigKey.FogStateUiEnabled), true, CreateConfigDescription(ConfigKey.FogStateUiEnabled, isChineseLanguage)); RunTimerUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.RunTimerUiEnabled), GetConfigKeyName(ConfigKey.RunTimerUiEnabled), true, CreateConfigDescription(ConfigKey.RunTimerUiEnabled, isChineseLanguage)); DayNightTimeUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.DayNightTimeUiEnabled), GetConfigKeyName(ConfigKey.DayNightTimeUiEnabled), true, CreateConfigDescription(ConfigKey.DayNightTimeUiEnabled, isChineseLanguage)); AltitudeUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.AltitudeUiEnabled), GetConfigKeyName(ConfigKey.AltitudeUiEnabled), true, CreateConfigDescription(ConfigKey.AltitudeUiEnabled, isChineseLanguage)); FogSpeedUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.FogSpeedUiEnabled), GetConfigKeyName(ConfigKey.FogSpeedUiEnabled), true, CreateConfigDescription(ConfigKey.FogSpeedUiEnabled, isChineseLanguage)); CampfireDistanceUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.CampfireDistanceUiEnabled), GetConfigKeyName(ConfigKey.CampfireDistanceUiEnabled), true, Create